Share file offset across processes

This change ensures that if a file descriptor for an open disk file gets
shared by multiple processes within a process tree, then lseek() changes
will be visible across processes, and read() / write() are synchronized.
Note this only applies to Windows, because UNIX kernels already do this.
This commit is contained in:
Justine Tunney 2024-08-03 01:24:46 -07:00
parent a80ab3f8fe
commit 761c6ad615
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
15 changed files with 256 additions and 63 deletions

View file

@ -16,13 +16,13 @@
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.
*/
#include "libc/intrin/fds.h"
#include "libc/calls/internal.h"
#include "libc/calls/state.internal.h"
#include "libc/calls/ttydefaults.h"
#include "libc/dce.h"
#include "libc/intrin/atomic.h"
#include "libc/intrin/extend.h"
#include "libc/intrin/fds.h"
#include "libc/intrin/kprintf.h"
#include "libc/intrin/nomultics.h"
#include "libc/intrin/pushpop.h"
@ -40,6 +40,7 @@
#include "libc/sock/sock.h"
#include "libc/sysv/consts/map.h"
#include "libc/sysv/consts/o.h"
#include "libc/sysv/consts/prot.h"
#include "libc/thread/thread.h"
#define OPEN_MAX 16
@ -156,12 +157,29 @@ textstartup void __init_fds(int argc, char **argv, char **envp) {
f->kind = kind;
f->flags = flags;
f->mode = mode;
f->pointer = pointer;
f->type = type;
f->family = family;
f->protocol = protocol;
atomic_store_explicit(&fds->f, fd + 1, memory_order_relaxed);
//
// - v1 abi: This field was originally the file pointer.
//
// - v2 abi: This field is the negated shared memory address.
//
if (f->kind == kFdFile) {
if (pointer < 0) {
f->shared = (struct Cursor *)(uintptr_t)-pointer;
} else if ((f->shared = __cursor_new())) {
f->shared->pointer = pointer;
}
}
}
}
for (int i = 0; i < 3; ++i) {
struct Fd *f = fds->p + i;
if (f->kind == kFdFile && !f->shared)
f->shared = __cursor_new();
}
}
}