瀏覽代碼

fix usage of locks with vfork

__release_ptc() is only valid in the parent; if it's performed in the
child, the lock will be unlocked early then double-unlocked later,
corrupting the lock state.
Rich Felker 12 年之前
父節點
當前提交
599f973603
共有 3 個文件被更改,包括 4 次插入3 次删除
  1. 1 1
      src/process/posix_spawn.c
  2. 2 1
      src/process/system.c
  3. 1 1
      src/stdio/popen.c

+ 1 - 1
src/process/posix_spawn.c

@@ -35,9 +35,9 @@ int __posix_spawnx(pid_t *restrict res, const char *restrict path,
 
 	__acquire_ptc();
 	pid = __vfork();
-	__release_ptc();
 
 	if (pid) {
+		__release_ptc();
 		sigprocmask(SIG_SETMASK, &oldmask, 0);
 		if (pid < 0) return -pid;
 		*res = pid;

+ 2 - 1
src/process/system.c

@@ -29,7 +29,8 @@ int system(const char *cmd)
 
 	__acquire_ptc();
 	pid = __vfork();
-	__release_ptc();
+
+	if (pid) __release_ptc();
 
 	if (pid > 0) {
 		sigset_t new = old;

+ 1 - 1
src/stdio/popen.c

@@ -38,9 +38,9 @@ FILE *popen(const char *cmd, const char *mode)
 	
 	__acquire_ptc();
 	pid = __vfork();
-	__release_ptc();
 
 	if (pid) {
+		__release_ptc();
 		__syscall(SYS_close, p[1-op]);
 		sigprocmask(SIG_BLOCK, SIGALL_SET, &old);
 		if (pid < 0) {