From 1eb14bae8cc488dad2da4925cb73e4376c69fe45 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 23 Oct 2000 20:16:52 +0000 Subject: [PATCH] * fcntl.cc (_fcntl): Rearrange as wrapper function. Move all functionality except F_DUPFD to fhandler classes. * fhandler.cc (fhandler_base::fcntl): New method. * net.cc (fhandler_socket::fcntl): Ditto. * fhandler.h (class fhandler_base): Add method prototype for fcntl(). (class fhandler_socket): Ditto. --- winsup/cygwin/ChangeLog | 9 +++++ winsup/cygwin/fcntl.cc | 83 ++++++--------------------------------- winsup/cygwin/fhandler.cc | 44 +++++++++++++++++++++ winsup/cygwin/fhandler.h | 2 + winsup/cygwin/net.cc | 27 ++++++++++++- 5 files changed, 92 insertions(+), 73 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index ae9c3187c..e43c4a537 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,12 @@ +Mon Oct 23 21:43:00 2000 Corinna Vinschen + + * fcntl.cc (_fcntl): Rearrange as wrapper function. Move all + functionality except F_DUPFD to fhandler classes. + * fhandler.cc (fhandler_base::fcntl): New method. + * net.cc (fhandler_socket::fcntl): Ditto. + * fhandler.h (class fhandler_base): Add method prototype for fcntl(). + (class fhandler_socket): Ditto. + Mon Oct 23 12:44:35 2000 Christopher Faylor * sigproc.cc (proc_subproc): Correctly handle flags for WNOHANG case. diff --git a/winsup/cygwin/fcntl.cc b/winsup/cygwin/fcntl.cc index f4d1b44f8..408cbc2cb 100644 --- a/winsup/cygwin/fcntl.cc +++ b/winsup/cygwin/fcntl.cc @@ -22,10 +22,9 @@ extern "C" int _fcntl (int fd, int cmd,...) { + void *arg = NULL; va_list args; - int arg = 0; int res; - SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK, "_fcntl"); if (fdtab.not_open (fd)) { @@ -34,77 +33,17 @@ _fcntl (int fd, int cmd,...) goto done; } - switch (cmd) - { - case F_DUPFD: - va_start (args, cmd); - arg = va_arg (args,int); - va_end (args); - res = dup2 (fd, fdtab.find_unused_handle (arg)); - goto done; - - case F_GETFD: - res = fdtab[fd]->get_close_on_exec () ? FD_CLOEXEC : 0; - goto done; - - case F_SETFD: - va_start (args, cmd); - arg = va_arg (args, int); - va_end (args); - fdtab[fd]->set_close_on_exec (arg); - res = 0; - goto done; - - case F_GETFL: - { - res = fdtab[fd]->get_flags (); - goto done; - } - case F_SETFL: - { - int temp = 0; - - va_start (args, cmd); - arg = va_arg (args, int); - va_end (args); - - if (arg & O_RDONLY) - temp |= GENERIC_READ; - if (arg & O_WRONLY) - temp |= GENERIC_WRITE; - - syscall_printf ("fcntl (%d, F_SETFL, %d)", arg); - - fdtab[fd]->set_access (temp); - fdtab[fd]->set_flags (arg); - - res = 0; - goto done; - } - - case F_GETLK: - case F_SETLK: - case F_SETLKW: - { - struct flock *fl; - va_start (args, cmd); - fl = va_arg (args,struct flock *); - va_end (args); - res = fdtab[fd]->lock (cmd, fl); - goto done; - } - default: - set_errno (EINVAL); - res = -1; - goto done; - } - - set_errno (ENOSYS); - res = -1; - - done: + SetResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK, "_fcntl"); + va_start (args, cmd); + arg = va_arg (args, void *); + if (cmd == F_DUPFD) + res = dup2 (fd, fdtab.find_unused_handle ((int) arg)); + else + res = fdtab[fd]->fcntl(cmd, arg); + va_end (args); ReleaseResourceLock(LOCK_FD_LIST,WRITE_LOCK|READ_LOCK,"_fcntl"); - syscall_printf ("%d = fcntl (%d, %d, %d)", res, fd, cmd, arg); +done: + syscall_printf ("%d = fcntl (%d, %d, %p)", res, fd, cmd, arg); return res; } diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 5d2be0f31..8e6c33161 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -997,6 +997,50 @@ fhandler_base::dup (fhandler_base *child) return 0; } +int fhandler_base::fcntl (int cmd, void *arg) +{ + int res; + + /*int temp = 0;*/ + + switch (cmd) + { + case F_GETFD: + res = get_close_on_exec () ? FD_CLOEXEC : 0; + break; + case F_SETFD: + set_close_on_exec ((int) arg); + res = 0; + break; + case F_GETFL: + res = get_flags (); + break; + case F_SETFL: + /* Only O_APPEND, O_NONBLOCK and O_ASYNC may be set. */ + /* + if (arg & O_RDONLY) + temp |= GENERIC_READ; + if (arg & O_WRONLY) + temp |= GENERIC_WRITE; + syscall_printf ("fcntl (F_SETFL, %d)", (int) arg); + set_access (temp); + */ + set_flags ((int) arg); + res = 0; + break; + case F_GETLK: + case F_SETLK: + case F_SETLKW: + res = lock (cmd, (struct flock *) arg); + break; + default: + set_errno (EINVAL); + res = -1; + break; + } + return res; +} + /* Base terminal handlers. These just return errors. */ int diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 3b984572c..43b33ed14 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -255,6 +255,7 @@ public: virtual int close (); virtual int fstat (struct stat *buf) { return stat_dev (get_device (), get_unit (), get_namehash (), buf); } virtual int ioctl (unsigned int cmd, void *); + virtual int fcntl (int cmd, void *); virtual char const * ttyname () { return get_name(); } virtual int read (void *ptr, size_t len); virtual int write (const void *ptr, size_t len); @@ -327,6 +328,7 @@ public: int write (const void *ptr, size_t len); int read (void *ptr, size_t len); int ioctl (unsigned int cmd, void *); + int fcntl (int cmd, void *); off_t lseek (off_t, int) { return 0; } int close (); void hclose (HANDLE) {close ();} diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index bb33bca57..10153f417 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -1957,7 +1957,7 @@ fhandler_socket::ioctl (unsigned int cmd, void *p) set_async (*(int *) p); break; default: - /* We must cancel WSAAsyncSelect (if any) before settting socket to + /* We must cancel WSAAsyncSelect (if any) before setting socket to * blocking mode */ if (cmd == FIONBIO && *(int *) p == 0) @@ -1979,6 +1979,31 @@ fhandler_socket::ioctl (unsigned int cmd, void *p) return res; } +int +fhandler_socket::fcntl (int cmd, void *arg) +{ + int res = 0; + int request, current; + + switch (cmd) + { + case F_SETFL: + request = ((int) arg & O_NONBLOCK) ? 1 : 0; + current = (get_flags () & O_NONBLOCK) ? 1 : 0; + if (request != current && (res = ioctl (FIONBIO, &request))) + break; + if (request) + set_flags (get_flags () | O_NONBLOCK); + else + set_flags (get_flags () & ~O_NONBLOCK); + break; + default: + res = fhandler_base::fcntl (cmd, arg); + break; + } + return res; +} + extern "C" { /* Initialize WinSock */ LoadDLLinitfunc (wsock32)