* fhandler.h (class cygthread): Forward declare.
(fhandler_socket::sec_pipe): Remove. (fhandler_socket::eid_pipe_name): Remove. (fhandler_socket::eid_setblocking): New private method. (fhandler_socket::eid_unsetblocking): Ditto (fhandler_socket::eid_recv): Ditto (fhandler_socket::eid_send): Ditto (fhandler_socket::eid_accept): Ditto (fhandler_socket::eid_connect): New public method. * fhandler_socket.cc (ASYNC_MASK): Move to beginning of file. (fhandler_socket::eid_pipe_name): Remove. (fhandler_socket::set_socketpair_eids): Move down to fhandler_socket methods. (fhandler_socket::fhandler_socket): Drop initializing sec_pipe. (fhandler_socket::~fhandler_socket): Drop closing sec_pipe. (fhandler_socket::eid_setblocking): New method. (fhandler_socket::eid_unsetblocking): New method. (fhandler_socket::eid_recv): New method. (fhandler_socket::eid_send): New method. (fhandler_socket::eid_connect): New method. (fhandler_socket::eid_accept): New method. (fhandler_socket::dup): Drop sec_pipe handling. (fhandler_socket::connect): Fix WinSock error handling. Prepare eid credential transaction. Call eid_connect on successful connect. (fhandler_socket::listen): Drop creating sec_pipe. (fhandler_socket::accept): Slightly simplify code. Call eid_accept on accepted socket. (fhandler_socket::getpeereid): Reshuffle code for readability. Fix test for invalid pid. * select.cc (set_bits): Call eid_connect on successfully connected socket.
This commit is contained in:
parent
b5e27d4009
commit
ef82f76c30
|
@ -1,3 +1,37 @@
|
|||
2005-03-21 Corinna Vinschen <corinna@vinschen.de>
|
||||
|
||||
* fhandler.h (class cygthread): Forward declare.
|
||||
(fhandler_socket::sec_pipe): Remove.
|
||||
(fhandler_socket::eid_pipe_name): Remove.
|
||||
(fhandler_socket::eid_setblocking): New private method.
|
||||
(fhandler_socket::eid_unsetblocking): Ditto
|
||||
(fhandler_socket::eid_recv): Ditto
|
||||
(fhandler_socket::eid_send): Ditto
|
||||
(fhandler_socket::eid_accept): Ditto
|
||||
(fhandler_socket::eid_connect): New public method.
|
||||
* fhandler_socket.cc (ASYNC_MASK): Move to beginning of file.
|
||||
(fhandler_socket::eid_pipe_name): Remove.
|
||||
(fhandler_socket::set_socketpair_eids): Move down to fhandler_socket
|
||||
methods.
|
||||
(fhandler_socket::fhandler_socket): Drop initializing sec_pipe.
|
||||
(fhandler_socket::~fhandler_socket): Drop closing sec_pipe.
|
||||
(fhandler_socket::eid_setblocking): New method.
|
||||
(fhandler_socket::eid_unsetblocking): New method.
|
||||
(fhandler_socket::eid_recv): New method.
|
||||
(fhandler_socket::eid_send): New method.
|
||||
(fhandler_socket::eid_connect): New method.
|
||||
(fhandler_socket::eid_accept): New method.
|
||||
(fhandler_socket::dup): Drop sec_pipe handling.
|
||||
(fhandler_socket::connect): Fix WinSock error handling. Prepare
|
||||
eid credential transaction. Call eid_connect on successful connect.
|
||||
(fhandler_socket::listen): Drop creating sec_pipe.
|
||||
(fhandler_socket::accept): Slightly simplify code. Call eid_accept
|
||||
on accepted socket.
|
||||
(fhandler_socket::getpeereid): Reshuffle code for readability. Fix
|
||||
test for invalid pid.
|
||||
* select.cc (set_bits): Call eid_connect on successfully connected
|
||||
socket.
|
||||
|
||||
2005-03-19 Christopher Faylor <cgf@timesys.com>
|
||||
|
||||
* child_info.h (fork_info): Use different method to alias variable.
|
||||
|
|
|
@ -37,6 +37,7 @@ typedef struct __DIR DIR;
|
|||
struct dirent;
|
||||
struct iovec;
|
||||
struct __acl32;
|
||||
class cygthread;
|
||||
|
||||
enum dirent_states
|
||||
{
|
||||
|
@ -365,15 +366,19 @@ class fhandler_socket: public fhandler_base
|
|||
int connect_secret [4];
|
||||
HANDLE secret_event;
|
||||
|
||||
HANDLE sec_pipe;
|
||||
pid_t sec_pid;
|
||||
__uid32_t sec_uid;
|
||||
__gid32_t sec_gid;
|
||||
pid_t sec_peer_pid;
|
||||
__uid32_t sec_peer_uid;
|
||||
__gid32_t sec_peer_gid;
|
||||
char *eid_pipe_name (char *buf);
|
||||
void eid_setblocking (bool &, bool &);
|
||||
void eid_unsetblocking (bool, bool);
|
||||
bool eid_recv (void);
|
||||
bool eid_send (void);
|
||||
void eid_accept (void);
|
||||
public:
|
||||
void eid_connect (void);
|
||||
void set_socketpair_eids (void);
|
||||
|
||||
private:
|
||||
|
|
|
@ -36,6 +36,8 @@
|
|||
#include <unistd.h>
|
||||
#include <sys/acl.h>
|
||||
|
||||
#define ASYNC_MASK (FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT)
|
||||
|
||||
extern bool fdsock (cygheap_fdmanip& fd, const device *, SOCKET soc);
|
||||
extern "C" {
|
||||
int sscanf (const char *, const char *, ...);
|
||||
|
@ -53,22 +55,6 @@ secret_event_name (char *buf, short port, int *secret_ptr)
|
|||
secret_ptr [2], secret_ptr [3]);
|
||||
}
|
||||
|
||||
char *
|
||||
fhandler_socket::eid_pipe_name (char *buf)
|
||||
{
|
||||
__small_sprintf (buf, "\\\\.\\pipe\\cygwin-unix-%s", get_sun_path ());
|
||||
debug_printf ("%s", buf);
|
||||
return buf;
|
||||
}
|
||||
|
||||
void
|
||||
fhandler_socket::set_socketpair_eids (void)
|
||||
{
|
||||
sec_pid = sec_peer_pid = getpid ();
|
||||
sec_uid = sec_peer_uid = geteuid32 ();
|
||||
sec_gid = sec_peer_gid = getegid32 ();
|
||||
}
|
||||
|
||||
/* cygwin internal: map sockaddr into internet domain address */
|
||||
static int
|
||||
get_inet_addr (const struct sockaddr *in, int inlen,
|
||||
|
@ -140,7 +126,6 @@ get_inet_addr (const struct sockaddr *in, int inlen,
|
|||
|
||||
fhandler_socket::fhandler_socket () :
|
||||
fhandler_base (),
|
||||
sec_pipe (INVALID_HANDLE_VALUE),
|
||||
sun_path (NULL),
|
||||
status ()
|
||||
{
|
||||
|
@ -163,12 +148,119 @@ fhandler_socket::~fhandler_socket ()
|
|||
cfree (prot_info_ptr);
|
||||
if (sun_path)
|
||||
cfree (sun_path);
|
||||
/* Close eid credentials pipe handle. */
|
||||
if (sec_pipe != INVALID_HANDLE_VALUE)
|
||||
CloseHandle (sec_pipe);
|
||||
}
|
||||
|
||||
char *fhandler_socket::get_proc_fd_name (char *buf)
|
||||
void
|
||||
fhandler_socket::set_socketpair_eids (void)
|
||||
{
|
||||
sec_pid = sec_peer_pid = getpid ();
|
||||
sec_uid = sec_peer_uid = geteuid32 ();
|
||||
sec_gid = sec_peer_gid = getegid32 ();
|
||||
}
|
||||
|
||||
void
|
||||
fhandler_socket::eid_setblocking (bool &async, bool &nonblocking)
|
||||
{
|
||||
async = async_io ();
|
||||
nonblocking = is_nonblocking ();
|
||||
if (async || nonblocking)
|
||||
WSAAsyncSelect (get_socket (), winmsg, 0, 0);
|
||||
unsigned long p = 0;
|
||||
ioctlsocket (get_socket (), FIONBIO, &p);
|
||||
set_nonblocking (false);
|
||||
async_io (false);
|
||||
}
|
||||
|
||||
void
|
||||
fhandler_socket::eid_unsetblocking (bool async, bool nonblocking)
|
||||
{
|
||||
if (nonblocking)
|
||||
{
|
||||
unsigned long p = 1;
|
||||
ioctlsocket (get_socket (), FIONBIO, &p);
|
||||
set_nonblocking (true);
|
||||
}
|
||||
if (async)
|
||||
{
|
||||
WSAAsyncSelect (get_socket (), winmsg, WM_ASYNCIO, ASYNC_MASK);
|
||||
async_io (true);
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
fhandler_socket::eid_recv (void)
|
||||
{
|
||||
struct ucred out = { (pid_t) 0, (__uid32_t) -1, (__gid32_t) -1 };
|
||||
int rest = sizeof out;
|
||||
char *ptr = (char *) &out;
|
||||
while (rest > 0)
|
||||
{
|
||||
int ret = recvfrom (ptr, rest, 0, NULL, NULL);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
rest -= ret;
|
||||
ptr += ret;
|
||||
}
|
||||
if (rest == 0)
|
||||
{
|
||||
debug_printf ("Received eid credentials: pid: %d, uid: %d, gid: %d",
|
||||
out.pid, out.uid, out.gid);
|
||||
sec_peer_pid = out.pid;
|
||||
sec_peer_uid = out.uid;
|
||||
sec_peer_gid = out.gid;
|
||||
}
|
||||
else
|
||||
debug_printf ("Receiving eid credentials failed");
|
||||
return rest == 0;
|
||||
}
|
||||
|
||||
bool
|
||||
fhandler_socket::eid_send (void)
|
||||
{
|
||||
struct ucred in = { sec_pid, sec_uid, sec_gid };
|
||||
int rest = sizeof in;
|
||||
char *ptr = (char *) ∈
|
||||
while (rest > 0)
|
||||
{
|
||||
int ret = sendto (ptr, rest, 0, NULL, 0);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
rest -= ret;
|
||||
ptr += ret;
|
||||
}
|
||||
if (rest == 0)
|
||||
debug_printf ("Sending eid credentials succeeded");
|
||||
else
|
||||
debug_printf ("Sending eid credentials failed");
|
||||
return rest == 0;
|
||||
}
|
||||
|
||||
void
|
||||
fhandler_socket::eid_connect (void)
|
||||
{
|
||||
/* This test allows to keep select.cc clean from boring implementation
|
||||
details. */
|
||||
if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
|
||||
return;
|
||||
debug_printf ("eid_connect called");
|
||||
bool orig_async_io, orig_is_nonblocking;
|
||||
eid_setblocking (orig_async_io, orig_is_nonblocking);
|
||||
eid_send () && eid_recv ();
|
||||
eid_unsetblocking (orig_async_io, orig_is_nonblocking);
|
||||
}
|
||||
|
||||
void
|
||||
fhandler_socket::eid_accept (void)
|
||||
{
|
||||
debug_printf ("eid_accept called");
|
||||
bool orig_async_io, orig_is_nonblocking;
|
||||
eid_setblocking (orig_async_io, orig_is_nonblocking);
|
||||
eid_recv () && eid_send ();
|
||||
eid_unsetblocking (orig_async_io, orig_is_nonblocking);
|
||||
}
|
||||
|
||||
char *
|
||||
fhandler_socket::get_proc_fd_name (char *buf)
|
||||
{
|
||||
__small_sprintf (buf, "socket:[%d]", get_socket ());
|
||||
return buf;
|
||||
|
@ -370,18 +462,6 @@ fhandler_socket::dup (fhandler_base *child)
|
|||
fhs->sec_peer_pid = sec_peer_pid;
|
||||
fhs->sec_peer_uid = sec_peer_uid;
|
||||
fhs->sec_peer_gid = sec_peer_gid;
|
||||
if (sec_pipe != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
if (!DuplicateHandle (hMainProc, sec_pipe, hMainProc, &nh, 0,
|
||||
TRUE, DUPLICATE_SAME_ACCESS))
|
||||
{
|
||||
system_printf ("!DuplicateHandle(%x) failed, %E", sec_pipe);
|
||||
__seterrno ();
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
fhs->sec_pipe = nh;
|
||||
}
|
||||
}
|
||||
}
|
||||
fhs->connect_state (connect_state ());
|
||||
|
@ -420,8 +500,6 @@ fhandler_socket::dup (fhandler_base *child)
|
|||
{
|
||||
system_printf ("!DuplicateHandle(%x) failed, %E", get_io_handle ());
|
||||
__seterrno ();
|
||||
if (fhs->sec_pipe != INVALID_HANDLE_VALUE)
|
||||
CloseHandle (fhs->sec_pipe);
|
||||
return -1;
|
||||
}
|
||||
VerifyHandle (nh);
|
||||
|
@ -622,18 +700,18 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
|
|||
|
||||
if (res)
|
||||
{
|
||||
err = WSAGetLastError ();
|
||||
/* Special handling for connect to return the correct error code
|
||||
when called on a non-blocking socket. */
|
||||
if (is_nonblocking () || connect_state () == connect_pending)
|
||||
{
|
||||
err = WSAGetLastError ();
|
||||
if (err == WSAEWOULDBLOCK || err == WSAEALREADY)
|
||||
in_progress = true;
|
||||
|
||||
if (err == WSAEWOULDBLOCK)
|
||||
WSASetLastError (WSAEINPROGRESS);
|
||||
WSASetLastError (err = WSAEINPROGRESS);
|
||||
else if (err == WSAEINVAL)
|
||||
WSASetLastError (WSAEISCONN);
|
||||
WSASetLastError (err = WSAEISCONN);
|
||||
}
|
||||
set_winsock_errno ();
|
||||
}
|
||||
|
@ -671,38 +749,23 @@ fhandler_socket::connect (const struct sockaddr *name, int namelen)
|
|||
res = -1;
|
||||
}
|
||||
|
||||
if (!res || in_progress)
|
||||
/* Prepare eid credential transaction. */
|
||||
sec_pid = getpid ();
|
||||
sec_uid = geteuid32 ();
|
||||
sec_gid = getegid32 ();
|
||||
sec_peer_pid = (pid_t) 0;
|
||||
sec_peer_uid = (__uid32_t) -1;
|
||||
sec_peer_gid = (__gid32_t) -1;
|
||||
|
||||
if (!res)
|
||||
{
|
||||
/* eid credential transaction. */
|
||||
if (wincap.has_named_pipes ())
|
||||
{
|
||||
struct ucred in = { getpid (), geteuid32 (), getegid32 () };
|
||||
struct ucred out = { (pid_t) 0, (__uid32_t) -1, (__gid32_t) -1 };
|
||||
DWORD bytes = 0;
|
||||
debug_printf ("Calling CallNamedPipe");
|
||||
if (CallNamedPipe(eid_pipe_name ((char *) alloca (CYG_MAX_PATH + 1)),
|
||||
&in, sizeof in, &out, sizeof out, &bytes, 1000))
|
||||
{
|
||||
debug_printf ("Received eid credentials: pid: %d, uid: %d"
|
||||
", gid: %d", out.pid, out.uid, out.gid);
|
||||
sec_peer_pid = out.pid;
|
||||
sec_peer_uid = out.uid;
|
||||
sec_peer_gid = out.gid;
|
||||
}
|
||||
else
|
||||
debug_printf ("Receiving eid credentials failed: %E");
|
||||
}
|
||||
else /* 9x */
|
||||
{
|
||||
/* Incorrect but wrong pid at least doesn't break getpeereid. */
|
||||
sec_peer_pid = getpid ();
|
||||
sec_peer_uid = geteuid32 ();
|
||||
sec_peer_gid = getegid32 ();
|
||||
}
|
||||
/* eid credential transaction. If connect is in progress,
|
||||
we're deferring the eid transaction to the successful select,
|
||||
see select.cc, function set_bits(). */
|
||||
eid_connect ();
|
||||
}
|
||||
}
|
||||
|
||||
err = WSAGetLastError ();
|
||||
if (err == WSAEINPROGRESS || err == WSAEALREADY)
|
||||
connect_state (connect_pending);
|
||||
else
|
||||
|
@ -728,16 +791,6 @@ fhandler_socket::listen (int backlog)
|
|||
sec_peer_pid = (pid_t) 0;
|
||||
sec_peer_uid = (__uid32_t) -1;
|
||||
sec_peer_gid = (__gid32_t) -1;
|
||||
/* A listening socket can call listen again, but that shouldn't
|
||||
result in trying to create another pipe. */
|
||||
if (wincap.has_named_pipes () && sec_pipe == INVALID_HANDLE_VALUE)
|
||||
sec_pipe =
|
||||
CreateNamedPipe (eid_pipe_name ((char *) alloca (CYG_MAX_PATH + 1)),
|
||||
PIPE_ACCESS_DUPLEX,
|
||||
PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE,
|
||||
PIPE_UNLIMITED_INSTANCES, sizeof (struct ucred),
|
||||
sizeof (struct ucred), 1000, &sec_all);
|
||||
debug_printf ("sec_pipe: %x", sec_pipe);
|
||||
}
|
||||
connect_state (connected);
|
||||
}
|
||||
|
@ -749,8 +802,6 @@ fhandler_socket::accept (struct sockaddr *peer, int *len)
|
|||
{
|
||||
int res = -1;
|
||||
bool secret_check_failed = false;
|
||||
struct ucred in = { sec_pid, sec_uid, sec_gid };
|
||||
struct ucred out = { (pid_t) 0, (__uid32_t) -1, (__gid32_t) -1 };
|
||||
|
||||
/* Allows NULL peer and len parameters. */
|
||||
struct sockaddr_in peer_dummy;
|
||||
|
@ -794,34 +845,6 @@ fhandler_socket::accept (struct sockaddr *peer, int *len)
|
|||
set_errno (ECONNABORTED);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* eid credential transaction. */
|
||||
if (wincap.has_named_pipes ())
|
||||
{
|
||||
DWORD bytes = 0;
|
||||
debug_printf ("Calling ConnectNamedPipe");
|
||||
bool ret = ConnectNamedPipe (sec_pipe, NULL);
|
||||
if (ret || GetLastError () == ERROR_PIPE_CONNECTED)
|
||||
{
|
||||
if (!ReadFile (sec_pipe, &out, sizeof out, &bytes, NULL))
|
||||
debug_printf ("Receiving eid credentials failed: %E");
|
||||
else
|
||||
debug_printf ("Received eid credentials: pid: %d, uid: %d"
|
||||
", gid: %d", out.pid, out.uid, out.gid);
|
||||
if (!WriteFile (sec_pipe, &in, sizeof in, &bytes, NULL))
|
||||
debug_printf ("Sending eid credentials failed: %E");
|
||||
DisconnectNamedPipe (sec_pipe);
|
||||
}
|
||||
else
|
||||
debug_printf ("Connecting the eid credential pipe failed: %E");
|
||||
}
|
||||
else /* 9x */
|
||||
{
|
||||
/* Incorrect but wrong pid at least doesn't break getpeereid. */
|
||||
out.pid = sec_pid;
|
||||
out.uid = sec_uid;
|
||||
out.gid = sec_gid;
|
||||
}
|
||||
}
|
||||
|
||||
if ((SOCKET) res == INVALID_SOCKET)
|
||||
|
@ -831,19 +854,29 @@ fhandler_socket::accept (struct sockaddr *peer, int *len)
|
|||
cygheap_fdnew res_fd;
|
||||
if (res_fd >= 0 && fdsock (res_fd, &dev (), res))
|
||||
{
|
||||
((fhandler_socket *) res_fd)->set_addr_family (get_addr_family ());
|
||||
((fhandler_socket *) res_fd)->set_socket_type (get_socket_type ());
|
||||
fhandler_socket *sock = (fhandler_socket *) res_fd;
|
||||
sock->set_addr_family (get_addr_family ());
|
||||
sock->set_socket_type (get_socket_type ());
|
||||
sock->async_io (async_io ());
|
||||
sock->set_nonblocking (is_nonblocking ());
|
||||
if (get_addr_family () == AF_LOCAL)
|
||||
{
|
||||
((fhandler_socket *) res_fd)->set_sun_path (get_sun_path ());
|
||||
sock->set_sun_path (get_sun_path ());
|
||||
if (get_socket_type () == SOCK_STREAM)
|
||||
{
|
||||
((fhandler_socket *) res_fd)->sec_peer_pid = out.pid;
|
||||
((fhandler_socket *) res_fd)->sec_peer_uid = out.uid;
|
||||
((fhandler_socket *) res_fd)->sec_peer_gid = out.gid;
|
||||
}
|
||||
{
|
||||
/* Don't forget to copy credentials from accepting
|
||||
socket to accepted socket and start transaction
|
||||
on accepted socket! */
|
||||
sock->sec_pid = sec_pid;
|
||||
sock->sec_uid = sec_uid;
|
||||
sock->sec_gid = sec_gid;
|
||||
sock->sec_peer_pid = sec_peer_pid;
|
||||
sock->sec_peer_uid = sec_peer_uid;
|
||||
sock->sec_peer_gid = sec_peer_gid;
|
||||
sock->eid_accept ();
|
||||
}
|
||||
}
|
||||
((fhandler_socket *) res_fd)->connect_state (connected);
|
||||
sock->connect_state (connected);
|
||||
res = res_fd;
|
||||
}
|
||||
else
|
||||
|
@ -1475,8 +1508,6 @@ fhandler_socket::close ()
|
|||
return res;
|
||||
}
|
||||
|
||||
#define ASYNC_MASK (FD_READ|FD_WRITE|FD_OOB|FD_ACCEPT|FD_CONNECT)
|
||||
|
||||
int
|
||||
fhandler_socket::ioctl (unsigned int cmd, void *p)
|
||||
{
|
||||
|
@ -1673,21 +1704,28 @@ fhandler_socket::set_sun_path (const char *path)
|
|||
int
|
||||
fhandler_socket::getpeereid (pid_t *pid, __uid32_t *euid, __gid32_t *egid)
|
||||
{
|
||||
if (get_addr_family () == AF_LOCAL && get_socket_type () == SOCK_STREAM)
|
||||
if (get_addr_family () != AF_LOCAL || get_socket_type () != SOCK_STREAM)
|
||||
{
|
||||
if (connect_state () == connected && sec_peer_pid != (pid_t) -1)
|
||||
{
|
||||
if (!check_null_invalid_struct (pid))
|
||||
*pid = sec_peer_pid;
|
||||
if (!check_null_invalid_struct (euid))
|
||||
*euid = sec_peer_uid;
|
||||
if (!check_null_invalid_struct (egid))
|
||||
*egid = sec_peer_gid;
|
||||
return 0;
|
||||
}
|
||||
set_errno (ENOTCONN);
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
set_errno (EINVAL);
|
||||
return -1;
|
||||
if (connect_state () != connected)
|
||||
{
|
||||
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;
|
||||
}
|
||||
|
||||
if (!check_null_invalid_struct (pid))
|
||||
*pid = sec_peer_pid;
|
||||
if (!check_null_invalid_struct (euid))
|
||||
*euid = sec_peer_uid;
|
||||
if (!check_null_invalid_struct (egid))
|
||||
*egid = sec_peer_gid;
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -326,6 +326,7 @@ set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
|
|||
fd_set *exceptfds)
|
||||
{
|
||||
int ready = 0;
|
||||
fhandler_socket *sock;
|
||||
select_printf ("me %p, testing fd %d (%s)", me, me->fd, me->fh->get_name ());
|
||||
if (me->read_selected && me->read_ready)
|
||||
{
|
||||
|
@ -335,8 +336,15 @@ set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
|
|||
if (me->write_selected && me->write_ready)
|
||||
{
|
||||
UNIX_FD_SET (me->fd, writefds);
|
||||
if (me->except_on_write && me->fh->is_socket ())
|
||||
((fhandler_socket *) me->fh)->connect_state (connected);
|
||||
if (me->except_on_write && (sock = me->fh->is_socket ()))
|
||||
{
|
||||
/* eid credential transaction on successful non-blocking connect.
|
||||
Since the read bit indicates an error, don't start transaction
|
||||
if it's set. */
|
||||
if (!me->read_ready && sock->connect_state () == connect_pending)
|
||||
sock->eid_connect ();
|
||||
sock->connect_state (connected);
|
||||
}
|
||||
ready++;
|
||||
}
|
||||
if ((me->except_selected || me->except_on_write) && me->except_ready)
|
||||
|
@ -344,8 +352,12 @@ set_bits (select_record *me, fd_set *readfds, fd_set *writefds,
|
|||
if (me->except_on_write) /* Only on sockets */
|
||||
{
|
||||
UNIX_FD_SET (me->fd, writefds);
|
||||
if (me->fh->is_socket ())
|
||||
((fhandler_socket *) me->fh)->connect_state (connected);
|
||||
if ((sock = me->fh->is_socket ()))
|
||||
{
|
||||
if (!me->read_ready && sock->connect_state () == connect_pending)
|
||||
sock->eid_connect ();
|
||||
sock->connect_state (connected);
|
||||
}
|
||||
}
|
||||
if (me->except_selected)
|
||||
UNIX_FD_SET (me->fd, exceptfds);
|
||||
|
|
Loading…
Reference in New Issue