Make system() and popen() thread safe

This commit is contained in:
Justine Tunney 2022-10-13 15:38:31 -07:00
parent 997ce29ddc
commit f52f65b2e3
No known key found for this signature in database
GPG key ID: BE714B4575D6E328
19 changed files with 135 additions and 31 deletions

View file

@ -20,10 +20,18 @@
#include "libc/calls/struct/sigaction.h"
#include "libc/dce.h"
#include "libc/fmt/fmt.h"
#include "libc/fmt/itoa.h"
#include "libc/limits.h"
#include "libc/mem/gc.h"
#include "libc/mem/mem.h"
#include "libc/runtime/runtime.h"
#include "libc/stdio/lock.internal.h"
#include "libc/stdio/rand.h"
#include "libc/stdio/stdio.h"
#include "libc/str/str.h"
#include "libc/sysv/consts/sig.h"
#include "libc/testlib/testlib.h"
#include "libc/thread/thread.h"
FILE *f;
char buf[32];
@ -93,3 +101,39 @@ TEST(popen, complicated) {
ASSERT_EQ(1, gotsig);
signal(SIGUSR1, SIG_DFL);
}
void *Worker(void *arg) {
FILE *f;
char buf[32];
char *arg1, *arg2, *cmd;
for (int i = 0; i < 8; ++i) {
cmd = malloc(64);
arg1 = malloc(13);
arg2 = malloc(13);
FormatInt32(arg1, _rand64());
FormatInt32(arg2, _rand64());
sprintf(cmd, "echo %s; ./echo.com %s", arg1, arg2);
strcat(arg1, "\n");
strcat(arg2, "\n");
ASSERT_NE(NULL, (f = popen(cmd, "r")));
ASSERT_STREQ(arg1, fgets(buf, sizeof(buf), f));
ASSERT_STREQ(arg2, fgets(buf, sizeof(buf), f));
ASSERT_EQ(0, pclose(f));
free(arg2);
free(arg1);
free(cmd);
}
return 0;
}
TEST(popen, torture) {
int i, n = 8;
pthread_t *t = _gc(malloc(sizeof(pthread_t) * n));
testlib_extract("/zip/echo.com", "echo.com", 0755);
for (i = 0; i < n; ++i) {
ASSERT_EQ(0, pthread_create(t + i, 0, Worker, 0));
}
for (i = 0; i < n; ++i) {
ASSERT_EQ(0, pthread_join(t[i], 0));
}
}