* 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.
This commit is contained in:
		| @@ -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> | 2006-06-15  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
| 	* cygwin.din: Export __srget_r, __swbuf_r. | 	* cygwin.din: Export __srget_r, __swbuf_r. | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| /* fhandler_fifo.cc - See fhandler.h for a description of the fhandler classes. | /* 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. |    This file is part of Cygwin. | ||||||
|  |  | ||||||
| @@ -141,10 +141,48 @@ out: | |||||||
|   return res; |   return res; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | #define FIFO_PREFIX "_cygfifo_" | ||||||
|  |  | ||||||
| int | int | ||||||
| fhandler_fifo::open (int flags, mode_t) | fhandler_fifo::open (int flags, mode_t) | ||||||
| { | { | ||||||
|   int res = 1; |   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_io_handle (NULL); | ||||||
|   set_output_handle (NULL); |   set_output_handle (NULL); | ||||||
| @@ -174,6 +212,11 @@ fhandler_fifo::open (int flags, mode_t) | |||||||
|     } |     } | ||||||
|  |  | ||||||
| out: | out: | ||||||
|  |   if (h) | ||||||
|  |     { | ||||||
|  |       ReleaseMutex (h); | ||||||
|  |       CloseHandle (h); | ||||||
|  |     } | ||||||
|   debug_printf ("returning %d, errno %d", res, get_errno ()); |   debug_printf ("returning %d, errno %d", res, get_errno ()); | ||||||
|   return res; |   return res; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| /* smallprint.c: small print routines for WIN32 | /* 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. | This file is part of Cygwin. | ||||||
|  |  | ||||||
| @@ -159,7 +159,7 @@ __small_vsprintf (char *dst, const char *fmt, va_list ap) | |||||||
| 		    s = tmp; | 		    s = tmp; | ||||||
| 		  goto fillin; | 		  goto fillin; | ||||||
| 		case '.': | 		case '.': | ||||||
| 		  n = strtol (fmt, (char **)&fmt, 10); | 		  n = strtol (fmt, (char **) &fmt, 10); | ||||||
| 		  if (*fmt++ != 's') | 		  if (*fmt++ != 's') | ||||||
| 		    goto endfor; | 		    goto endfor; | ||||||
| 		case 's': | 		case 's': | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| /* sync.h: Header file for cygwin synchronization primitives. | /* 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> |    Written by Christopher Faylor <cgf@cygnus.com> | ||||||
|  |  | ||||||
| @@ -66,6 +66,7 @@ public: | |||||||
|       locker.release (); |       locker.release (); | ||||||
|   } |   } | ||||||
|   friend class dtable; |   friend class dtable; | ||||||
|  |   friend class fhandler_fifo; | ||||||
| }; | }; | ||||||
|  |  | ||||||
| #endif /*_SYNC_H*/ | #endif /*_SYNC_H*/ | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user