From 4470d66ddc7a41c8efee2f307a2dece3227f5515 Mon Sep 17 00:00:00 2001 From: Christopher Faylor Date: Fri, 23 Jun 2006 00:19:39 +0000 Subject: [PATCH] * 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. --- winsup/cygwin/ChangeLog | 8 ++++++ winsup/cygwin/fhandler_fifo.cc | 45 +++++++++++++++++++++++++++++++++- winsup/cygwin/smallprint.c | 4 +-- winsup/cygwin/sync.h | 3 ++- 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 + + * 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 * 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 @@ -66,6 +66,7 @@ public: locker.release (); } friend class dtable; + friend class fhandler_fifo; }; #endif /*_SYNC_H*/