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:
Justine Tunney 2021-05-01 17:13:48 -07:00
parent cef08d47b6
commit fabf7f9f02
5 changed files with 35 additions and 14 deletions

View file

@ -20,6 +20,11 @@
#include "libc/macros.internal.h"
.privileged
#ifdef __FSANITIZE_ADDRESS__
vfork: jmp fork # TODO: asan and vfork don't mix?
.endfn vfork,globl
#else
// Forks process without copying page tables.
//
// This is the same as fork() except it's optimized for the case
@ -75,3 +80,5 @@ vfork.bsd:
jmp 0b
.endfn vfork.bsd
#endif /* BSD */
#endif /* __FSANITIZE_ADDRESS__ */

View file

@ -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];
}
}

View file

@ -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;
}

View file

@ -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 */

View file

@ -23,7 +23,6 @@
TEST(popen, test) {
int ws;
FILE *f;
/* TODO(jart): look into popen() asan error */
f = popen("echo hi", "r");
ASSERT_NE(NULL, f);
EXPECT_EQ('h', fgetc(f));