Throughout, call fcntl64 instead of fcntl or fcntl_worker.
* fcntl.cc (fcntl_worker): Remove. (fcntl64): Add fault handler. Move fcntl_worker stuff here. Add case for locking and call fhandler's lock method directly. Make sure that F_FLOCK flag isn't set in lock call. (_fcntl): Add fault handler. * fhandler.cc (fhandler_base::fcntl): Drop lock cases. * flock.cc (flock): Add fault handler. Simplify code. Call fhandlers lock method directly instead of fcntl_worker. Add debug output. (lockf): Add fault handler. Call fhandlers lock method directly instead of fcntl_worker. Add debug output. * winsup.h (fcntl_worker): Drop declaration. (fcntl64): Declare.
This commit is contained in:
		| @@ -1,3 +1,19 @@ | ||||
| 2008-04-01  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	Throughout, call fcntl64 instead of fcntl or fcntl_worker. | ||||
| 	* fcntl.cc (fcntl_worker): Remove. | ||||
| 	(fcntl64): Add fault handler.  Move fcntl_worker stuff here.  Add case | ||||
| 	for locking and call fhandler's lock method directly.  Make sure that | ||||
| 	F_FLOCK flag isn't set in lock call. | ||||
| 	(_fcntl): Add fault handler. | ||||
| 	* fhandler.cc (fhandler_base::fcntl): Drop lock cases. | ||||
| 	* flock.cc (flock): Add fault handler.  Simplify code.  Call fhandlers | ||||
| 	lock method directly instead of fcntl_worker.  Add debug output. | ||||
| 	(lockf): Add fault handler.  Call fhandlers lock method directly | ||||
| 	instead of fcntl_worker.  Add debug output. | ||||
| 	* winsup.h (fcntl_worker): Drop declaration. | ||||
| 	(fcntl64): Declare. | ||||
|  | ||||
| 2008-03-31  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* smallprint.cc (__small_vswprintf): Fix uninitialized usage of `w'. | ||||
|   | ||||
| @@ -20,10 +20,12 @@ details. */ | ||||
| #include "thread.h" | ||||
| #include "cygtls.h" | ||||
|  | ||||
| int | ||||
| fcntl_worker (int fd, int cmd, void *arg) | ||||
| extern "C" int | ||||
| fcntl64 (int fd, int cmd, ...) | ||||
| { | ||||
|   int res; | ||||
|   int res = -1; | ||||
|   void *arg = NULL; | ||||
|   va_list args; | ||||
|  | ||||
|   myfault efault; | ||||
|   if (efault.faulted (EFAULT)) | ||||
| @@ -31,29 +33,33 @@ fcntl_worker (int fd, int cmd, void *arg) | ||||
|  | ||||
|   cygheap_fdget cfd (fd, true); | ||||
|   if (cfd < 0) | ||||
|     { | ||||
|       res = -1; | ||||
|     goto done; | ||||
|     } | ||||
|   if (cmd != F_DUPFD) | ||||
|     res = cfd->fcntl (cmd, arg); | ||||
|   else | ||||
|     res = dup2 (fd, cygheap_fdnew (((int) arg) - 1)); | ||||
| done: | ||||
|   syscall_printf ("%d = fcntl (%d, %d, %p)", res, fd, cmd, arg); | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| extern "C" int | ||||
| fcntl64 (int fd, int cmd, ...) | ||||
| { | ||||
|   void *arg = NULL; | ||||
|   va_list args; | ||||
|  | ||||
|   va_start (args, cmd); | ||||
|   arg = va_arg (args, void *); | ||||
|   va_end (args); | ||||
|   return fcntl_worker (fd, cmd, arg); | ||||
|  | ||||
|   switch (cmd) | ||||
|     { | ||||
|     case F_DUPFD: | ||||
|       res = dup2 (fd, cygheap_fdnew (((int) arg) - 1)); | ||||
|       break; | ||||
|     case F_GETLK: | ||||
|     case F_SETLK: | ||||
|     case F_SETLKW: | ||||
|       { | ||||
|         struct __flock64 *fl = (struct __flock64 *) arg; | ||||
|         fl->l_type &= F_RDLCK | F_WRLCK | F_UNLCK; | ||||
|         res = cfd->lock (cmd, fl); | ||||
|       } | ||||
|       break; | ||||
|     default: | ||||
|       res = cfd->fcntl (cmd, arg); | ||||
|       break; | ||||
|     } | ||||
| done: | ||||
|   syscall_printf ("%d = fcntl (%d, %d, %p)", res, fd, cmd, arg); | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| extern "C" int | ||||
| @@ -64,6 +70,10 @@ _fcntl (int fd, int cmd, ...) | ||||
|   struct __flock32 *src = NULL; | ||||
|   struct __flock64 dst; | ||||
|  | ||||
|   myfault efault; | ||||
|   if (efault.faulted (EFAULT)) | ||||
|     return -1; | ||||
|  | ||||
|   va_start (args, cmd); | ||||
|   arg = va_arg (args, void *); | ||||
|   va_end (args); | ||||
| @@ -77,7 +87,7 @@ _fcntl (int fd, int cmd, ...) | ||||
|       dst.l_pid = src->l_pid; | ||||
|       arg = &dst; | ||||
|     } | ||||
|   int res = fcntl_worker (fd, cmd, arg); | ||||
|   int res = fcntl64 (fd, cmd, arg); | ||||
|   if (cmd == F_GETLK) | ||||
|     { | ||||
|       src->l_type = dst.l_type; | ||||
|   | ||||
| @@ -1178,11 +1178,6 @@ int fhandler_base::fcntl (int cmd, void *arg) | ||||
|       } | ||||
|       res = 0; | ||||
|       break; | ||||
|     case F_GETLK: | ||||
|     case F_SETLK: | ||||
|     case F_SETLKW: | ||||
|       res = lock (cmd, (struct __flock64 *) arg); | ||||
|       break; | ||||
|     default: | ||||
|       set_errno (EINVAL); | ||||
|       res = -1; | ||||
|   | ||||
| @@ -58,7 +58,7 @@ | ||||
|  * $RH: flock.c,v 1.2 2000/08/23 17:07:00 nalin Exp $ | ||||
|  */ | ||||
|  | ||||
| /* The lockf function has been taken from FreeBSD with the following | ||||
| /* The lockf function is based upon FreeBSD sources with the following | ||||
|  * copyright. | ||||
|  * | ||||
|  * Copyright (c) 1997 The NetBSD Foundation, Inc. | ||||
| @@ -835,8 +835,8 @@ fhandler_disk_file::lock (int a_op, struct __flock64 *fl) | ||||
|     } | ||||
|   need_fork_fixup (true); | ||||
|  | ||||
|   /* Unlock the fd table which has been locked in fcntl_worker, otherwise | ||||
|      a blocking F_SETLKW never wakes up on a signal. */ | ||||
|   /* Unlock the fd table which has been locked in fcntl_worker/lock_worker, | ||||
|      otherwise a blocking F_SETLKW never wakes up on a signal. */ | ||||
|   cygheap->fdtab.unlock (); | ||||
|  | ||||
|   lockf_t **head = &node->i_lockf; | ||||
| @@ -1495,68 +1495,59 @@ lf_wakelock (lockf_t *listhead, HANDLE fhdl) | ||||
|   listhead->del_lock_obj (fhdl, true); | ||||
| } | ||||
|  | ||||
| int | ||||
| extern "C" int | ||||
| flock (int fd, int operation) | ||||
| { | ||||
|   int i, cmd; | ||||
|   struct __flock64 l = { 0, 0, 0, 0, 0 }; | ||||
|   if (operation & LOCK_NB) | ||||
|     { | ||||
|       cmd = F_SETLK; | ||||
|     } | ||||
|   else | ||||
|     { | ||||
|       cmd = F_SETLKW; | ||||
|     } | ||||
|   l.l_whence = SEEK_SET; | ||||
|   int res = -1; | ||||
|   int cmd; | ||||
|   struct __flock64 fl = { 0, SEEK_SET, 0, 0, 0 }; | ||||
|  | ||||
|   myfault efault; | ||||
|   if (efault.faulted (EFAULT)) | ||||
|     return -1; | ||||
|  | ||||
|   cygheap_fdget cfd (fd, true); | ||||
|   if (cfd < 0) | ||||
|     goto done; | ||||
|  | ||||
|   cmd = (operation & LOCK_NB) ? F_SETLK : F_SETLKW; | ||||
|   switch (operation & (~LOCK_NB)) | ||||
|     { | ||||
|     case LOCK_EX: | ||||
|       l.l_type = F_WRLCK | F_FLOCK; | ||||
|       i = fcntl_worker (fd, cmd, &l); | ||||
|       if (i == -1) | ||||
| 	{ | ||||
| 	  if ((get_errno () == EAGAIN) || (get_errno () == EACCES)) | ||||
| 	    { | ||||
| 	      set_errno (EWOULDBLOCK); | ||||
| 	    } | ||||
| 	} | ||||
|       fl.l_type = F_WRLCK | F_FLOCK; | ||||
|       break; | ||||
|     case LOCK_SH: | ||||
|       l.l_type = F_RDLCK | F_FLOCK; | ||||
|       i = fcntl_worker (fd, cmd, &l); | ||||
|       if (i == -1) | ||||
| 	{ | ||||
| 	  if ((get_errno () == EAGAIN) || (get_errno () == EACCES)) | ||||
| 	    { | ||||
| 	      set_errno (EWOULDBLOCK); | ||||
| 	    } | ||||
| 	} | ||||
|       fl.l_type = F_RDLCK | F_FLOCK; | ||||
|       break; | ||||
|     case LOCK_UN: | ||||
|       l.l_type = F_UNLCK | F_FLOCK; | ||||
|       i = fcntl_worker (fd, cmd, &l); | ||||
|       if (i == -1) | ||||
| 	{ | ||||
| 	  if ((get_errno () == EAGAIN) || (get_errno () == EACCES)) | ||||
| 	    { | ||||
| 	      set_errno (EWOULDBLOCK); | ||||
| 	    } | ||||
| 	} | ||||
|       fl.l_type = F_UNLCK | F_FLOCK; | ||||
|       break; | ||||
|     default: | ||||
|       i = -1; | ||||
|       set_errno (EINVAL); | ||||
|       break; | ||||
|       goto done; | ||||
|     } | ||||
|   return i; | ||||
|   res = cfd->lock (cmd, &fl); | ||||
|   if (res == -1 && (get_errno () == EAGAIN) || (get_errno () == EACCES)) | ||||
|     set_errno (EWOULDBLOCK); | ||||
| done: | ||||
|   syscall_printf ("%d = flock (%d, %d)", res, fd, operation); | ||||
|   return res; | ||||
| } | ||||
|  | ||||
| extern "C" int | ||||
| lockf (int filedes, int function, _off64_t size) | ||||
| { | ||||
|   struct flock fl; | ||||
|   int res = -1; | ||||
|   int cmd; | ||||
|   struct __flock64 fl; | ||||
|  | ||||
|   myfault efault; | ||||
|   if (efault.faulted (EFAULT)) | ||||
|     return -1; | ||||
|  | ||||
|   cygheap_fdget cfd (filedes, true); | ||||
|   if (cfd < 0) | ||||
|     goto done; | ||||
|  | ||||
|   fl.l_start = 0; | ||||
|   fl.l_len = size; | ||||
| @@ -1578,18 +1569,21 @@ lockf (int filedes, int function, _off64_t size) | ||||
|       break; | ||||
|     case F_TEST: | ||||
|       fl.l_type = F_WRLCK; | ||||
|       if (fcntl_worker (filedes, F_GETLK, &fl) == -1) | ||||
| 	return -1; | ||||
|       if (cfd->lock (F_GETLK, &fl) == -1) | ||||
| 	goto done; | ||||
|       if (fl.l_type == F_UNLCK || fl.l_pid == getpid ()) | ||||
| 	return 0; | ||||
| 	res = 0; | ||||
|       else | ||||
| 	errno = EAGAIN; | ||||
|       return -1; | ||||
|       goto done; | ||||
|       /* NOTREACHED */ | ||||
|     default: | ||||
|       errno = EINVAL; | ||||
|       return -1; | ||||
|       goto done; | ||||
|       /* NOTREACHED */ | ||||
|     } | ||||
|  | ||||
|   return fcntl_worker (filedes, cmd, &fl); | ||||
|   res = cfd->lock (cmd, &fl); | ||||
| done: | ||||
|   syscall_printf ("%d = lockf (%d, %d, %D)", res, filedes, function, size); | ||||
|   return res; | ||||
| } | ||||
|   | ||||
| @@ -427,7 +427,7 @@ int res_nsend( res_state statp, const unsigned char * MsgPtr, | ||||
|       return -1; | ||||
|     } | ||||
|     /* Set close on exec flag */ | ||||
|     if (fcntl(statp->sockfd, F_SETFD, 1) == -1) { | ||||
|     if (fcntl64(statp->sockfd, F_SETFD, 1) == -1) { | ||||
|       DPRINTF(debug, "fcntl: %s\n", | ||||
| 	      strerror(errno)); | ||||
|       statp->res_h_errno = NETDB_INTERNAL; | ||||
|   | ||||
| @@ -203,7 +203,7 @@ cygwin_rcmd_af(char **ahost, in_port_t rport, const char *locuser, | ||||
| 			    NULL); | ||||
| 			return (-1); | ||||
| 		} | ||||
| 		fcntl(s, F_SETOWN, pid); | ||||
| 		fcntl64(s, F_SETOWN, pid); | ||||
| 		if (cygwin_connect(s, ai->ai_addr, ai->ai_addrlen) >= 0) | ||||
| 			break; | ||||
| 		(void)close(s); | ||||
|   | ||||
| @@ -209,14 +209,14 @@ public: | ||||
|     fl.l_whence = SEEK_SET; | ||||
|     fl.l_start = 0; | ||||
|     fl.l_len = size; | ||||
|     return fcntl (fd, F_SETLKW, &fl); | ||||
|     return fcntl64 (fd, F_SETLKW, &fl); | ||||
|   } | ||||
|   int unlock (int fd) | ||||
|   { | ||||
|     if (!fl.l_len) | ||||
|       return 0; | ||||
|     fl.l_type = F_UNLCK; | ||||
|     return fcntl (fd, F_SETLKW, &fl); | ||||
|     return fcntl64 (fd, F_SETLKW, &fl); | ||||
|   } | ||||
| }; | ||||
|  | ||||
|   | ||||
| @@ -2940,12 +2940,12 @@ locked_append (int fd, const void * buf, size_t size) | ||||
|  | ||||
|   do | ||||
|     if ((lock_buffer.l_start = lseek64 (fd, 0, SEEK_END)) != (_off64_t) -1 | ||||
| 	&& fcntl_worker (fd, F_SETLKW, &lock_buffer) != -1) | ||||
| 	&& fcntl64 (fd, F_SETLKW, &lock_buffer) != -1) | ||||
|       { | ||||
| 	if (lseek64 (fd, 0, SEEK_END) != (_off64_t) -1) | ||||
| 	  write (fd, buf, size); | ||||
| 	lock_buffer.l_type = F_UNLCK; | ||||
| 	fcntl_worker (fd, F_SETLK, &lock_buffer); | ||||
| 	fcntl64 (fd, F_SETLK, &lock_buffer); | ||||
| 	break; | ||||
|       } | ||||
|   while (count++ < 1000 | ||||
| @@ -3452,7 +3452,7 @@ popen (const char *command, const char *in_type) | ||||
|     } | ||||
|  | ||||
|   FILE *fp = fdopen (fd, in_type); | ||||
|   fcntl (fd, F_SETFD, fcntl (fd, F_GETFD, 0) | FD_CLOEXEC); | ||||
|   fcntl64 (fd, F_SETFD, fcntl64 (fd, F_GETFD, 0) | FD_CLOEXEC); | ||||
|  | ||||
|   if (!fp) | ||||
|     goto err; | ||||
| @@ -3467,11 +3467,11 @@ popen (const char *command, const char *in_type) | ||||
|  | ||||
|   { | ||||
|     lock_process now; | ||||
|     int state = fcntl (stdwhat, F_GETFD, 0); | ||||
|     fcntl (stdwhat, F_SETFD, state | FD_CLOEXEC); | ||||
|     int state = fcntl64 (stdwhat, F_GETFD, 0); | ||||
|     fcntl64 (stdwhat, F_SETFD, state | FD_CLOEXEC); | ||||
|     pid = spawn_guts ("/bin/sh", argv, cur_environ (), _P_NOWAIT, | ||||
| 		      __stdin, __stdout); | ||||
|     fcntl (stdwhat, F_SETFD, state); | ||||
|     fcntl64 (stdwhat, F_SETFD, state); | ||||
|   } | ||||
|  | ||||
|   if (pid < 0) | ||||
|   | ||||
| @@ -217,7 +217,7 @@ connect_syslogd () | ||||
|   else | ||||
|     syslogd_inited = inited_dgram; | ||||
|   syslogd_sock = fd; | ||||
|   fcntl (syslogd_sock, F_SETFD, FD_CLOEXEC); | ||||
|   fcntl64 (syslogd_sock, F_SETFD, FD_CLOEXEC); | ||||
|   return; | ||||
| } | ||||
|  | ||||
|   | ||||
| @@ -54,7 +54,7 @@ extern struct passwd *getpwnam (const char *); | ||||
| extern struct __sFILE64 *fopen64 (const char *, const char *); | ||||
| extern struct hostent *cygwin_gethostbyname (const char *name); | ||||
| extern unsigned long cygwin_inet_addr (const char *cp); | ||||
|  | ||||
| extern int fcntl64 (int fd, int cmd, ...); | ||||
| #ifdef __cplusplus | ||||
| } | ||||
| #endif | ||||
| @@ -324,7 +324,6 @@ int symlink_worker (const char *, const char *, bool, bool) | ||||
|  | ||||
| class path_conv; | ||||
|  | ||||
| int fcntl_worker (int fd, int cmd, void *arg); | ||||
| int __stdcall stat_worker (path_conv &pc, struct __stat64 *buf) __attribute__ ((regparm (2))); | ||||
|  | ||||
| __ino64_t __stdcall readdir_get_ino (const char *path, bool dot_dot) __attribute__ ((regparm (2))); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user