summaryrefslogtreecommitdiffstats
path: root/winsup/cygwin
diff options
context:
space:
mode:
Diffstat (limited to 'winsup/cygwin')
-rw-r--r--winsup/cygwin/ChangeLog16
-rw-r--r--winsup/cygwin/dtable.cc7
-rw-r--r--winsup/cygwin/fhandler.h20
-rw-r--r--winsup/cygwin/fhandler_serial.cc2
-rw-r--r--winsup/cygwin/fhandler_socket.cc30
5 files changed, 55 insertions, 20 deletions
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 <corinna@vinschen.de>
+
+ * 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 <corinna@vinschen.de>
* 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))