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:
Corinna Vinschen
2018-02-21 21:40:01 +01:00
parent dff3bc9a86
commit 859d215b7e
10 changed files with 3293 additions and 2218 deletions

View 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)];