Skip to content

Commit f52f65b

Browse files
committed
Make system() and popen() thread safe
1 parent 997ce29 commit f52f65b

File tree

19 files changed

+135
-31
lines changed

19 files changed

+135
-31
lines changed

libc/calls/__sig2.c

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,21 +66,19 @@ static inline textwindows int __sig_is_masked(int sig) {
6666
}
6767

6868
textwindows int __sig_is_applicable(struct Signal *s) {
69-
return (s->tid <= 0 || s->tid == gettid()) && !__sig_is_masked(s->sig);
69+
return s->tid <= 0 || s->tid == gettid();
7070
}
7171

7272
/**
7373
* Dequeues signal that isn't masked.
7474
* @return signal or null if empty or none unmasked
7575
*/
7676
static textwindows struct Signal *__sig_remove(void) {
77-
int tid;
7877
struct Signal *prev, *res;
7978
if (__sig.queue) {
80-
tid = gettid();
8179
__sig_lock();
8280
for (prev = 0, res = __sig.queue; res; prev = res, res = res->next) {
83-
if (__sig_is_applicable(res)) {
81+
if (__sig_is_applicable(res) && !__sig_is_masked(res->sig)) {
8482
if (res == __sig.queue) {
8583
__sig.queue = res->next;
8684
} else if (prev) {

libc/calls/siglock.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,6 @@
1919
#include "libc/calls/state.internal.h"
2020
#include "libc/thread/thread.h"
2121

22-
static pthread_mutex_t __sig_lock_obj;
23-
2422
void(__sig_lock)(void) {
2523
pthread_mutex_lock(&__sig_lock_obj);
2624
}

test/libc/intrin/gettid_test.c renamed to libc/calls/siglock_obj.c

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,7 @@
1616
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
1717
│ PERFORMANCE OF THIS SOFTWARE. │
1818
╚─────────────────────────────────────────────────────────────────────────────*/
19-
#include "libc/calls/struct/sigaction.h"
20-
#include "libc/intrin/intrin.h"
21-
#include "libc/intrin/kprintf.h"
22-
#include "libc/sysv/consts/sig.h"
23-
#include "libc/testlib/testlib.h"
19+
#include "libc/calls/state.internal.h"
20+
#include "libc/thread/thread.h"
2421

25-
void OnSig(int sig) {
26-
kprintf("got sig\n");
27-
}
28-
29-
TEST(gettid, test) {
30-
signal(SIGTRAP, OnSig);
31-
DebugBreak();
32-
}
22+
pthread_mutex_t __sig_lock_obj;

libc/calls/state.internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ hidden extern bool __time_critical;
1111
hidden extern unsigned __sighandrvas[NSIG];
1212
hidden extern unsigned __sighandflags[NSIG];
1313
hidden extern pthread_mutex_t __fds_lock_obj;
14+
hidden extern pthread_mutex_t __sig_lock_obj;
1415
hidden extern const struct NtSecurityAttributes kNtIsInheritable;
1516

1617
void __fds_lock(void);

libc/intrin/fds_lock_obj.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:2;tab-width:8;coding:utf-8 -*-│
2+
│vi: set net ft=c ts=2 sts=2 sw=2 fenc=utf-8 :vi│
3+
╞══════════════════════════════════════════════════════════════════════════════╡
4+
│ Copyright 2022 Justine Alexandra Roberts Tunney │
5+
│ │
6+
│ Permission to use, copy, modify, and/or distribute this software for │
7+
│ any purpose with or without fee is hereby granted, provided that the │
8+
│ above copyright notice and this permission notice appear in all copies. │
9+
│ │
10+
│ THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL │
11+
│ WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED │
12+
│ WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE │
13+
│ AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL │
14+
│ DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR │
15+
│ PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER │
16+
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
17+
│ PERFORMANCE OF THIS SOFTWARE. │
18+
╚─────────────────────────────────────────────────────────────────────────────*/
19+
#include "libc/calls/state.internal.h"
20+
#include "libc/thread/thread.h"
21+
22+
pthread_mutex_t __fds_lock_obj;

libc/stdio/flushers.c renamed to libc/intrin/flushers.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,4 +18,5 @@
1818
╚─────────────────────────────────────────────────────────────────────────────*/
1919
#include "libc/stdio/fflush.internal.h"
2020

21+
pthread_mutex_t __fflush_lock_obj;
2122
struct StdioFlush __fflush;

libc/intrin/g_fds.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@
3030
STATIC_YOINK("_init_g_fds");
3131

3232
struct Fds g_fds;
33-
pthread_mutex_t __fds_lock_obj;
3433

3534
static textwindows dontinline void SetupWinStd(struct Fds *fds, int i, int x) {
3635
int64_t h;

libc/runtime/fork.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,23 @@
2121
#include "libc/calls/struct/sigset.internal.h"
2222
#include "libc/calls/syscall-nt.internal.h"
2323
#include "libc/calls/syscall-sysv.internal.h"
24-
#include "libc/calls/syscall_support-sysv.internal.h"
2524
#include "libc/dce.h"
2625
#include "libc/intrin/atomic.h"
2726
#include "libc/intrin/strace.internal.h"
27+
#include "libc/intrin/weaken.h"
2828
#include "libc/nt/process.h"
2929
#include "libc/runtime/internal.h"
3030
#include "libc/sysv/consts/sig.h"
31+
#include "libc/thread/posixthread.internal.h"
3132
#include "libc/thread/tls.h"
3233

3334
int _fork(uint32_t dwCreationFlags) {
3435
axdx_t ad;
3536
sigset_t old, all;
36-
int ax, dx, parent;
37+
int ax, dx, parent, parent_tid = 0;
38+
if (_weaken(_pthread_atfork)) {
39+
parent_tid = gettid();
40+
}
3741
if (!IsWindows()) {
3842
sigfillset(&all);
3943
sys_sigprocmask(SIG_BLOCK, &all, &old);
@@ -61,6 +65,9 @@ int _fork(uint32_t dwCreationFlags) {
6165
IsLinux() ? dx : sys_gettid(),
6266
memory_order_relaxed);
6367
}
68+
if (_weaken(_pthread_atfork)) {
69+
_weaken(_pthread_atfork)(parent_tid);
70+
}
6471
if (!IsWindows()) sys_sigprocmask(SIG_SETMASK, &old, 0);
6572
STRACE("fork() → 0 (child of %d)", parent);
6673
} else {

libc/stdio/fflush.internal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ struct StdioFlush {
1818
};
1919

2020
hidden extern struct StdioFlush __fflush;
21+
hidden extern pthread_mutex_t __fflush_lock_obj;
2122

2223
void __fflush_lock(void);
2324
void __fflush_unlock(void);

libc/stdio/fflush_unlocked.c

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@
1919
#include "libc/calls/calls.h"
2020
#include "libc/errno.h"
2121
#include "libc/intrin/bits.h"
22-
#include "libc/thread/thread.h"
2322
#include "libc/intrin/pushpop.h"
2423
#include "libc/macros.internal.h"
2524
#include "libc/mem/arraylist.internal.h"
@@ -29,8 +28,7 @@
2928
#include "libc/stdio/internal.h"
3029
#include "libc/stdio/stdio.h"
3130
#include "libc/sysv/consts/o.h"
32-
33-
static pthread_mutex_t __fflush_lock_obj;
31+
#include "libc/thread/thread.h"
3432

3533
void(__fflush_lock)(void) {
3634
pthread_mutex_lock(&__fflush_lock_obj);

0 commit comments

Comments
 (0)