Cygwin: split out fhandler_socket into inet and local classes
First cut, still incomplete * fhandler_socket is now base class for other socket classes * fhandler_socket_inet handles AF_INET and AF_INET6 sockets * fhandler_socket_local handles AF_LOCAL/AF_UNIX sockets * finally get rid of fdsock by using set_socket_handle in accept4 * align file-related calls (fstat, fstatvfs, fchown, fchmod, facl) to Linux. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
dff3bc9a86
commit
859d215b7e
|
@ -296,6 +296,8 @@ DLL_OFILES:= \
|
|||
fhandler_registry.o \
|
||||
fhandler_serial.o \
|
||||
fhandler_socket.o \
|
||||
fhandler_socket_inet.o \
|
||||
fhandler_socket_local.o \
|
||||
fhandler_tape.o \
|
||||
fhandler_termios.o \
|
||||
fhandler_tty.o \
|
||||
|
|
|
@ -304,8 +304,8 @@ dtable::init_std_file_from_handle (int fd, HANDLE handle)
|
|||
dev.parse (name);
|
||||
else if (strcmp (name, ":sock:") == 0
|
||||
/* NtQueryObject returns an error when called on an LSP socket
|
||||
handle. fdsock tries to fetch the underlying base socket,
|
||||
but this might fail. */
|
||||
handle. fhandler_socket::set_socket_handle tries to fetch
|
||||
the underlying base socket, but this might fail. */
|
||||
|| (strcmp (name, unknown_file) == 0
|
||||
&& !::getsockopt ((SOCKET) handle, SOL_SOCKET, SO_RCVBUF,
|
||||
(char *) &rcv, &len)))
|
||||
|
@ -517,10 +517,12 @@ fh_alloc (path_conv& pc)
|
|||
case FH_TCP:
|
||||
case FH_UDP:
|
||||
case FH_ICMP:
|
||||
fh = cnew (fhandler_socket_inet);
|
||||
break;
|
||||
case FH_UNIX:
|
||||
case FH_STREAM:
|
||||
case FH_DGRAM:
|
||||
fh = cnew (fhandler_socket);
|
||||
fh = cnew (fhandler_socket_local);
|
||||
break;
|
||||
case FH_FS:
|
||||
fh = cnew (fhandler_disk_file);
|
||||
|
|
|
@ -479,9 +479,16 @@ struct wsa_event
|
|||
class fhandler_socket: public fhandler_base
|
||||
{
|
||||
private:
|
||||
/* permission fake following Linux rules */
|
||||
uid_t uid;
|
||||
uid_t gid;
|
||||
mode_t mode;
|
||||
|
||||
protected:
|
||||
int addr_family;
|
||||
int type;
|
||||
int connect_secret[4];
|
||||
virtual int af_local_connect () = 0;
|
||||
int get_socket_flags ();
|
||||
|
||||
wsa_event *wsock_events;
|
||||
HANDLE wsock_mtx;
|
||||
|
@ -491,32 +498,11 @@ class fhandler_socket: public fhandler_base
|
|||
int evaluate_events (const long event_mask, long &events, const bool erase);
|
||||
const HANDLE wsock_event () const { return wsock_evt; }
|
||||
const LONG serial_number () const { return wsock_events->serial_number; }
|
||||
private:
|
||||
protected:
|
||||
int wait_for_events (const long event_mask, const DWORD flags);
|
||||
void release_events ();
|
||||
|
||||
pid_t sec_pid;
|
||||
uid_t sec_uid;
|
||||
gid_t sec_gid;
|
||||
pid_t sec_peer_pid;
|
||||
uid_t sec_peer_uid;
|
||||
gid_t sec_peer_gid;
|
||||
void af_local_set_secret (char *);
|
||||
void af_local_setblocking (bool &, bool &);
|
||||
void af_local_unsetblocking (bool, bool);
|
||||
void af_local_set_cred ();
|
||||
void af_local_copy (fhandler_socket *);
|
||||
bool af_local_recv_secret ();
|
||||
bool af_local_send_secret ();
|
||||
bool af_local_recv_cred ();
|
||||
bool af_local_send_cred ();
|
||||
int af_local_accept ();
|
||||
public:
|
||||
int af_local_connect ();
|
||||
int af_local_set_no_getpeereid ();
|
||||
void af_local_set_sockpair_cred ();
|
||||
|
||||
private:
|
||||
protected:
|
||||
int _rmem;
|
||||
int _wmem;
|
||||
public:
|
||||
|
@ -525,22 +511,20 @@ class fhandler_socket: public fhandler_base
|
|||
void rmem (int nrmem) { _rmem = nrmem; }
|
||||
void wmem (int nwmem) { _wmem = nwmem; }
|
||||
|
||||
private:
|
||||
protected:
|
||||
DWORD _rcvtimeo; /* msecs */
|
||||
DWORD _sndtimeo; /* msecs */
|
||||
public:
|
||||
DWORD &rcvtimeo () { return _rcvtimeo; }
|
||||
DWORD &sndtimeo () { return _sndtimeo; }
|
||||
|
||||
private:
|
||||
protected:
|
||||
struct _WSAPROTOCOL_INFOW *prot_info_ptr;
|
||||
public:
|
||||
void init_fixup_before ();
|
||||
bool need_fixup_before () const {return prot_info_ptr != NULL;}
|
||||
|
||||
private:
|
||||
char *sun_path;
|
||||
char *peer_sun_path;
|
||||
protected:
|
||||
struct status_flags
|
||||
{
|
||||
unsigned async_io : 1; /* async I/O */
|
||||
|
@ -580,35 +564,34 @@ class fhandler_socket: public fhandler_base
|
|||
IMPLEMENT_STATUS_FLAG (conn_state, connect_state)
|
||||
IMPLEMENT_STATUS_FLAG (bool, no_getpeereid)
|
||||
|
||||
int socket (int af, int type, int protocol, int flags);
|
||||
int bind (const struct sockaddr *name, int namelen);
|
||||
int connect (const struct sockaddr *name, int namelen);
|
||||
int listen (int backlog);
|
||||
int accept4 (struct sockaddr *peer, int *len, int flags);
|
||||
int getsockname (struct sockaddr *name, int *namelen);
|
||||
int getpeername (struct sockaddr *name, int *namelen);
|
||||
int getpeereid (pid_t *pid, uid_t *euid, gid_t *egid);
|
||||
int socketpair (int af, int type, int protocol, int flags,
|
||||
fhandler_socket *fh_out);
|
||||
int setsockopt (int level, int optname, const void *optval,
|
||||
__socklen_t optlen);
|
||||
int getsockopt (int level, int optname, const void *optval,
|
||||
__socklen_t *optlen);
|
||||
virtual int socket (int af, int type, int protocol, int flags) = 0;
|
||||
virtual int socketpair (int af, int type, int protocol, int flags,
|
||||
fhandler_socket *fh_out) = 0;
|
||||
virtual int bind (const struct sockaddr *name, int namelen) = 0;
|
||||
virtual int listen (int backlog) = 0;
|
||||
virtual int accept4 (struct sockaddr *peer, int *len, int flags) = 0;
|
||||
virtual int connect (const struct sockaddr *name, int namelen) = 0;
|
||||
virtual int getsockname (struct sockaddr *name, int *namelen) = 0;
|
||||
virtual int getpeername (struct sockaddr *name, int *namelen) = 0;
|
||||
virtual int getpeereid (pid_t *pid, uid_t *euid, gid_t *egid);
|
||||
virtual int setsockopt (int level, int optname, const void *optval,
|
||||
__socklen_t optlen) = 0;
|
||||
virtual int getsockopt (int level, int optname, const void *optval,
|
||||
__socklen_t *optlen) = 0;
|
||||
|
||||
int open (int flags, mode_t mode = 0);
|
||||
void __reg3 read (void *ptr, size_t& len);
|
||||
ssize_t __stdcall readv (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
||||
inline ssize_t __reg3 recv_internal (struct _WSAMSG *wsamsg, bool use_recvmsg);
|
||||
ssize_t recvfrom (void *ptr, size_t len, int flags,
|
||||
struct sockaddr *from, int *fromlen);
|
||||
ssize_t recvmsg (struct msghdr *msg, int flags);
|
||||
virtual ssize_t recvfrom (void *ptr, size_t len, int flags,
|
||||
struct sockaddr *from, int *fromlen) = 0;
|
||||
virtual ssize_t recvmsg (struct msghdr *msg, int flags) = 0;
|
||||
virtual void __reg3 read (void *ptr, size_t& len) = 0;
|
||||
virtual ssize_t __stdcall readv (const struct iovec *, int iovcnt,
|
||||
ssize_t tot = -1) = 0;
|
||||
|
||||
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||
ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
||||
inline ssize_t send_internal (struct _WSAMSG *wsamsg, int flags);
|
||||
ssize_t sendto (const void *ptr, size_t len, int flags,
|
||||
const struct sockaddr *to, int tolen);
|
||||
ssize_t sendmsg (const struct msghdr *msg, int flags);
|
||||
virtual ssize_t sendto (const void *ptr, size_t len, int flags,
|
||||
const struct sockaddr *to, int tolen) = 0;
|
||||
virtual ssize_t sendmsg (const struct msghdr *msg, int flags) = 0;
|
||||
virtual ssize_t __stdcall write (const void *ptr, size_t len) = 0;
|
||||
virtual ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1) = 0;
|
||||
|
||||
int ioctl (unsigned int cmd, void *);
|
||||
int fcntl (int cmd, intptr_t);
|
||||
|
@ -635,31 +618,159 @@ class fhandler_socket: public fhandler_base
|
|||
int get_addr_family () {return addr_family;}
|
||||
void set_socket_type (int st) { type = st;}
|
||||
int get_socket_type () {return type;}
|
||||
|
||||
int __reg2 fstat (struct stat *buf);
|
||||
int __reg2 fstatvfs (struct statvfs *buf);
|
||||
int __reg1 fchmod (mode_t newmode);
|
||||
int __reg2 fchown (uid_t newuid, gid_t newgid);
|
||||
int __reg3 facl (int, int, struct acl *);
|
||||
int __reg2 link (const char *);
|
||||
};
|
||||
|
||||
class fhandler_socket_inet: public fhandler_socket
|
||||
{
|
||||
protected:
|
||||
int af_local_connect () { return 0; }
|
||||
|
||||
private:
|
||||
inline ssize_t recv_internal (struct _WSAMSG *wsamsg, bool use_recvmsg);
|
||||
inline ssize_t send_internal (struct _WSAMSG *wsamsg, int flags);
|
||||
|
||||
public:
|
||||
fhandler_socket_inet ();
|
||||
~fhandler_socket_inet ();
|
||||
|
||||
int socket (int af, int type, int protocol, int flags);
|
||||
int socketpair (int af, int type, int protocol, int flags,
|
||||
fhandler_socket *fh_out);
|
||||
int bind (const struct sockaddr *name, int namelen);
|
||||
int listen (int backlog);
|
||||
int accept4 (struct sockaddr *peer, int *len, int flags);
|
||||
int connect (const struct sockaddr *name, int namelen);
|
||||
int getsockname (struct sockaddr *name, int *namelen);
|
||||
int getpeername (struct sockaddr *name, int *namelen);
|
||||
int setsockopt (int level, int optname, const void *optval,
|
||||
__socklen_t optlen);
|
||||
int getsockopt (int level, int optname, const void *optval,
|
||||
__socklen_t *optlen);
|
||||
ssize_t recvfrom (void *ptr, size_t len, int flags,
|
||||
struct sockaddr *from, int *fromlen);
|
||||
ssize_t recvmsg (struct msghdr *msg, int flags);
|
||||
void __reg3 read (void *ptr, size_t& len);
|
||||
ssize_t __stdcall readv (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
||||
ssize_t sendto (const void *ptr, size_t len, int flags,
|
||||
const struct sockaddr *to, int tolen);
|
||||
ssize_t sendmsg (const struct msghdr *msg, int flags);
|
||||
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||
ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
||||
|
||||
/* from here on: CLONING */
|
||||
fhandler_socket_inet (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
x->pc.free_strings ();
|
||||
*reinterpret_cast<fhandler_socket_inet *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_socket_inet *clone (cygheap_types malloc_type = HEAP_FHANDLER)
|
||||
{
|
||||
void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_socket_inet));
|
||||
fhandler_socket_inet *fh = new (ptr) fhandler_socket_inet (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
};
|
||||
|
||||
class fhandler_socket_local: public fhandler_socket
|
||||
{
|
||||
protected:
|
||||
char *sun_path;
|
||||
char *peer_sun_path;
|
||||
void set_sun_path (const char *path);
|
||||
char *get_sun_path () {return sun_path;}
|
||||
void set_peer_sun_path (const char *path);
|
||||
char *get_peer_sun_path () {return peer_sun_path;}
|
||||
|
||||
protected:
|
||||
int connect_secret[4];
|
||||
pid_t sec_pid;
|
||||
uid_t sec_uid;
|
||||
gid_t sec_gid;
|
||||
pid_t sec_peer_pid;
|
||||
uid_t sec_peer_uid;
|
||||
gid_t sec_peer_gid;
|
||||
void af_local_set_secret (char *);
|
||||
void af_local_setblocking (bool &, bool &);
|
||||
void af_local_unsetblocking (bool, bool);
|
||||
void af_local_set_cred ();
|
||||
void af_local_copy (fhandler_socket_local *);
|
||||
bool af_local_recv_secret ();
|
||||
bool af_local_send_secret ();
|
||||
bool af_local_recv_cred ();
|
||||
bool af_local_send_cred ();
|
||||
int af_local_accept ();
|
||||
int af_local_connect ();
|
||||
int af_local_set_no_getpeereid ();
|
||||
void af_local_set_sockpair_cred ();
|
||||
|
||||
private:
|
||||
inline ssize_t recv_internal (struct _WSAMSG *wsamsg, bool use_recvmsg);
|
||||
inline ssize_t send_internal (struct _WSAMSG *wsamsg, int flags);
|
||||
|
||||
public:
|
||||
fhandler_socket_local ();
|
||||
~fhandler_socket_local ();
|
||||
|
||||
int dup (fhandler_base *child, int);
|
||||
|
||||
int socket (int af, int type, int protocol, int flags);
|
||||
int socketpair (int af, int type, int protocol, int flags,
|
||||
fhandler_socket *fh_out);
|
||||
int bind (const struct sockaddr *name, int namelen);
|
||||
int listen (int backlog);
|
||||
int accept4 (struct sockaddr *peer, int *len, int flags);
|
||||
int connect (const struct sockaddr *name, int namelen);
|
||||
int getsockname (struct sockaddr *name, int *namelen);
|
||||
int getpeername (struct sockaddr *name, int *namelen);
|
||||
int getpeereid (pid_t *pid, uid_t *euid, gid_t *egid);
|
||||
int setsockopt (int level, int optname, const void *optval,
|
||||
__socklen_t optlen);
|
||||
int getsockopt (int level, int optname, const void *optval,
|
||||
__socklen_t *optlen);
|
||||
ssize_t recvfrom (void *ptr, size_t len, int flags,
|
||||
struct sockaddr *from, int *fromlen);
|
||||
ssize_t recvmsg (struct msghdr *msg, int flags);
|
||||
void __reg3 read (void *ptr, size_t& len);
|
||||
ssize_t __stdcall readv (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
||||
ssize_t sendto (const void *ptr, size_t len, int flags,
|
||||
const struct sockaddr *to, int tolen);
|
||||
ssize_t sendmsg (const struct msghdr *msg, int flags);
|
||||
ssize_t __stdcall write (const void *ptr, size_t len);
|
||||
ssize_t __stdcall writev (const struct iovec *, int iovcnt, ssize_t tot = -1);
|
||||
|
||||
int __reg2 fstat (struct stat *buf);
|
||||
int __reg2 fstatvfs (struct statvfs *buf);
|
||||
int __reg1 fchmod (mode_t mode);
|
||||
int __reg2 fchown (uid_t uid, gid_t gid);
|
||||
int __reg1 fchmod (mode_t newmode);
|
||||
int __reg2 fchown (uid_t newuid, gid_t newgid);
|
||||
int __reg3 facl (int, int, struct acl *);
|
||||
int __reg2 link (const char *);
|
||||
|
||||
fhandler_socket (void *) {}
|
||||
/* from here on: CLONING */
|
||||
fhandler_socket_local (void *) {}
|
||||
|
||||
void copyto (fhandler_base *x)
|
||||
{
|
||||
x->pc.free_strings ();
|
||||
*reinterpret_cast<fhandler_socket *> (x) = *this;
|
||||
*reinterpret_cast<fhandler_socket_local *> (x) = *this;
|
||||
x->reset (this);
|
||||
}
|
||||
|
||||
fhandler_socket *clone (cygheap_types malloc_type = HEAP_FHANDLER)
|
||||
fhandler_socket_local *clone (cygheap_types malloc_type = HEAP_FHANDLER)
|
||||
{
|
||||
void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_socket));
|
||||
fhandler_socket *fh = new (ptr) fhandler_socket (ptr);
|
||||
void *ptr = (void *) ccalloc (malloc_type, 1, sizeof (fhandler_socket_local));
|
||||
fhandler_socket_local *fh = new (ptr) fhandler_socket_local (ptr);
|
||||
copyto (fh);
|
||||
return fh;
|
||||
}
|
||||
|
@ -2223,6 +2334,8 @@ typedef union
|
|||
char __registry[sizeof (fhandler_registry)];
|
||||
char __serial[sizeof (fhandler_serial)];
|
||||
char __socket[sizeof (fhandler_socket)];
|
||||
char __socket_inet[sizeof (fhandler_socket_inet)];
|
||||
char __socket_local[sizeof (fhandler_socket_local)];
|
||||
char __termios[sizeof (fhandler_termios)];
|
||||
char __pty_common[sizeof (fhandler_pty_common)];
|
||||
char __pty_slave[sizeof (fhandler_pty_slave)];
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -500,146 +500,6 @@ cygwin_getprotobynumber (int number)
|
|||
return dup_ent (getprotobynumber (number));
|
||||
}
|
||||
|
||||
#ifndef SIO_BASE_HANDLE
|
||||
#define SIO_BASE_HANDLE _WSAIOR(IOC_WS2,34)
|
||||
#endif
|
||||
|
||||
bool
|
||||
fdsock (cygheap_fdmanip& fd, const device *dev, SOCKET soc)
|
||||
{
|
||||
fd = build_fh_dev (*dev);
|
||||
if (!fd.isopen ())
|
||||
return false;
|
||||
|
||||
/* Usually sockets are inheritable IFS objects. Unfortunately some virus
|
||||
scanners or other network-oriented software replace normal sockets
|
||||
with their own kind, which is running through a filter driver called
|
||||
"layered service provider" (LSP).
|
||||
|
||||
LSP sockets are not kernel objects. They are typically not marked as
|
||||
inheritable, nor are they IFS handles. They are in fact not inheritable
|
||||
to child processes, and it does not help to mark them inheritable via
|
||||
SetHandleInformation. Subsequent socket calls in the child process fail
|
||||
with error 10038, WSAENOTSOCK.
|
||||
|
||||
There's a neat way to workaround these annoying LSP sockets. WSAIoctl
|
||||
allows to fetch the underlying base socket, which is a normal, inheritable
|
||||
IFS handle. So we fetch the base socket, duplicate it, and close the
|
||||
original socket. Now we have a standard IFS socket which (hopefully)
|
||||
works as expected.
|
||||
|
||||
If that doesn't work for some reason, mark the sockets for duplication
|
||||
via WSADuplicateSocket/WSASocket. This requires to start the child
|
||||
process in SUSPENDED state so we only do this if really necessary. */
|
||||
DWORD flags;
|
||||
bool fixup = false;
|
||||
if (!GetHandleInformation ((HANDLE) soc, &flags)
|
||||
|| !(flags & HANDLE_FLAG_INHERIT))
|
||||
{
|
||||
int ret;
|
||||
SOCKET base_soc;
|
||||
DWORD bret;
|
||||
|
||||
fixup = true;
|
||||
debug_printf ("LSP handle: %p", soc);
|
||||
ret = WSAIoctl (soc, SIO_BASE_HANDLE, NULL, 0, (void *) &base_soc,
|
||||
sizeof (base_soc), &bret, NULL, NULL);
|
||||
if (ret)
|
||||
debug_printf ("WSAIoctl: %u", WSAGetLastError ());
|
||||
else if (base_soc != soc)
|
||||
{
|
||||
if (GetHandleInformation ((HANDLE) base_soc, &flags)
|
||||
&& (flags & HANDLE_FLAG_INHERIT))
|
||||
{
|
||||
if (!DuplicateHandle (GetCurrentProcess (), (HANDLE) base_soc,
|
||||
GetCurrentProcess (), (PHANDLE) &base_soc,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS))
|
||||
debug_printf ("DuplicateHandle failed, %E");
|
||||
else
|
||||
{
|
||||
closesocket (soc);
|
||||
soc = base_soc;
|
||||
fixup = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fd->set_io_handle ((HANDLE) soc);
|
||||
if (!((fhandler_socket *) fd)->init_events ())
|
||||
return false;
|
||||
if (fixup)
|
||||
((fhandler_socket *) fd)->init_fixup_before ();
|
||||
fd->set_flags (O_RDWR | O_BINARY);
|
||||
debug_printf ("fd %d, name '%s', soc %p", (int) fd, dev->name (), soc);
|
||||
|
||||
/* Raise default buffer sizes (instead of WinSock default 8K).
|
||||
|
||||
64K appear to have the best size/performance ratio for a default
|
||||
value. Tested with ssh/scp on Vista over Gigabit LAN.
|
||||
|
||||
NOTE. If the SO_RCVBUF size exceeds 65535(*), and if the socket is
|
||||
connected to a remote machine, then calling WSADuplicateSocket on
|
||||
fork/exec fails with WinSock error 10022, WSAEINVAL. Fortunately
|
||||
we don't use WSADuplicateSocket anymore, rather we just utilize
|
||||
handle inheritance. An explanation for this weird behaviour would
|
||||
be nice, though.
|
||||
|
||||
NOTE 2. Testing on x86_64 (Vista, 2008 R2, W8) indicates that
|
||||
this is no problem on 64 bit. So we set the default buffer size to
|
||||
the default values in current 3.x Linux versions.
|
||||
|
||||
NOTE 3. Setting the window size to 65535 results in extremely bad
|
||||
performance for apps that send data in multiples of Kb, as they
|
||||
eventually end up sending 1 byte on the network and naggle + delay
|
||||
ack kicks in. For example, iperf on a 10Gb network gives only 10
|
||||
Mbits/sec with a 65535 send buffer. We want this to be a multiple
|
||||
of 1k, but since 64k breaks WSADuplicateSocket we use 63Kb.
|
||||
|
||||
NOTE 4. Tests with iperf uncover a problem in setting the SO_RCVBUF
|
||||
and SO_SNDBUF sizes. Windows is using autotuning since Windows Vista.
|
||||
Manually setting SO_RCVBUF/SO_SNDBUF disables autotuning and leads to
|
||||
inferior send/recv performance in scenarios with larger RTTs, as is
|
||||
basically standard when accessing the internet. For a discussion,
|
||||
see https://cygwin.com/ml/cygwin-patches/2017-q1/msg00010.html.
|
||||
|
||||
(*) Maximum normal TCP window size. Coincidence? */
|
||||
#ifdef __x86_64__
|
||||
((fhandler_socket *) fd)->rmem () = 212992;
|
||||
((fhandler_socket *) fd)->wmem () = 212992;
|
||||
#else
|
||||
((fhandler_socket *) fd)->rmem () = 64512;
|
||||
((fhandler_socket *) fd)->wmem () = 64512;
|
||||
#endif
|
||||
#if 0 /* See NOTE 4 above. */
|
||||
int size;
|
||||
|
||||
if (::setsockopt (soc, SOL_SOCKET, SO_RCVBUF,
|
||||
(char *) &((fhandler_socket *) fd)->rmem (), sizeof (int)))
|
||||
{
|
||||
debug_printf ("setsockopt(SO_RCVBUF) failed, %u", WSAGetLastError ());
|
||||
if (::getsockopt (soc, SOL_SOCKET, SO_RCVBUF,
|
||||
(char *) &((fhandler_socket *) fd)->rmem (),
|
||||
(size = sizeof (int), &size)))
|
||||
system_printf ("getsockopt(SO_RCVBUF) failed, %u", WSAGetLastError ());
|
||||
}
|
||||
if (::setsockopt (soc, SOL_SOCKET, SO_SNDBUF,
|
||||
(char *) &((fhandler_socket *) fd)->wmem (), sizeof (int)))
|
||||
{
|
||||
debug_printf ("setsockopt(SO_SNDBUF) failed, %u", WSAGetLastError ());
|
||||
if (::getsockopt (soc, SOL_SOCKET, SO_SNDBUF,
|
||||
(char *) &((fhandler_socket *) fd)->wmem (),
|
||||
(size = sizeof (int), &size)))
|
||||
system_printf ("getsockopt(SO_SNDBUF) failed, %u", WSAGetLastError ());
|
||||
}
|
||||
#endif
|
||||
/* A unique ID is necessary to recognize fhandler entries which are
|
||||
duplicated by dup(2) or fork(2). This is used in BSD flock calls
|
||||
to identify the descriptor. */
|
||||
((fhandler_socket *) fd)->set_unique_id ();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* exported as socket: POSIX.1-2001, POSIX.1-2008, 4.4BSD */
|
||||
extern "C" int
|
||||
cygwin_socket (int af, int type, int protocol)
|
||||
|
|
|
@ -17,6 +17,7 @@ details. */
|
|||
|
||||
/* UID/GID */
|
||||
void uinfo_init ();
|
||||
bool check_token_membership (PSID);
|
||||
|
||||
#define ILLEGAL_UID ((uid_t)-1)
|
||||
#define ILLEGAL_GID ((gid_t)-1)
|
||||
|
|
|
@ -185,17 +185,12 @@ static enum {
|
|||
static int syslogd_sock = -1;
|
||||
extern "C" int cygwin_socket (int, int, int);
|
||||
extern "C" int cygwin_connect (int, const struct sockaddr *, int);
|
||||
extern int get_inet_addr (const struct sockaddr *, int,
|
||||
struct sockaddr_storage *, int *,
|
||||
int * = NULL, int * = NULL);
|
||||
|
||||
static void
|
||||
connect_syslogd ()
|
||||
{
|
||||
int fd;
|
||||
struct sockaddr_un sun;
|
||||
struct sockaddr_storage sst;
|
||||
int len, type;
|
||||
|
||||
if (syslogd_inited != not_inited && syslogd_sock >= 0)
|
||||
close (syslogd_sock);
|
||||
|
@ -203,20 +198,38 @@ connect_syslogd ()
|
|||
syslogd_sock = -1;
|
||||
sun.sun_family = AF_LOCAL;
|
||||
strncpy (sun.sun_path, _PATH_LOG, sizeof sun.sun_path);
|
||||
if (get_inet_addr ((struct sockaddr *) &sun, sizeof sun, &sst, &len, &type))
|
||||
return;
|
||||
if ((fd = cygwin_socket (AF_LOCAL, type, 0)) < 0)
|
||||
if ((fd = cygwin_socket (AF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC, 0)) < 0)
|
||||
return;
|
||||
if (cygwin_connect (fd, (struct sockaddr *) &sun, sizeof sun) == 0)
|
||||
syslogd_inited = inited_stream;
|
||||
else
|
||||
{
|
||||
/* connect on a dgram socket always succeeds. We still don't know
|
||||
if syslogd is actually listening. */
|
||||
if (type == SOCK_DGRAM)
|
||||
close (fd);
|
||||
if ((fd = cygwin_socket (AF_LOCAL, SOCK_DGRAM | SOCK_CLOEXEC, 0)) < 0)
|
||||
return;
|
||||
if (cygwin_connect (fd, (struct sockaddr *) &sun, sizeof sun) == 0)
|
||||
{
|
||||
/*
|
||||
* FIXME
|
||||
*
|
||||
* As soon as AF_LOCAL sockets are using pipes, this code has to
|
||||
* got away.
|
||||
*/
|
||||
|
||||
/* connect on a dgram socket always succeeds. We still don't know
|
||||
if syslogd is actually listening. */
|
||||
cygheap_fdget cfd (fd);
|
||||
fhandler_socket_local *const fh = (fhandler_socket_local *)
|
||||
cfd->is_socket ();
|
||||
tmp_pathbuf tp;
|
||||
PMIB_UDPTABLE tab = (PMIB_UDPTABLE) tp.w_get ();
|
||||
DWORD size = 65536;
|
||||
bool found = false;
|
||||
struct sockaddr_storage sst;
|
||||
int len;
|
||||
|
||||
len = sizeof sst;
|
||||
::getsockname (fh->get_socket (), (struct sockaddr *) &sst, &len);
|
||||
struct sockaddr_in *sa = (struct sockaddr_in *) &sst;
|
||||
|
||||
if (GetUdpTable (tab, &size, FALSE) == NO_ERROR)
|
||||
|
@ -235,11 +248,12 @@ connect_syslogd ()
|
|||
return;
|
||||
}
|
||||
}
|
||||
syslogd_inited = inited_dgram;
|
||||
}
|
||||
syslogd_inited = type == SOCK_DGRAM ? inited_dgram : inited_stream;
|
||||
else
|
||||
close (fd);
|
||||
}
|
||||
syslogd_sock = fd;
|
||||
fcntl64 (syslogd_sock, F_SETFD, FD_CLOEXEC);
|
||||
debug_printf ("found /dev/log, fd = %d, type = %s",
|
||||
fd, syslogd_inited == inited_stream ? "STREAM" : "DGRAM");
|
||||
return;
|
||||
|
|
|
@ -117,7 +117,7 @@ cygheap_user::init ()
|
|||
|
||||
This needs careful checking should we use check_token_membership in other
|
||||
circumstances. */
|
||||
static bool
|
||||
bool
|
||||
check_token_membership (PSID sid)
|
||||
{
|
||||
NTSTATUS status;
|
||||
|
@ -142,7 +142,7 @@ check_token_membership (PSID sid)
|
|||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
internal_getlogin (cygheap_user &user)
|
||||
{
|
||||
struct passwd *pwd;
|
||||
|
|
Loading…
Reference in New Issue