summaryrefslogtreecommitdiff
path: root/libc/stdio/popen.c
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2006-12-07 23:24:02 +0000
committerEric Andersen <andersen@codepoet.org>2006-12-07 23:24:02 +0000
commit1478c2de052374c6356db5513749a144c13791b1 (patch)
tree3b22a3f8361f94c99508c497e240ecb71acf8641 /libc/stdio/popen.c
parent99d6c367c4820a072dc4ada51561df17e2093778 (diff)
Major cleanup of internal mutex locking. Be more consistant in how we do
things, and avoid potential deadlocks caused when a thread holding a uClibc internal lock get canceled and terminates without releasing the lock. This change also provides a single place, bits/uClibc_mutex.h, for thread libraries to modify to change all instances of internal locking.
Diffstat (limited to 'libc/stdio/popen.c')
-rw-r--r--libc/stdio/popen.c33
1 files changed, 17 insertions, 16 deletions
diff --git a/libc/stdio/popen.c b/libc/stdio/popen.c
index 2163d7f8c..43d07fa0f 100644
--- a/libc/stdio/popen.c
+++ b/libc/stdio/popen.c
@@ -20,6 +20,11 @@
#include <errno.h>
#include <unistd.h>
#include <sys/wait.h>
+#include <bits/uClibc_mutex.h>
+
+#ifdef __UCLIBC_MJN3_ONLY__
+#warning "hmm... susv3 says Pipe streams are byte-oriented."
+#endif /* __UCLIBC_MJN3_ONLY__ */
libc_hidden_proto(close)
libc_hidden_proto(_exit)
@@ -34,22 +39,16 @@ libc_hidden_proto(fclose)
/* uClinux-2.0 has vfork, but Linux 2.0 doesn't */
#include <sys/syscall.h>
#if ! defined __NR_vfork
-# define vfork fork
+# define vfork fork
# define VFORK_LOCK ((void) 0)
-# define VFORK_UNLOCK ((void) 0)
+# define VFORK_UNLOCK ((void) 0)
libc_hidden_proto(fork)
#endif
-#ifdef __UCLIBC_HAS_THREADS__
-# include <pthread.h>
-static pthread_mutex_t mylock = PTHREAD_MUTEX_INITIALIZER;
-#endif
-#define LOCK __pthread_mutex_lock(&mylock)
-#define UNLOCK __pthread_mutex_unlock(&mylock)
-
#ifndef VFORK_LOCK
-# define VFORK_LOCK LOCK
-# define VFORK_UNLOCK UNLOCK
+__UCLIBC_MUTEX_STATIC(mylock, PTHREAD_MUTEX_INITIALIZER);
+# define VFORK_LOCK __UCLIBC_MUTEX_LOCK(mylock)
+# define VFORK_UNLOCK __UCLIBC_MUTEX_UNLOCK(mylock)
#endif
struct popen_list_item {
@@ -126,11 +125,11 @@ FILE *popen(const char *command, const char *modes)
if (pid > 0) { /* Parent of vfork... */
pi->pid = pid;
pi->f = fp;
- LOCK;
+ VFORK_LOCK;
pi->next = popen_list;
popen_list = pi;
- UNLOCK;
-
+ VFORK_UNLOCK;
+
return fp;
}
@@ -144,6 +143,8 @@ FILE *popen(const char *command, const char *modes)
return NULL;
}
+#warning is pclose correct wrt the new mutex semantics?
+
int pclose(FILE *stream)
{
struct popen_list_item *p;
@@ -152,7 +153,7 @@ int pclose(FILE *stream)
/* First, find the list entry corresponding to stream and remove it
* from the list. Set p to the list item (NULL if not found). */
- LOCK;
+ VFORK_LOCK;
if ((p = popen_list) != NULL) {
if (p->f == stream) {
popen_list = p->next;
@@ -171,7 +172,7 @@ int pclose(FILE *stream)
} while (1);
}
}
- UNLOCK;
+ VFORK_UNLOCK;
if (p) {
pid = p->pid; /* Save the pid we need */