Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/lib/libc/gen make popen/pclose thread safe
details: https://anonhg.NetBSD.org/src/rev/f92521848b88
branches: trunk
changeset: 552007:f92521848b88
user: cl <cl%NetBSD.org@localhost>
date: Mon Sep 15 22:30:38 2003 +0000
description:
make popen/pclose thread safe
diffstat:
lib/libc/gen/popen.c | 43 +++++++++++++++++++++++++++++++++++--------
1 files changed, 35 insertions(+), 8 deletions(-)
diffs (124 lines):
diff -r 2e2cd7c948b9 -r f92521848b88 lib/libc/gen/popen.c
--- a/lib/libc/gen/popen.c Mon Sep 15 21:03:10 2003 +0000
+++ b/lib/libc/gen/popen.c Mon Sep 15 22:30:38 2003 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: popen.c,v 1.27 2003/08/07 16:42:55 agc Exp $ */
+/* $NetBSD: popen.c,v 1.28 2003/09/15 22:30:38 cl Exp $ */
/*
* Copyright (c) 1988, 1993
@@ -37,7 +37,7 @@
#if 0
static char sccsid[] = "@(#)popen.c 8.3 (Berkeley) 5/3/95";
#else
-__RCSID("$NetBSD: popen.c,v 1.27 2003/08/07 16:42:55 agc Exp $");
+__RCSID("$NetBSD: popen.c,v 1.28 2003/09/15 22:30:38 cl Exp $");
#endif
#endif /* LIBC_SCCS and not lint */
@@ -68,9 +68,16 @@
static struct pid {
struct pid *next;
FILE *fp;
+#ifdef _REENTRANT
+ int fd;
+#endif
pid_t pid;
} *pidlist;
+#ifdef _REENTRANT
+static rwlock_t pidlist_lock = RWLOCK_INITIALIZER;
+#endif
+
FILE *
popen(command, type)
const char *command, *type;
@@ -108,11 +115,13 @@
return (NULL);
}
+ rwlock_rdlock(&pidlist_lock);
rwlock_rdlock(&__environ_lock);
switch (pid = vfork()) {
case -1: /* Error. */
serrno = errno;
rwlock_unlock(&__environ_lock);
+ rwlock_unlock(&pidlist_lock);
free(cur);
(void)close(pdes[0]);
(void)close(pdes[1]);
@@ -124,7 +133,11 @@
from previous popen() calls that remain open in the
parent process are closed in the new child process. */
for (old = pidlist; old; old = old->next)
+#ifdef _REENTRANT
+ close(old->fd); /* don't allow a flush */
+#else
close(fileno(old->fp)); /* don't allow a flush */
+#endif
if (*type == 'r') {
(void)close(pdes[0]);
@@ -151,9 +164,15 @@
/* Parent; assume fdopen can't fail. */
if (*type == 'r') {
iop = fdopen(pdes[0], type);
+#ifdef _REENTRANT
+ cur->fd = pdes[0];
+#endif
(void)close(pdes[1]);
} else {
iop = fdopen(pdes[1], type);
+#ifdef _REENTRANT
+ cur->fd = pdes[1];
+#endif
(void)close(pdes[0]);
}
@@ -162,6 +181,7 @@
cur->pid = pid;
cur->next = pidlist;
pidlist = cur;
+ rwlock_unlock(&pidlist_lock);
return (iop);
}
@@ -181,25 +201,32 @@
_DIAGASSERT(iop != NULL);
+ rwlock_wrlock(&pidlist_lock);
+
/* Find the appropriate file pointer. */
for (last = NULL, cur = pidlist; cur; last = cur, cur = cur->next)
if (cur->fp == iop)
break;
- if (cur == NULL)
+ if (cur == NULL) {
+ rwlock_unlock(&pidlist_lock);
return (-1);
+ }
(void)fclose(iop);
- do {
- pid = waitpid(cur->pid, &pstat, 0);
- } while (pid == -1 && errno == EINTR);
-
/* Remove the entry from the linked list. */
if (last == NULL)
pidlist = cur->next;
else
last->next = cur->next;
+
+ rwlock_unlock(&pidlist_lock);
+
+ do {
+ pid = waitpid(cur->pid, &pstat, 0);
+ } while (pid == -1 && errno == EINTR);
+
free(cur);
-
+
return (pid == -1 ? -1 : pstat);
}
Home |
Main Index |
Thread Index |
Old Index