summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher Faylor <me@cgf.cx>2006-06-23 00:19:39 +0000
committerChristopher Faylor <me@cgf.cx>2006-06-23 00:19:39 +0000
commit4470d66ddc7a41c8efee2f307a2dece3227f5515 (patch)
tree28079124f0580364885a7779dc8eb8b99ba09022
parent083f3e4a23a83c4f62754da41a9bbac4a95cf1a7 (diff)
downloadcygnal-4470d66ddc7a41c8efee2f307a2dece3227f5515.tar.gz
cygnal-4470d66ddc7a41c8efee2f307a2dece3227f5515.tar.bz2
cygnal-4470d66ddc7a41c8efee2f307a2dece3227f5515.zip
* fhandler_fifo.cc (fhandler_fifo::open): Release process lock and grab a
system-wide mutex to prevent a deadlock and a race. * sync.h (lock_process): Make fhandler_fifo a friend. * smallprint.c (__small_vsprintf): Cosmetic change.
-rw-r--r--winsup/cygwin/ChangeLog8
-rw-r--r--winsup/cygwin/fhandler_fifo.cc45
-rw-r--r--winsup/cygwin/smallprint.c4
-rw-r--r--winsup/cygwin/sync.h3
4 files changed, 56 insertions, 4 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index af6c3dd13..a0c0fd9f4 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,11 @@
+2006-06-22 Christopher Faylor <cgf@timesys.com>
+
+ * fhandler_fifo.cc (fhandler_fifo::open): Release process lock and grab
+ a system-wide mutex to prevent a deadlock and a race.
+ * sync.h (lock_process): Make fhandler_fifo a friend.
+
+ * smallprint.c (__small_vsprintf): Cosmetic change.
+
2006-06-15 Corinna Vinschen <corinna@vinschen.de>
* cygwin.din: Export __srget_r, __swbuf_r.
diff --git a/winsup/cygwin/fhandler_fifo.cc b/winsup/cygwin/fhandler_fifo.cc
index 14292671a..8f1a58477 100644
--- a/winsup/cygwin/fhandler_fifo.cc
+++ b/winsup/cygwin/fhandler_fifo.cc
@@ -1,6 +1,6 @@
/* fhandler_fifo.cc - See fhandler.h for a description of the fhandler classes.
- Copyright 2002, 2003, 2004, 2005 Red Hat, Inc.
+ Copyright 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
This file is part of Cygwin.
@@ -141,10 +141,48 @@ out:
return res;
}
+#define FIFO_PREFIX "_cygfifo_"
+
int
fhandler_fifo::open (int flags, mode_t)
{
int res = 1;
+ char mutex[CYG_MAX_PATH];
+ char *emutex = mutex + CYG_MAX_PATH;
+ char *p, *p1;
+
+ /* Generate a semi-unique name to associate with this fifo but try to ensure
+ that it is no larger than CYG_MAX_PATH */
+ for (p = mutex, p1 = strchr (get_name (), '\0');
+ --p1 >= get_name () && p < emutex ; p++)
+ *p = (*p1 == '/') ? '_' : *p1;
+ strncpy (p, FIFO_PREFIX, emutex - p);
+ mutex[CYG_MAX_PATH - 1] = '\0';
+
+ /* Create a mutex lock access to this fifo to prevent a race by two processes
+ trying to figure out if they own the fifo or if they should create it. */
+ HANDLE h = CreateMutex (&sec_none_nih, false, mutex);
+ if (!h)
+ {
+ __seterrno ();
+ system_printf ("couldn't open fifo mutex '%s', %E", mutex);
+ res = 0;
+ goto out;
+ }
+
+ lock_process::locker.release (); /* Since we may be a while, release the
+ process lock that is held when we
+ open an fd. */
+ /* FIXME? Need to wait for signal here?
+ This shouldn't block for long, but... */
+ DWORD resw = WaitForSingleObject (h, INFINITE);
+ lock_process::locker.acquire (); /* Restore the lock */
+ if (resw != WAIT_OBJECT_0 && resw != WAIT_ABANDONED_0)
+ {
+ __seterrno ();
+ system_printf ("Wait for fifo mutex '%s' failed, %E", mutex);
+ goto out;
+ }
set_io_handle (NULL);
set_output_handle (NULL);
@@ -174,6 +212,11 @@ fhandler_fifo::open (int flags, mode_t)
}
out:
+ if (h)
+ {
+ ReleaseMutex (h);
+ CloseHandle (h);
+ }
debug_printf ("returning %d, errno %d", res, get_errno ());
return res;
}
diff --git a/winsup/cygwin/smallprint.c b/winsup/cygwin/smallprint.c
index 851e1414c..37c70ee60 100644
--- a/winsup/cygwin/smallprint.c
+++ b/winsup/cygwin/smallprint.c
@@ -1,6 +1,6 @@
/* smallprint.c: small print routines for WIN32
- Copyright 1996, 1998, 2000, 2001, 2002 Red Hat, Inc.
+ Copyright 1996, 1998, 2000, 2001, 2002, 2003, 2005, 2006 Red Hat, Inc.
This file is part of Cygwin.
@@ -159,7 +159,7 @@ __small_vsprintf (char *dst, const char *fmt, va_list ap)
s = tmp;
goto fillin;
case '.':
- n = strtol (fmt, (char **)&fmt, 10);
+ n = strtol (fmt, (char **) &fmt, 10);
if (*fmt++ != 's')
goto endfor;
case 's':
diff --git a/winsup/cygwin/sync.h b/winsup/cygwin/sync.h
index f8019a8fe..8fd01df3a 100644
--- a/winsup/cygwin/sync.h
+++ b/winsup/cygwin/sync.h
@@ -1,6 +1,6 @@
/* sync.h: Header file for cygwin synchronization primitives.
- Copyright 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc.
+ Copyright 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006 Red Hat, Inc.
Written by Christopher Faylor <cgf@cygnus.com>
@@ -66,6 +66,7 @@ public:
locker.release ();
}
friend class dtable;
+ friend class fhandler_fifo;
};
#endif /*_SYNC_H*/