Fix popen_test in MODE=dbg
ASAN and vfork() don't appear to play well together. Maybe in later versions of GCC it'll be better. But vfork() is flirting with danger after all and that probably doesn't make sense in ASAN mode anyway.
This commit is contained in:
@@ -23,11 +23,11 @@
|
||||
* @return byte in range 0..255, or -1 w/ errno
|
||||
*/
|
||||
int fgetc(FILE *f) {
|
||||
unsigned char b;
|
||||
unsigned char b[1];
|
||||
if (f->beg < f->end) {
|
||||
return f->buf[f->beg++] & 0xff;
|
||||
} else {
|
||||
if (!fread(&b, 1, 1, f)) return -1;
|
||||
return b;
|
||||
if (!fread(b, 1, 1, f)) return -1;
|
||||
return b[0];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@
|
||||
*/
|
||||
FILE *popen(const char *cmdline, const char *mode) {
|
||||
FILE *f;
|
||||
int dir, flags, pipefds[2];
|
||||
int e, pid, dir, flags, pipefds[2];
|
||||
flags = fopenflags(mode);
|
||||
if ((flags & O_ACCMODE) == O_RDONLY) {
|
||||
dir = 0;
|
||||
@@ -45,13 +45,28 @@ FILE *popen(const char *cmdline, const char *mode) {
|
||||
}
|
||||
if (pipe(pipefds) == -1) return NULL;
|
||||
fcntl(pipefds[dir], F_SETFD, FD_CLOEXEC);
|
||||
if (!(f = fdopen(pipefds[dir], mode))) abort();
|
||||
if ((f->pid = vfork()) == -1) abort();
|
||||
if (!f->pid) {
|
||||
dup2(pipefds[!dir], !dir);
|
||||
systemexec(cmdline);
|
||||
_exit(127);
|
||||
if ((f = fdopen(pipefds[dir], mode))) {
|
||||
switch ((pid = vfork())) {
|
||||
case 0:
|
||||
dup2(pipefds[!dir], !dir);
|
||||
systemexec(cmdline);
|
||||
_exit(127);
|
||||
default:
|
||||
f->pid = pid;
|
||||
close(pipefds[!dir]);
|
||||
return f;
|
||||
case -1:
|
||||
e = errno;
|
||||
fclose(f);
|
||||
close(pipefds[!dir]);
|
||||
errno = e;
|
||||
return NULL;
|
||||
}
|
||||
} else {
|
||||
e = errno;
|
||||
close(pipefds[0]);
|
||||
close(pipefds[1]);
|
||||
errno = e;
|
||||
return NULL;
|
||||
}
|
||||
close(pipefds[!dir]);
|
||||
return f;
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ COSMOPOLITAN_C_START_
|
||||
|
||||
typedef struct FILE {
|
||||
uint8_t bufmode; /* 0x00 _IOFBF, etc. (ignored if fd=-1) */
|
||||
bool noclose; /* 0x01 for fake dup() */
|
||||
bool noclose; /* 0x01 for fake dup() todo delete! */
|
||||
uint32_t iomode; /* 0x04 O_RDONLY, etc. (ignored if fd=-1) */
|
||||
int32_t state; /* 0x08 0=OK, -1=EOF, >0=errno */
|
||||
int fd; /* 0x0c ≥0=fd, -1=closed|buffer */
|
||||
|
||||
Reference in New Issue
Block a user