Skip to content

Commit 3f26dfb

Browse files
committed
Share file offset across execve() on Windows
This is a breaking change. It defines the new environment variable named _COSMO_FDS_V2 which is used for inheriting non-stdio file descriptors on execve() or posix_spawn(). No effort has been spent thus far integrating with the older variable. If a new binary launches the older ones or vice versa they'll only be able to pass stdin / stdout / stderr to each other therefore it's important that you upgrade all your cosmo binaries if you depend on this functionality. You'll be glad you did because inheritance of file descriptors is more aligned with the POSIX standard than before.
1 parent 761c6ad commit 3f26dfb

29 files changed

+572
-249
lines changed

libc/calls/close-nt.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ textwindows int sys_close_nt(int fd, int fildes) {
6565
default:
6666
break;
6767
}
68-
if (f->shared && !f->isdup)
69-
munmap(f->shared, sizeof(struct Cursor));
68+
if (f->cursor)
69+
__cursor_unref(f->cursor);
7070
return CloseHandle(f->handle) ? 0 : __winerr();
7171
}

libc/calls/dup-nt.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "libc/calls/struct/sigset.internal.h"
2525
#include "libc/calls/syscall_support-nt.internal.h"
2626
#include "libc/errno.h"
27+
#include "libc/intrin/fds.h"
2728
#include "libc/intrin/kprintf.h"
2829
#include "libc/intrin/weaken.h"
2930
#include "libc/nt/files.h"
@@ -82,8 +83,7 @@ static textwindows int sys_dup_nt_impl(int oldfd, int newfd, int flags,
8283

8384
g_fds.p[newfd] = g_fds.p[oldfd];
8485
g_fds.p[newfd].handle = handle;
85-
g_fds.p[newfd].isdup = true;
86-
g_fds.p[oldfd].isdup = true; // TODO(jart): is it possible to avoid leak?
86+
__cursor_ref(g_fds.p[newfd].cursor);
8787
if (flags & _O_CLOEXEC) {
8888
g_fds.p[newfd].flags |= _O_CLOEXEC;
8989
} else {

libc/calls/fcntl-nt.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ static textwindows int sys_fcntl_nt_lock(struct Fd *f, int fd, int cmd,
151151
case SEEK_SET:
152152
break;
153153
case SEEK_CUR:
154-
off = f->shared->pointer + off;
154+
off = f->cursor->shared->pointer + off;
155155
break;
156156
case SEEK_END: {
157157
int64_t size;
@@ -352,7 +352,7 @@ textwindows int sys_fcntl_nt(int fd, int cmd, uintptr_t arg) {
352352
rc = 0;
353353
} else if (cmd == F_SETLK || cmd == F_SETLKW || cmd == F_GETLK) {
354354
struct Fd *f = g_fds.p + fd;
355-
if (f->shared) {
355+
if (f->cursor) {
356356
pthread_mutex_lock(&g_locks.mu);
357357
rc = sys_fcntl_nt_lock(f, fd, cmd, arg);
358358
pthread_mutex_unlock(&g_locks.mu);

libc/calls/isapemagic.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,5 @@
2525
bool IsApeLoadable(char buf[8]) {
2626
return READ32LE(buf) == READ32LE("\177ELF") ||
2727
READ64LE(buf) == READ64LE("MZqFpD='") ||
28-
READ64LE(buf) == READ64LE("jartsr='") ||
29-
READ64LE(buf) == READ64LE("APEDBG='");
28+
READ64LE(buf) == READ64LE("jartsr='");
3029
}

libc/calls/lseek-nt.c

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "libc/calls/calls.h"
2020
#include "libc/calls/internal.h"
2121
#include "libc/calls/syscall_support-nt.internal.h"
22+
#include "libc/intrin/fds.h"
2223
#include "libc/nt/enum/filetype.h"
2324
#include "libc/nt/files.h"
2425
#include "libc/nt/struct/byhandlefileinformation.h"
@@ -31,7 +32,7 @@ static textwindows int64_t GetPosition(struct Fd *f, int whence) {
3132
case SEEK_SET:
3233
return 0;
3334
case SEEK_CUR:
34-
return f->shared->pointer;
35+
return f->cursor->shared->pointer;
3536
case SEEK_END: {
3637
struct NtByHandleFileInformation wst;
3738
if (!GetFileInformationByHandle(f->handle, &wst)) {
@@ -69,12 +70,12 @@ textwindows int64_t sys_lseek_nt(int fd, int64_t offset, int whence) {
6970
int filetype = GetFileType(f->handle);
7071
if (filetype != kNtFileTypePipe && //
7172
filetype != kNtFileTypeChar && //
72-
f->shared) {
73+
f->cursor->shared) {
7374
int64_t res;
74-
__fd_lock(f);
75+
__cursor_lock(f->cursor);
7576
if ((res = Seek(f, offset, whence)) != -1)
76-
f->shared->pointer = res;
77-
__fd_unlock(f);
77+
f->cursor->shared->pointer = res;
78+
__cursor_unlock(f->cursor);
7879
return res;
7980
} else {
8081
return espipe();

libc/calls/open-nt.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
#include "libc/calls/syscall-nt.internal.h"
2525
#include "libc/calls/syscall_support-nt.internal.h"
2626
#include "libc/errno.h"
27+
#include "libc/intrin/fds.h"
2728
#include "libc/macros.internal.h"
2829
#include "libc/nt/console.h"
2930
#include "libc/nt/createfile.h"
@@ -138,7 +139,7 @@ static textwindows int sys_open_nt_file(int dirfd, const char *file,
138139
int64_t handle;
139140
if ((handle = sys_open_nt_impl(dirfd, file, flags, mode,
140141
kNtFileFlagOverlapped)) != -1) {
141-
g_fds.p[fd].shared = __cursor_new();
142+
g_fds.p[fd].cursor = __cursor_new();
142143
g_fds.p[fd].handle = handle;
143144
g_fds.p[fd].kind = kFdFile;
144145
g_fds.p[fd].flags = flags;
@@ -178,8 +179,8 @@ static textwindows int sys_open_nt_dup(int fd, int flags, int mode, int oldfd) {
178179
kNtDuplicateSameAccess)) {
179180
g_fds.p[fd] = g_fds.p[oldfd];
180181
g_fds.p[fd].handle = handle;
181-
g_fds.p[fd].isdup = true;
182182
g_fds.p[fd].mode = mode;
183+
__cursor_ref(g_fds.p[fd].cursor);
183184
if (!sys_fcntl_nt_setfl(fd, flags)) {
184185
return fd;
185186
} else {

libc/calls/readwrite-nt.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -61,29 +61,29 @@ sys_readwrite_nt(int fd, void *data, size_t size, ssize_t offset,
6161
return espipe();
6262

6363
// determine if we need to lock a file descriptor across processes
64-
bool locked = isdisk && !pwriting && f->shared;
64+
bool locked = isdisk && !pwriting && f->cursor;
6565
if (locked)
66-
__fd_lock(f);
66+
__cursor_lock(f->cursor);
6767

68+
RestartOperation:
6869
// when a file is opened in overlapped mode win32 requires that we
6970
// take over full responsibility for managing our own file pointer
7071
// which is fine, because the one win32 has was never very good in
7172
// the sense that it behaves so differently from linux, that using
7273
// win32 i/o required more compatibilty toil than doing it by hand
7374
if (!pwriting) {
74-
if (seekable && f->shared) {
75-
offset = f->shared->pointer;
75+
if (seekable && f->cursor) {
76+
offset = f->cursor->shared->pointer;
7677
} else {
7778
offset = 0;
7879
}
7980
}
8081

81-
RestartOperation:
8282
bool eagained = false;
8383
// check for signals and cancelation
8484
if (_check_cancel() == -1) {
8585
if (locked)
86-
__fd_unlock(f);
86+
__cursor_unlock(f->cursor);
8787
return -1; // ECANCELED
8888
}
8989
if (_weaken(__sig_get) && (sig = _weaken(__sig_get)(waitmask))) {
@@ -122,10 +122,10 @@ sys_readwrite_nt(int fd, void *data, size_t size, ssize_t offset,
122122

123123
// if i/o succeeded then return its result
124124
if (ok) {
125-
if (!pwriting && seekable && f->shared)
126-
f->shared->pointer = offset + exchanged;
125+
if (!pwriting && seekable && f->cursor)
126+
f->cursor->shared->pointer = offset + exchanged;
127127
if (locked)
128-
__fd_unlock(f);
128+
__cursor_unlock(f->cursor);
129129
return exchanged;
130130
}
131131

@@ -134,31 +134,31 @@ sys_readwrite_nt(int fd, void *data, size_t size, ssize_t offset,
134134
// raise EAGAIN if it's due to O_NONBLOCK mmode
135135
if (eagained) {
136136
if (locked)
137-
__fd_unlock(f);
137+
__cursor_unlock(f->cursor);
138138
return eagain();
139139
}
140140
// otherwise it must be due to a kill() via __sig_cancel()
141141
if (_weaken(__sig_relay) && (sig = _weaken(__sig_get)(waitmask))) {
142142
HandleInterrupt:
143143
if (locked)
144-
__fd_unlock(f);
144+
__cursor_unlock(f->cursor);
145145
int handler_was_called = _weaken(__sig_relay)(sig, SI_KERNEL, waitmask);
146146
if (_check_cancel() == -1)
147147
return -1; // possible if we SIGTHR'd
148148
if (locked)
149-
__fd_lock(f);
149+
__cursor_lock(f->cursor);
150150
// read() is @restartable unless non-SA_RESTART hands were called
151151
if (!(handler_was_called & SIG_HANDLED_NO_RESTART))
152152
goto RestartOperation;
153153
}
154154
if (locked)
155-
__fd_unlock(f);
155+
__cursor_unlock(f->cursor);
156156
return eintr();
157157
}
158158

159159
// read() and write() have generally different error-handling paths
160160
if (locked)
161-
__fd_unlock(f);
161+
__cursor_unlock(f->cursor);
162162
return -2;
163163
}
164164

libc/calls/write-nt.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,14 @@
1818
╚─────────────────────────────────────────────────────────────────────────────*/
1919
#include "libc/calls/internal.h"
2020
#include "libc/calls/sig.internal.h"
21-
#include "libc/intrin/fds.h"
2221
#include "libc/calls/struct/iovec.h"
2322
#include "libc/calls/struct/sigset.h"
2423
#include "libc/calls/struct/sigset.internal.h"
2524
#include "libc/calls/syscall-nt.internal.h"
2625
#include "libc/calls/syscall_support-nt.internal.h"
2726
#include "libc/errno.h"
2827
#include "libc/intrin/atomic.h"
28+
#include "libc/intrin/fds.h"
2929
#include "libc/intrin/nomultics.h"
3030
#include "libc/intrin/weaken.h"
3131
#include "libc/nt/console.h"

libc/integral/c.inc

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@
66
#define COSMOPOLITAN_CXX_USING_
77
#endif
88

9-
#ifndef __cplusplus
10-
#pragma GCC diagnostic warning "-Wimplicit-function-declaration"
11-
#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
12-
#pragma GCC diagnostic warning "-Wint-conversion"
13-
#endif
14-
159
#if !defined(__GNUC__) && __cplusplus + 0 >= 201103L
1610
#define typeof(x) decltype(x)
1711
#elif !defined(__GNUC__) && __STDC_VERSION__ + 0 < 201112

libc/intrin/BUILD.mk

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ o/$(MODE)/libc/intrin/kprintf.o: private \
6262
-Wframe-larger-than=128 \
6363
-Walloca-larger-than=128
6464

65+
o/$(MODE)/libc/intrin/cursor.o \
6566
o/$(MODE)/libc/intrin/mmap.o \
6667
o/$(MODE)/libc/intrin/tree.o: private \
6768
CFLAGS += \

0 commit comments

Comments
 (0)