From: Corinna Vinschen Date: Mon, 18 Aug 2014 11:09:56 +0000 (+0000) Subject: * dtable.cc (dtable::init_std_file_from_handle): Mention that console X-Git-Tag: sid-snapshot-20141001~63 X-Git-Url: https://sourceware.org/git/?a=commitdiff_plain;h=1091d4404ed9f4b20a0f45be20a9f8187d5db335;p=newlib-cygwin.git * dtable.cc (dtable::init_std_file_from_handle): Mention that console handles are kernel objects since Windows 8. * fhandler.h (enum conn_state): Add "listener" state. (class fhandler_socket): Drop listener status flag. (fhandler_socket::lseek): Return -1 and errno ESPIPE. (fhandler_serial::lseek): Ditto. * fhandler_socket.cc (fhandler_socket::listen): Set connect_state to listener. Add comment. (fhandler_socket::accept4): Explicitely check if the socket is listening and fail with EINVAL, if not. Explain why we have to do that. (fhandler_socket::recv_internal): Explicitely check if the socket is connected if it's a stream socket. Explain why we have to do that. (fhandler_socket::getpeereid): Drop now redundant test. --- diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index d6a9e10d8..6c52cf781 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,19 @@ +2014-08-18 Corinna Vinschen + + * dtable.cc (dtable::init_std_file_from_handle): Mention that console + handles are kernel objects since Windows 8. + * fhandler.h (enum conn_state): Add "listener" state. + (class fhandler_socket): Drop listener status flag. + (fhandler_socket::lseek): Return -1 and errno ESPIPE. + (fhandler_serial::lseek): Ditto. + * fhandler_socket.cc (fhandler_socket::listen): Set connect_state to + listener. Add comment. + (fhandler_socket::accept4): Explicitely check if the socket is listening + and fail with EINVAL, if not. Explain why we have to do that. + (fhandler_socket::recv_internal): Explicitely check if the socket is + connected if it's a stream socket. Explain why we have to do that. + (fhandler_socket::getpeereid): Drop now redundant test. + 2014-08-15 Corinna Vinschen * winsup.h (_GNU_SOURCE): Define. Explain why. diff --git a/winsup/cygwin/dtable.cc b/winsup/cygwin/dtable.cc index 0dc548c3d..17ed51f9a 100644 --- a/winsup/cygwin/dtable.cc +++ b/winsup/cygwin/dtable.cc @@ -371,9 +371,10 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle) FILE_ACCESS_INFORMATION fai; int openflags = O_BINARY; - /* Console windows are not kernel objects, so the access mask returned - by NtQueryInformationFile is meaningless. CMD always hands down - stdin handles as R/O handles, but our tty slave sides are R/W. */ + /* Console windows are no kernel objects up to Windows 7/2008R2, so the + access mask returned by NtQueryInformationFile is meaningless. CMD + always hands down stdin handles as R/O handles, but our tty slave + sides are R/W. */ if (fh->is_tty ()) { openflags |= O_RDWR; diff --git a/winsup/cygwin/fhandler.h b/winsup/cygwin/fhandler.h index 19f629124..8561f0cf2 100644 --- a/winsup/cygwin/fhandler.h +++ b/winsup/cygwin/fhandler.h @@ -77,7 +77,8 @@ enum conn_state unconnected = 0, connect_pending = 1, connected = 2, - connect_failed = 3 + listener = 3, + connect_failed = 4 }; enum line_edit_status @@ -528,12 +529,11 @@ class fhandler_socket: public fhandler_base unsigned saw_shutdown_read : 1; /* Socket saw a SHUT_RD */ unsigned saw_shutdown_write : 1; /* Socket saw a SHUT_WR */ unsigned saw_reuseaddr : 1; /* Socket saw SO_REUSEADDR call */ - unsigned listener : 1; /* listen called */ unsigned connect_state : 2; public: status_flags () : async_io (0), saw_shutdown_read (0), saw_shutdown_write (0), - listener (0), connect_state (unconnected) + connect_state (unconnected) {} } status; @@ -554,7 +554,6 @@ class fhandler_socket: public fhandler_base IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_read) IMPLEMENT_STATUS_FLAG (bool, saw_shutdown_write) IMPLEMENT_STATUS_FLAG (bool, saw_reuseaddr) - IMPLEMENT_STATUS_FLAG (bool, listener) IMPLEMENT_STATUS_FLAG (conn_state, connect_state) int bind (const struct sockaddr *name, int namelen); @@ -582,7 +581,11 @@ class fhandler_socket: public fhandler_base int ioctl (unsigned int cmd, void *); int fcntl (int cmd, intptr_t); - off_t lseek (off_t, int) { return 0; } + off_t lseek (off_t, int) + { + set_errno (ESPIPE); + return -1; + } int shutdown (int how); int close (); void hclose (HANDLE) {close ();} @@ -1135,9 +1138,12 @@ class fhandler_serial: public fhandler_base int switch_modem_lines (int set, int clr); int tcsetattr (int a, const struct termios *t); int tcgetattr (struct termios *t); - off_t lseek (off_t, int) { return 0; } + off_t lseek (off_t, int) + { + set_errno (ESPIPE); + return -1; + } int tcflush (int); - bool is_tty () const { return true; } void fixup_after_fork (HANDLE parent); void fixup_after_exec (); diff --git a/winsup/cygwin/fhandler_serial.cc b/winsup/cygwin/fhandler_serial.cc index b6641e5e4..4e5d488b4 100644 --- a/winsup/cygwin/fhandler_serial.cc +++ b/winsup/cygwin/fhandler_serial.cc @@ -53,7 +53,7 @@ fhandler_serial::raw_read (void *ptr, size_t& ulen) ulen, vmin_, vtime_, io_status.hEvent); if (!overlapped_armed) { - SetCommMask (get_handle (), EV_RXCHAR); + SetCommMask (get_handle (), EV_RXCHAR| EV_ERR | EV_BREAK | EV_CTS | EV_DSR | EV_RING | EV_RLSD | EV_RXFLAG); ResetEvent (io_status.hEvent); } diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc index 793578f39..779508b8c 100644 --- a/winsup/cygwin/fhandler_socket.cc +++ b/winsup/cygwin/fhandler_socket.cc @@ -1180,8 +1180,7 @@ fhandler_socket::listen (int backlog) { if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM) af_local_set_cred (); - connect_state (connected); - listener (true); + connect_state (listener); /* gets set to connected on accepted socket. */ } else set_winsock_errno (); @@ -1195,7 +1194,17 @@ fhandler_socket::accept4 (struct sockaddr *peer, int *len, int flags) struct sockaddr_storage lpeer; int llen = sizeof (struct sockaddr_storage); - int res = 0; + int res = (int) INVALID_SOCKET; + + /* Windows event handling does not check for the validity of the desired + flags so we have to do it here. */ + if (connect_state () != listener) + { + WSASetLastError (WSAEINVAL); + set_winsock_errno (); + goto out; + } + while (!(res = wait_for_events (FD_ACCEPT | FD_CLOSE, 0)) && (res = ::accept (get_socket (), (struct sockaddr *) &lpeer, &llen)) == SOCKET_ERROR @@ -1392,6 +1401,15 @@ fhandler_socket::recv_internal (LPWSAMSG wsamsg, bool use_recvmsg) static NO_COPY LPFN_WSARECVMSG WSARecvMsg; int orig_namelen = wsamsg->namelen; + /* Windows event handling does not check for the validity of the desired + flags so we have to do it here. */ + if (get_socket_type () == SOCK_STREAM && connect_state () != connected) + { + WSASetLastError (WSAENOTCONN); + set_winsock_errno (); + return SOCKET_ERROR; + } + DWORD wait_flags = wsamsg->dwFlags; bool waitall = !!(wait_flags & MSG_WAITALL); wsamsg->dwFlags &= (MSG_OOB | MSG_PEEK | MSG_DONTROUTE); @@ -2264,12 +2282,6 @@ fhandler_socket::getpeereid (pid_t *pid, uid_t *euid, gid_t *egid) set_errno (ENOTCONN); return -1; } - if (sec_peer_pid == (pid_t) 0) - { - set_errno (ENOTCONN); /* Usually when calling getpeereid on - accepting (instead of accepted) socket. */ - return -1; - } myfault efault; if (efault.faulted (EFAULT))