* 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.
This commit is contained in:
Corinna Vinschen 2001-08-14 07:41:45 +00:00
parent 52c80be814
commit 6a574f1ad6
8 changed files with 68 additions and 28 deletions

View File

@ -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> Wed Aug 8 15:24:59 2001 Christopher Faylor <cgf@cygnus.com>
* include/wchar.h: Define __need_wint_t. * include/wchar.h: Define __need_wint_t.

View File

@ -1094,7 +1094,7 @@ int fhandler_base::fcntl (int cmd, void *arg)
* Since O_ASYNC isn't defined in fcntl.h it's currently * Since O_ASYNC isn't defined in fcntl.h it's currently
* ignored as well. * 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; int new_flags = (int) arg & allowed_flags;
/* Carefully test for the O_NONBLOCK or deprecated OLD_O_NDELAY flag. /* 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 Set only the flag that has been passed in. If both are set, just

View File

@ -118,6 +118,19 @@ enum
#define FHSTATOFF 0 #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 const char *windows_device_names[];
extern struct __cygwin_perfile *perfile_table; extern struct __cygwin_perfile *perfile_table;
#define __fmode (*(user_data->fmode_ptr)) #define __fmode (*(user_data->fmode_ptr))

View File

@ -257,6 +257,15 @@ fhandler_socket::close ()
int res = 0; int res = 0;
sigframe thisframe (mainthread); 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 ())) if (closesocket (get_socket ()))
{ {
set_winsock_errno (); set_winsock_errno ();
@ -265,6 +274,7 @@ fhandler_socket::close ()
close_secret_event (); close_secret_event ();
debug_printf ("%d = fhandler_socket::close()", res);
return res; return res;
} }
@ -395,6 +405,10 @@ fhandler_socket::ioctl (unsigned int cmd, void *p)
/* Start AsyncSelect if async socket unblocked */ /* Start AsyncSelect if async socket unblocked */
if (*(int *) p && get_async ()) if (*(int *) p && get_async ())
WSAAsyncSelect (get_socket (), gethwnd (), WM_ASYNCIO, ASYNC_MASK); 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; break;
} }
@ -412,20 +426,17 @@ fhandler_socket::fcntl (int cmd, void *arg)
{ {
case F_SETFL: 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. /* 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 Set only the flag that has been passed in. If both are set, just
record O_NONBLOCK. */ 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)) if ((new_flags & OLD_O_NDELAY) && (new_flags & O_NONBLOCK))
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))) if (!!current != !!new_flags && (res = ioctl (FIONBIO, &request)))
break; break;
set_flags ((get_flags () & ~allowed_flags) | new_flags); set_flags ((get_flags () & ~O_NONBLOCK_MASK) | new_flags);
break; break;
} }
default: default:

View File

@ -25,6 +25,8 @@ details. */
#include "pinfo.h" #include "pinfo.h"
#include "cygheap.h" #include "cygheap.h"
#include "shared_info.h" #include "shared_info.h"
#include "cygwin/version.h"
#include "perprocess.h"
/* Tty master stuff */ /* Tty master stuff */
@ -295,7 +297,7 @@ fhandler_pty_master::process_slave_output (char *buf, size_t len, int pktmode_on
break; break;
if (hit_eof ()) if (hit_eof ())
goto out; goto out;
if (n == 0 && (get_flags () & (O_NONBLOCK | O_NDELAY)) != 0) if (n == 0 && (get_flags () & O_NONBLOCK_MASK) != 0)
{ {
set_errno (EAGAIN); set_errno (EAGAIN);
rc = -1; rc = -1;
@ -747,7 +749,7 @@ fhandler_tty_slave::read (void *ptr, size_t len)
break; break;
} }
if (get_ttyp ()->ti.c_lflag & ICANON || if (get_ttyp ()->ti.c_lflag & ICANON ||
get_flags () & (O_NONBLOCK | O_NDELAY)) get_flags () & O_NONBLOCK_MASK)
break; break;
if (totalread >= vmin && (vmin > 0 || totalread > 0)) if (totalread >= vmin && (vmin > 0 || totalread > 0))
break; break;
@ -913,10 +915,11 @@ fhandler_tty_slave::ioctl (unsigned int cmd, void *arg)
case TIOCSWINSZ: case TIOCSWINSZ:
break; break;
case FIONBIO: case FIONBIO:
if (* (int *) arg) {
set_flags (get_flags () | O_NONBLOCK); int current = get_flags () & O_NONBLOCK_MASK;
else int new_flags = *(int *) arg ? (!current ? O_NONBLOCK : current) : 0;
set_flags (get_flags () & ~O_NONBLOCK); set_flags ((get_flags () & ~O_NONBLOCK_MASK) | new_flags);
}
goto out; goto out;
default: default:
set_errno (EINVAL); set_errno (EINVAL);
@ -1096,10 +1099,11 @@ fhandler_pty_master::ioctl (unsigned int cmd, void *arg)
_kill (-get_ttyp ()->getpgid (), SIGWINCH); _kill (-get_ttyp ()->getpgid (), SIGWINCH);
break; break;
case FIONBIO: case FIONBIO:
if (* (int *) arg) {
set_flags (get_flags () | O_NONBLOCK); int current = get_flags () & O_NONBLOCK_MASK;
else int new_flags = *(int *) arg ? (!current ? O_NONBLOCK : current) : 0;
set_flags (get_flags () & ~O_NONBLOCK); set_flags ((get_flags () & ~O_NONBLOCK_MASK) | new_flags);
}
break; break;
default: default:
set_errno (EINVAL); set_errno (EINVAL);

View File

@ -70,7 +70,7 @@ wsock_event::prepare ()
LPWSAOVERLAPPED ret = NULL; LPWSAOVERLAPPED ret = NULL;
SetLastError (0); SetLastError (0);
if ((event = WSACreateEvent ())) if ((event = WSACreateEvent ()) != WSA_INVALID_EVENT)
{ {
memset (&ovr, 0, sizeof ovr); memset (&ovr, 0, sizeof ovr);
ovr.hEvent = event; ovr.hEvent = event;

View File

@ -271,7 +271,7 @@ _read (int fd, void *ptr, size_t len)
// set_sig_errno (0); // set_sig_errno (0);
fh = cygheap->fdtab[fd]; 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. */ /* 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); syscall_printf ("read (%d, %p, %d) %sblocking, sigcatchers %d", fd, ptr, len, wait ? "" : "non", sigcatchers);

View File

@ -244,14 +244,6 @@ extern SYSTEM_INFO system_info;
#define STD_WBITS (S_IWUSR) #define STD_WBITS (S_IWUSR)
#define STD_XBITS (S_IXUSR | S_IXGRP | S_IXOTH) #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. */ /* The title on program start. */
extern char *old_title; extern char *old_title;
extern BOOL display_title; extern BOOL display_title;