diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2001-08-14 07:41:45 +0000 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2001-08-14 07:41:45 +0000 |
commit | 6a574f1ad6df42447a242b521c3bdc9e9039910c (patch) | |
tree | ae49f1fb41c40a10c1ab7e97240d0eb3b89fb265 | |
parent | 52c80be81471afa563671b5b78e8de702faa54d6 (diff) | |
download | newlib-6a574f1ad6df42447a242b521c3bdc9e9039910c.zip newlib-6a574f1ad6df42447a242b521c3bdc9e9039910c.tar.gz newlib-6a574f1ad6df42447a242b521c3bdc9e9039910c.tar.bz2 |
* fhandler.cc (fhandler_base::fcntl): Use new O_NONBLOCK_MASK define.
* fhandler.h: Move definitions of O_NOSYMLINK, O_DIROPEN and
OLD_O_NDELAY from winsup.h to here. Add O_NONBLOCK_MASK define.
* fhandler_socket.cc (fhandler_socket::close): Add hack to allow
a graceful shutdown even if shutdown() hasn't been called by the
application. Add debug output.
(fhandler_socket::ioctl): Set fhandler's NONBLOCK flag according
to FIONBIO setting.
(fhandler_socket::fcntl): Use new O_NONBLOCK_MASK define. Actually
set `request' before using it.
* fhandler_tty.cc: Use new O_NONBLOCK_MASK define throughout.
(fhandler_tty_slave::ioctl): Set fhandler's NONBLOCK flag according
to FIONBIO setting.
(fhandler_pty_master::ioctl): Ditto.
* net.cc (wsock_event::prepare): Compare WSACreateEvent return code
with `WSA_INVALID_EVENT' according to MSDN.
* syscalls.cc (_read): Use new O_NONBLOCK_MASK define.
-rw-r--r-- | winsup/cygwin/ChangeLog | 20 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/fhandler.h | 13 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_socket.cc | 25 | ||||
-rw-r--r-- | winsup/cygwin/fhandler_tty.cc | 24 | ||||
-rw-r--r-- | winsup/cygwin/net.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/syscalls.cc | 2 | ||||
-rw-r--r-- | winsup/cygwin/winsup.h | 8 |
8 files changed, 68 insertions, 28 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 599ef44..90b743a 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,23 @@ +Mon Aug 13 22:34:00 2001 Corinna Vinschen <corinna@vinschen.de> + + * fhandler.cc (fhandler_base::fcntl): Use new O_NONBLOCK_MASK define. + * fhandler.h: Move definitions of O_NOSYMLINK, O_DIROPEN and + OLD_O_NDELAY from winsup.h to here. Add O_NONBLOCK_MASK define. + * fhandler_socket.cc (fhandler_socket::close): Add hack to allow + a graceful shutdown even if shutdown() hasn't been called by the + application. Add debug output. + (fhandler_socket::ioctl): Set fhandler's NONBLOCK flag according + to FIONBIO setting. + (fhandler_socket::fcntl): Use new O_NONBLOCK_MASK define. Actually + set `request' before using it. + * fhandler_tty.cc: Use new O_NONBLOCK_MASK define throughout. + (fhandler_tty_slave::ioctl): Set fhandler's NONBLOCK flag according + to FIONBIO setting. + (fhandler_pty_master::ioctl): Ditto. + * net.cc (wsock_event::prepare): Compare WSACreateEvent return code + with `WSA_INVALID_EVENT' according to MSDN. + * syscalls.cc (_read): Use new O_NONBLOCK_MASK define. + Wed Aug 8 15:24:59 2001 Christopher Faylor <cgf@cygnus.com> * include/wchar.h: Define __need_wint_t. diff --git a/winsup/cygwin/fhandler.cc b/winsup/cygwin/fhandler.cc index 98b80b9..c4af734 100644 --- a/winsup/cygwin/fhandler.cc +++ b/winsup/cygwin/fhandler.cc @@ -1094,7 +1094,7 @@ int fhandler_base::fcntl (int cmd, void *arg) * Since O_ASYNC isn't defined in fcntl.h it's currently * ignored as well. */ - const int allowed_flags = O_APPEND | O_NONBLOCK | OLD_O_NDELAY; + const int allowed_flags = O_APPEND | O_NONBLOCK_MASK; int new_flags = (int) arg & allowed_flags; /* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag. Set only the flag that has been passed in. If both are set, just diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 4ff0bb3..a46f7d9 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -118,6 +118,19 @@ enum #define FHSTATOFF 0 +/* fcntl flags used only internaly. */ +#define O_NOSYMLINK 0x080000 +#define O_DIROPEN 0x100000 + +/* newlib used to define O_NDELAY differently from O_NONBLOCK. Now it + properly defines both to be the same. Unfortunately, we have to + behave properly the old version, too, to accomodate older executables. */ +#define OLD_O_NDELAY (CYGWIN_VERSION_CHECK_FOR_OLD_O_NONBLOCK ? 4 : 0) + +/* Care for the old O_NDELAY flag. If one of the flags is set, + both flags are set. */ +#define O_NONBLOCK_MASK (O_NONBLOCK | OLD_O_NDELAY) + extern const char *windows_device_names[]; extern struct __cygwin_perfile *perfile_table; #define __fmode (*(user_data->fmode_ptr)) diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 185843b..7c1be07 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -257,6 +257,15 @@ fhandler_socket::close () int res = 0; sigframe thisframe (mainthread); + /* HACK to allow a graceful shutdown even if shutdown() hasn't been + called by the application. Note that this isn't the ultimate + solution but it helps in many cases. */ + struct linger linger; + linger.l_onoff = 1; + linger.l_linger = 60; /* seconds. 2MSL according to BSD implementation. */ + setsockopt (get_socket (), SOL_SOCKET, SO_LINGER, + (const char *)&linger, sizeof linger); + if (closesocket (get_socket ())) { set_winsock_errno (); @@ -265,6 +274,7 @@ fhandler_socket::close () close_secret_event (); + debug_printf ("%d = fhandler_socket::close()", res); return res; } @@ -395,6 +405,10 @@ fhandler_socket::ioctl (unsigned int cmd, void *p) /* Start AsyncSelect if async socket unblocked */ if (*(int *) p && get_async ()) WSAAsyncSelect (get_socket (), gethwnd (), WM_ASYNCIO, ASYNC_MASK); + + int current = get_flags () & O_NONBLOCK_MASK; + int new_flags = *(int *) p ? (!current ? O_NONBLOCK : current) : 0; + set_flags ((get_flags () & ~O_NONBLOCK_MASK) | new_flags); } break; } @@ -412,20 +426,17 @@ fhandler_socket::fcntl (int cmd, void *arg) { case F_SETFL: { - /* Care for the old O_NDELAY flag. If one of the flags is set, - both flags are set. */ - const int allowed_flags = O_NONBLOCK | OLD_O_NDELAY; - /* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag. Set only the flag that has been passed in. If both are set, just record O_NONBLOCK. */ - int new_flags = (int) arg & allowed_flags; + int new_flags = (int) arg & O_NONBLOCK_MASK; if ((new_flags & OLD_O_NDELAY) && (new_flags & O_NONBLOCK)) new_flags = O_NONBLOCK; - current = get_flags () & allowed_flags; + current = get_flags () & O_NONBLOCK_MASK; + request = new_flags ? 1 : 0; if (!!current != !!new_flags && (res = ioctl (FIONBIO, &request))) break; - set_flags ((get_flags () & ~allowed_flags) | new_flags); + set_flags ((get_flags () & ~O_NONBLOCK_MASK) | new_flags); break; } default: diff --git a/winsup/cygwin/fhandler_tty.cc b/winsup/cygwin/fhandler_tty.cc index 7edc364..942f31d 100644 --- a/winsup/cygwin/fhandler_tty.cc +++ b/winsup/cygwin/fhandler_tty.cc @@ -25,6 +25,8 @@ details. */ #include "pinfo.h" #include "cygheap.h" #include "shared_info.h" +#include "cygwin/version.h" +#include "perprocess.h" /* Tty master stuff */ @@ -295,7 +297,7 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on break; if (hit_eof ()) goto out; - if (n == 0 && (get_flags () & (O_NONBLOCK | O_NDELAY)) != 0) + if (n == 0 && (get_flags () & O_NONBLOCK_MASK) != 0) { set_errno (EAGAIN); rc = -1; @@ -747,7 +749,7 @@ fhandler_tty_slave::read (void *ptr, size_t len) break; } if (get_ttyp ()->ti.c_lflag & ICANON || - get_flags () & (O_NONBLOCK | O_NDELAY)) + get_flags () & O_NONBLOCK_MASK) break; if (totalread >= vmin && (vmin > 0 || totalread > 0)) break; @@ -913,10 +915,11 @@ fhandler_tty_slave::ioctl (unsigned int cmd, void *arg) case TIOCSWINSZ: break; case FIONBIO: - if (* (int *) arg) - set_flags (get_flags () | O_NONBLOCK); - else - set_flags (get_flags () & ~O_NONBLOCK); + { + int current = get_flags () & O_NONBLOCK_MASK; + int new_flags = *(int *) arg ? (!current ? O_NONBLOCK : current) : 0; + set_flags ((get_flags () & ~O_NONBLOCK_MASK) | new_flags); + } goto out; default: set_errno (EINVAL); @@ -1096,10 +1099,11 @@ fhandler_pty_master::ioctl (unsigned int cmd, void *arg) _kill (-get_ttyp ()->getpgid (), SIGWINCH); break; case FIONBIO: - if (* (int *) arg) - set_flags (get_flags () | O_NONBLOCK); - else - set_flags (get_flags () & ~O_NONBLOCK); + { + int current = get_flags () & O_NONBLOCK_MASK; + int new_flags = *(int *) arg ? (!current ? O_NONBLOCK : current) : 0; + set_flags ((get_flags () & ~O_NONBLOCK_MASK) | new_flags); + } break; default: set_errno (EINVAL); diff --git a/winsup/cygwin/net.cc b/winsup/cygwin/net.cc index 4bce7b1..be68f42 100644 --- a/winsup/cygwin/net.cc +++ b/winsup/cygwin/net.cc @@ -70,7 +70,7 @@ wsock_event::prepare () LPWSAOVERLAPPED ret = NULL; SetLastError (0); - if ((event = WSACreateEvent ())) + if ((event = WSACreateEvent ()) != WSA_INVALID_EVENT) { memset (&ovr, 0, sizeof ovr); ovr.hEvent = event; diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index a779c3c..f3fecf1 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -271,7 +271,7 @@ _read (int fd, void *ptr, size_t len) // set_sig_errno (0); fh = cygheap->fdtab[fd]; - DWORD wait = (fh->get_flags () & (O_NONBLOCK | OLD_O_NDELAY)) ? 0 : INFINITE; + DWORD wait = (fh->get_flags () & O_NONBLOCK_MASK) ? 0 : INFINITE; /* Could block, so let user know we at least got here. */ syscall_printf ("read (%d, %p, %d) %sblocking, sigcatchers %d", fd, ptr, len, wait ? "" : "non", sigcatchers); diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h index f43d940..d0b2548 100644 --- a/winsup/cygwin/winsup.h +++ b/winsup/cygwin/winsup.h @@ -244,14 +244,6 @@ extern SYSTEM_INFO system_info; #define STD_WBITS (S_IWUSR) #define STD_XBITS (S_IXUSR | S_IXGRP | S_IXOTH) -#define O_NOSYMLINK 0x080000 -#define O_DIROPEN 0x100000 - -/* newlib used to define O_NDELAY differently from O_NONBLOCK. Now it - properly defines both to be the same. Unfortunately, we have to - behave properly the old version, too, to accomodate older executables. */ -#define OLD_O_NDELAY (CYGWIN_VERSION_CHECK_FOR_OLD_O_NONBLOCK ? 4 : 0) - /* The title on program start. */ extern char *old_title; extern BOOL display_title; |