diff options
author | Steffen Kieß <s-kiess@web.de> | 2016-01-18 12:04:09 +0300 |
---|---|---|
committer | Steffen Kieß <s-kiess@web.de> | 2016-01-18 12:04:09 +0300 |
commit | ac52b7f4586d49e95f06aea93eb9405b6a2a4cbb (patch) | |
tree | 95148d6e16a489589cc05d497cc91731088fcada /support | |
parent | a3e273b98b14bc2098b9f6171a0629bc94d92ef0 (diff) |
[Mono.Posix] Add wrappers for struct sockaddr_*
Add wrappers for the sockaddr_* structures and add the syscalls using these
structures (bind(), accept(), ...).
Diffstat (limited to 'support')
-rw-r--r-- | support/Makefile.am | 2 | ||||
-rw-r--r-- | support/map.c | 178 | ||||
-rw-r--r-- | support/map.h | 113 | ||||
-rw-r--r-- | support/sys-socket.c | 376 |
4 files changed, 658 insertions, 11 deletions
diff --git a/support/Makefile.am b/support/Makefile.am index 79154fc99bb..be3864cc9da 100644 --- a/support/Makefile.am +++ b/support/Makefile.am @@ -161,7 +161,7 @@ refresh: --rename-member=st_mtime=st_mtime_ \ --rename-namespace=Mono.Unix.Native=Mono.Posix \ --library=MonoPosixHelper \ - $(mcs_topdir)/class/lib/net_4_x/Mono.Posix.dll map + $(mcs_topdir_from_srcdir)/class/lib/net_4_x/Mono.Posix.dll map # Useful if mono is compiled with --enable-shared=no patch-libtool: diff --git a/support/map.c b/support/map.c index ee61ae661d9..6201c260c93 100644 --- a/support/map.c +++ b/support/map.c @@ -1,5 +1,5 @@ /* - * This file was automatically generated by create-native-map from /home/kiesssn/prog/mono/mono/mcs/class/lib/net_4_x/Mono.Posix.dll. + * This file was automatically generated by create-native-map from ../mcs/class/lib/net_4_x/Mono.Posix.dll. * * DO NOT MODIFY. */ @@ -5149,6 +5149,172 @@ int Mono_Posix_ToSignum (int x, int *r) errno = EINVAL; return -1; } +#ifdef HAVE_STRUCT_SOCKADDR_IN +int +Mono_Posix_FromSockaddrIn (struct Mono_Posix_SockaddrIn *from, struct sockaddr_in *to) +{ + _cnm_return_val_if_overflow (unsigned short, from->sin_port, -1); + + memset (to, 0, sizeof(*to)); + + to->sin_port = from->sin_port; + if (Mono_Posix_FromInAddr (&from->sin_addr, &to->sin_addr) != 0) { + return -1; + } + + return 0; +} +#endif /* ndef HAVE_STRUCT_SOCKADDR_IN */ + + +#ifdef HAVE_STRUCT_SOCKADDR_IN +int +Mono_Posix_ToSockaddrIn (struct sockaddr_in *from, struct Mono_Posix_SockaddrIn *to) +{ + _cnm_return_val_if_overflow (unsigned short, from->sin_port, -1); + + memset (to, 0, sizeof(*to)); + + to->sin_port = from->sin_port; + if (Mono_Posix_ToInAddr (&from->sin_addr, &to->sin_addr) != 0) { + return -1; + } + + return 0; +} +#endif /* ndef HAVE_STRUCT_SOCKADDR_IN */ + + +#ifdef HAVE_STRUCT_SOCKADDR_IN6 +int +Mono_Posix_FromSockaddrIn6 (struct Mono_Posix_SockaddrIn6 *from, struct sockaddr_in6 *to) +{ + _cnm_return_val_if_overflow (unsigned short, from->sin6_port, -1); + _cnm_return_val_if_overflow (unsigned int, from->sin6_flowinfo, -1); + _cnm_return_val_if_overflow (unsigned int, from->sin6_scope_id, -1); + + memset (to, 0, sizeof(*to)); + + to->sin6_port = from->sin6_port; + to->sin6_flowinfo = from->sin6_flowinfo; + if (Mono_Posix_FromIn6Addr (&from->sin6_addr, &to->sin6_addr) != 0) { + return -1; + } + to->sin6_scope_id = from->sin6_scope_id; + + return 0; +} +#endif /* ndef HAVE_STRUCT_SOCKADDR_IN6 */ + + +#ifdef HAVE_STRUCT_SOCKADDR_IN6 +int +Mono_Posix_ToSockaddrIn6 (struct sockaddr_in6 *from, struct Mono_Posix_SockaddrIn6 *to) +{ + _cnm_return_val_if_overflow (unsigned short, from->sin6_port, -1); + _cnm_return_val_if_overflow (unsigned int, from->sin6_flowinfo, -1); + _cnm_return_val_if_overflow (unsigned int, from->sin6_scope_id, -1); + + memset (to, 0, sizeof(*to)); + + to->sin6_port = from->sin6_port; + to->sin6_flowinfo = from->sin6_flowinfo; + if (Mono_Posix_ToIn6Addr (&from->sin6_addr, &to->sin6_addr) != 0) { + return -1; + } + to->sin6_scope_id = from->sin6_scope_id; + + return 0; +} +#endif /* ndef HAVE_STRUCT_SOCKADDR_IN6 */ + + +int Mono_Posix_FromSockaddrType (int x, int *r) +{ + *r = 0; + if (x == Mono_Posix_SockaddrType_Invalid) +#ifdef Invalid + {*r = Invalid; return 0;} +#else /* def Invalid */ + {errno = EINVAL; return -1;} +#endif /* ndef Invalid */ + if (x == Mono_Posix_SockaddrType_MustBeWrapped) +#ifdef MustBeWrapped + {*r = MustBeWrapped; return 0;} +#else /* def MustBeWrapped */ + {errno = EINVAL; return -1;} +#endif /* ndef MustBeWrapped */ + if (x == Mono_Posix_SockaddrType_Sockaddr) +#ifdef Sockaddr + {*r = Sockaddr; return 0;} +#else /* def Sockaddr */ + {errno = EINVAL; return -1;} +#endif /* ndef Sockaddr */ + if (x == Mono_Posix_SockaddrType_SockaddrIn) +#ifdef SockaddrIn + {*r = SockaddrIn; return 0;} +#else /* def SockaddrIn */ + {errno = EINVAL; return -1;} +#endif /* ndef SockaddrIn */ + if (x == Mono_Posix_SockaddrType_SockaddrIn6) +#ifdef SockaddrIn6 + {*r = SockaddrIn6; return 0;} +#else /* def SockaddrIn6 */ + {errno = EINVAL; return -1;} +#endif /* ndef SockaddrIn6 */ + if (x == Mono_Posix_SockaddrType_SockaddrStorage) +#ifdef SockaddrStorage + {*r = SockaddrStorage; return 0;} +#else /* def SockaddrStorage */ + {errno = EINVAL; return -1;} +#endif /* ndef SockaddrStorage */ + if (x == Mono_Posix_SockaddrType_SockaddrUn) +#ifdef SockaddrUn + {*r = SockaddrUn; return 0;} +#else /* def SockaddrUn */ + {errno = EINVAL; return -1;} +#endif /* ndef SockaddrUn */ + if (x == 0) + return 0; + errno = EINVAL; return -1; +} + +int Mono_Posix_ToSockaddrType (int x, int *r) +{ + *r = 0; + if (x == 0) + return 0; +#ifdef Invalid + if (x == Invalid) + {*r = Mono_Posix_SockaddrType_Invalid; return 0;} +#endif /* ndef Invalid */ +#ifdef MustBeWrapped + if (x == MustBeWrapped) + {*r = Mono_Posix_SockaddrType_MustBeWrapped; return 0;} +#endif /* ndef MustBeWrapped */ +#ifdef Sockaddr + if (x == Sockaddr) + {*r = Mono_Posix_SockaddrType_Sockaddr; return 0;} +#endif /* ndef Sockaddr */ +#ifdef SockaddrIn + if (x == SockaddrIn) + {*r = Mono_Posix_SockaddrType_SockaddrIn; return 0;} +#endif /* ndef SockaddrIn */ +#ifdef SockaddrIn6 + if (x == SockaddrIn6) + {*r = Mono_Posix_SockaddrType_SockaddrIn6; return 0;} +#endif /* ndef SockaddrIn6 */ +#ifdef SockaddrStorage + if (x == SockaddrStorage) + {*r = Mono_Posix_SockaddrType_SockaddrStorage; return 0;} +#endif /* ndef SockaddrStorage */ +#ifdef SockaddrUn + if (x == SockaddrUn) + {*r = Mono_Posix_SockaddrType_SockaddrUn; return 0;} +#endif /* ndef SockaddrUn */ + errno = EINVAL; return -1; +} + int Mono_Posix_FromSysconfName (int x, int *r) { *r = 0; @@ -7902,6 +8068,12 @@ int Mono_Posix_FromUnixAddressFamily (int x, int *r) #else /* def AF_X25 */ {errno = EINVAL; return -1;} #endif /* ndef AF_X25 */ + if (x == Mono_Posix_UnixAddressFamily_Unknown) +#ifdef Unknown + {*r = Unknown; return 0;} +#else /* def Unknown */ + {errno = EINVAL; return -1;} +#endif /* ndef Unknown */ if (x == 0) return 0; errno = EINVAL; return -1; @@ -8068,6 +8240,10 @@ int Mono_Posix_ToUnixAddressFamily (int x, int *r) if (x == AF_X25) {*r = Mono_Posix_UnixAddressFamily_AF_X25; return 0;} #endif /* ndef AF_X25 */ +#ifdef Unknown + if (x == Unknown) + {*r = Mono_Posix_UnixAddressFamily_Unknown; return 0;} +#endif /* ndef Unknown */ errno = EINVAL; return -1; } diff --git a/support/map.h b/support/map.h index 34cdb68ab4d..eb5bff9ec9a 100644 --- a/support/map.h +++ b/support/map.h @@ -1018,6 +1018,25 @@ enum Mono_Posix_Signum { int Mono_Posix_FromSignum (int x, int *r); int Mono_Posix_ToSignum (int x, int *r); +enum Mono_Posix_SockaddrType { + Mono_Posix_SockaddrType_Invalid = 0x00000000, + #define Mono_Posix_SockaddrType_Invalid Mono_Posix_SockaddrType_Invalid + Mono_Posix_SockaddrType_MustBeWrapped = 0x00008000, + #define Mono_Posix_SockaddrType_MustBeWrapped Mono_Posix_SockaddrType_MustBeWrapped + Mono_Posix_SockaddrType_Sockaddr = 0x00000003, + #define Mono_Posix_SockaddrType_Sockaddr Mono_Posix_SockaddrType_Sockaddr + Mono_Posix_SockaddrType_SockaddrIn = 0x00000004, + #define Mono_Posix_SockaddrType_SockaddrIn Mono_Posix_SockaddrType_SockaddrIn + Mono_Posix_SockaddrType_SockaddrIn6 = 0x00000005, + #define Mono_Posix_SockaddrType_SockaddrIn6 Mono_Posix_SockaddrType_SockaddrIn6 + Mono_Posix_SockaddrType_SockaddrStorage = 0x00000001, + #define Mono_Posix_SockaddrType_SockaddrStorage Mono_Posix_SockaddrType_SockaddrStorage + Mono_Posix_SockaddrType_SockaddrUn = 0x00000002, + #define Mono_Posix_SockaddrType_SockaddrUn Mono_Posix_SockaddrType_SockaddrUn +}; +int Mono_Posix_FromSockaddrType (int x, int *r); +int Mono_Posix_ToSockaddrType (int x, int *r); + enum Mono_Posix_SysconfName { Mono_Posix_SysconfName__SC_2_CHAR_TERM = 0x0000005f, #define Mono_Posix_SysconfName__SC_2_CHAR_TERM Mono_Posix_SysconfName__SC_2_CHAR_TERM @@ -1587,6 +1606,8 @@ enum Mono_Posix_UnixAddressFamily { #define Mono_Posix_UnixAddressFamily_AF_WANPIPE Mono_Posix_UnixAddressFamily_AF_WANPIPE Mono_Posix_UnixAddressFamily_AF_X25 = 0x00000009, #define Mono_Posix_UnixAddressFamily_AF_X25 Mono_Posix_UnixAddressFamily_AF_X25 + Mono_Posix_UnixAddressFamily_Unknown = 0x00010000, + #define Mono_Posix_UnixAddressFamily_Unknown Mono_Posix_UnixAddressFamily_Unknown }; int Mono_Posix_FromUnixAddressFamily (int x, int *r); int Mono_Posix_ToUnixAddressFamily (int x, int *r); @@ -1799,9 +1820,13 @@ int Mono_Posix_ToXattrFlags (int x, int *r); */ struct Mono_Posix_Flock; +struct Mono_Posix_In6Addr; +struct Mono_Posix_InAddr; struct Mono_Posix_Iovec; struct Mono_Posix_Linger; struct Mono_Posix_Pollfd; +struct Mono_Posix_SockaddrIn; +struct Mono_Posix_SockaddrIn6; struct Mono_Posix_Stat; struct Mono_Posix_Statvfs; struct Mono_Posix_Syscall__Dirent; @@ -1813,6 +1838,8 @@ struct Mono_Posix_Timespec; struct Mono_Posix_Timeval; struct Mono_Posix_Timezone; struct Mono_Posix_Utimbuf; +struct Mono_Posix__SockaddrDynamic; +struct Mono_Posix__SockaddrHeader; struct Mono_Unix_UnixSignal_SignalInfo; /* @@ -1823,6 +1850,8 @@ struct flock; struct iovec; struct linger; struct pollfd; +struct sockaddr_in; +struct sockaddr_in6; struct timespec; struct timeval; struct timezone; @@ -1852,6 +1881,15 @@ int Mono_Posix_ToFlock (struct flock *from, struct Mono_Posix_Flock* to); +struct Mono_Posix_In6Addr { + guint64 addr0; + guint64 addr1; +}; + +struct Mono_Posix_InAddr { + unsigned int s_addr; +}; + struct Mono_Posix_Iovec { void* iov_base; guint64 iov_len; @@ -1886,6 +1924,34 @@ int Mono_Posix_ToPollfd (struct pollfd *from, struct Mono_Posix_Pollfd* to); +struct Mono_Posix_SockaddrIn { + int type; + int _sa_family; + unsigned short sin_port; + struct Mono_Posix_InAddr sin_addr; +}; + +int +Mono_Posix_FromSockaddrIn (struct Mono_Posix_SockaddrIn* from, struct sockaddr_in *to); +int +Mono_Posix_ToSockaddrIn (struct sockaddr_in *from, struct Mono_Posix_SockaddrIn* to); + + +struct Mono_Posix_SockaddrIn6 { + int type; + int _sa_family; + unsigned short sin6_port; + unsigned int sin6_flowinfo; + struct Mono_Posix_In6Addr sin6_addr; + unsigned int sin6_scope_id; +}; + +int +Mono_Posix_FromSockaddrIn6 (struct Mono_Posix_SockaddrIn6* from, struct sockaddr_in6 *to); +int +Mono_Posix_ToSockaddrIn6 (struct sockaddr_in6 *from, struct Mono_Posix_SockaddrIn6* to); + + struct Mono_Posix_Stat { guint64 st_dev; /* dev_t */ guint64 st_ino; /* ino_t */ @@ -2013,6 +2079,18 @@ int Mono_Posix_ToUtimbuf (struct utimbuf *from, struct Mono_Posix_Utimbuf* to); +struct Mono_Posix__SockaddrDynamic { + int type; + int sa_family; + unsigned char* data; + gint64 len; +}; + +struct Mono_Posix__SockaddrHeader { + int type; + int sa_family; +}; + struct Mono_Unix_UnixSignal_SignalInfo { int signum; int count; @@ -2035,14 +2113,17 @@ int map_Mono_Posix_AccessMode (int mode); int map_Mono_Posix_FileMode (int mode); int map_Mono_Posix_OpenFlags (int flags); int map_Mono_Posix_WaitOptions (int wait_options); +int Mono_Posix_FromIn6Addr (struct Mono_Posix_In6Addr* source, void* destination); +int Mono_Posix_FromInAddr (struct Mono_Posix_InAddr* source, void* destination); int Mono_Posix_FromRealTimeSignum (int offset, int* rval); +int Mono_Posix_FromSockaddr (struct Mono_Posix__SockaddrHeader* source, void* destination); int Mono_Posix_FromStat (struct Mono_Posix_Stat* source, void* destination); int Mono_Posix_FromStatvfs (struct Mono_Posix_Statvfs* source, void* destination); int Mono_Posix_SIGRTMAX (void); int Mono_Posix_SIGRTMIN (void); -int Mono_Posix_Stdlib__IOFBF (void); -int Mono_Posix_Stdlib__IOLBF (void); -int Mono_Posix_Stdlib__IONBF (void); +int Mono_Posix_SockaddrStorage_get_size (void); +int Mono_Posix_SockaddrUn_get_sizeof_sun_path (void); +int Mono_Posix_Sockaddr_GetNativeSize (struct Mono_Posix__SockaddrHeader* address, gint64* size); int Mono_Posix_Stdlib_BUFSIZ (void); void* Mono_Posix_Stdlib_calloc (guint64 nmemb, guint64 size); int Mono_Posix_Stdlib_clearerr (void* stream); @@ -2078,8 +2159,15 @@ void* Mono_Posix_Stdlib_stdin (void); void* Mono_Posix_Stdlib_stdout (void); guint64 Mono_Posix_Stdlib_strlen (void* s); int Mono_Posix_Stdlib_TMP_MAX (void); +int Mono_Posix_Stdlib__IOFBF (void); +int Mono_Posix_Stdlib__IOLBF (void); +int Mono_Posix_Stdlib__IONBF (void); +int Mono_Posix_Syscall_accept (int socket, struct Mono_Posix__SockaddrHeader* address); +int Mono_Posix_Syscall_accept4 (int socket, struct Mono_Posix__SockaddrHeader* address, int flags); +int Mono_Posix_Syscall_bind (int socket, struct Mono_Posix__SockaddrHeader* address); int Mono_Posix_Syscall_closelog (void); guint64 Mono_Posix_Syscall_confstr (int name, char* buf, guint64 len); +int Mono_Posix_Syscall_connect (int socket, struct Mono_Posix__SockaddrHeader* address); int Mono_Posix_Syscall_creat (const char* pathname, unsigned int mode); int Mono_Posix_Syscall_endfsent (void); int Mono_Posix_Syscall_endgrent (void); @@ -2103,9 +2191,6 @@ int Mono_Posix_Syscall_fstatvfs (int fd, struct Mono_Posix_Statvfs* buf); int Mono_Posix_Syscall_ftruncate (int fd, gint64 length); int Mono_Posix_Syscall_futimens (int fd, struct Mono_Posix_Timespec* times); int Mono_Posix_Syscall_futimes (int fd, struct Mono_Posix_Timeval* tvp); -int Mono_Posix_Syscall_get_at_fdcwd (void); -gint64 Mono_Posix_Syscall_get_utime_now (void); -gint64 Mono_Posix_Syscall_get_utime_omit (void); void* Mono_Posix_Syscall_getcwd (char* buf, guint64 size); int Mono_Posix_Syscall_getdomainname (char* name, guint64 len); int Mono_Posix_Syscall_getfsent (struct Mono_Posix_Syscall__Fstab* fs); @@ -2119,18 +2204,21 @@ int Mono_Posix_Syscall_getgrnam_r (const char* name, struct Mono_Posix_Syscall__ gint64 Mono_Posix_Syscall_gethostid (void); int Mono_Posix_Syscall_gethostname (char* name, guint64 len); int Mono_Posix_Syscall_getlogin_r (char* name, guint64 bufsize); +int Mono_Posix_Syscall_getpeername (int socket, struct Mono_Posix__SockaddrHeader* address); int Mono_Posix_Syscall_getpwent (struct Mono_Posix_Syscall__Passwd* pwbuf); int Mono_Posix_Syscall_getpwnam (const char* name, struct Mono_Posix_Syscall__Passwd* passwd); int Mono_Posix_Syscall_getpwnam_r (const char* name, struct Mono_Posix_Syscall__Passwd* pwbuf, void** pwbufp); int Mono_Posix_Syscall_getpwuid (unsigned int uid, struct Mono_Posix_Syscall__Passwd* passwd); int Mono_Posix_Syscall_getpwuid_r (unsigned int uid, struct Mono_Posix_Syscall__Passwd* pwbuf, void** pwbufp); +int Mono_Posix_Syscall_getsockname (int socket, struct Mono_Posix__SockaddrHeader* address); int Mono_Posix_Syscall_getsockopt (int socket, int level, int option_name, void* option_value, gint64* option_len); int Mono_Posix_Syscall_getsockopt_linger (int socket, int level, int option_name, struct Mono_Posix_Linger* option_value); int Mono_Posix_Syscall_getsockopt_timeval (int socket, int level, int option_name, struct Mono_Posix_Timeval* option_value); int Mono_Posix_Syscall_gettimeofday (struct Mono_Posix_Timeval* tv, void* ignore); gint64 Mono_Posix_Syscall_getxattr (const char* path, const char* name, unsigned char* value, guint64 size); -int Mono_Posix_Syscall_L_ctermid (void); -int Mono_Posix_Syscall_L_cuserid (void); +int Mono_Posix_Syscall_get_at_fdcwd (void); +gint64 Mono_Posix_Syscall_get_utime_now (void); +gint64 Mono_Posix_Syscall_get_utime_omit (void); gint64 Mono_Posix_Syscall_lgetxattr (const char* path, const char* name, unsigned char* value, guint64 size); gint64 Mono_Posix_Syscall_listxattr (const char* path, unsigned char* list, guint64 size); gint64 Mono_Posix_Syscall_llistxattr (const char* path, unsigned char* list, guint64 size); @@ -2140,6 +2228,8 @@ gint64 Mono_Posix_Syscall_lseek (int fd, gint64 offset, int whence); int Mono_Posix_Syscall_lsetxattr (const char* path, const char* name, unsigned char* value, guint64 size, int flags); int Mono_Posix_Syscall_lstat (const char* file_name, struct Mono_Posix_Stat* buf); int Mono_Posix_Syscall_lutimes (const char* filename, struct Mono_Posix_Timeval* tvp); +int Mono_Posix_Syscall_L_ctermid (void); +int Mono_Posix_Syscall_L_cuserid (void); int Mono_Posix_Syscall_mincore (void* start, guint64 length, unsigned char* vec); int Mono_Posix_Syscall_mknod (const char* pathname, unsigned int mode, guint64 dev); int Mono_Posix_Syscall_mknodat (int dirfd, const char* pathname, unsigned int mode, guint64 dev); @@ -2152,8 +2242,8 @@ int Mono_Posix_Syscall_munlock (void* start, guint64 len); int Mono_Posix_Syscall_munmap (void* start, guint64 length); int Mono_Posix_Syscall_nanosleep (struct Mono_Posix_Timespec* req, struct Mono_Posix_Timespec* rem); int Mono_Posix_Syscall_open (const char* pathname, int flags); -int Mono_Posix_Syscall_open_mode (const char* pathname, int flags, unsigned int mode); int Mono_Posix_Syscall_openlog (void* ident, int option, int facility); +int Mono_Posix_Syscall_open_mode (const char* pathname, int flags, unsigned int mode); gint64 Mono_Posix_Syscall_pathconf (const char* path, int name, int defaultError); int Mono_Posix_Syscall_pipe (int* reading, int* writing); int Mono_Posix_Syscall_posix_fadvise (int fd, gint64 offset, gint64 len, int advice); @@ -2171,12 +2261,14 @@ gint64 Mono_Posix_Syscall_readlink (const char* path, unsigned char* buf, guint6 gint64 Mono_Posix_Syscall_readlinkat (int dirfd, const char* pathname, unsigned char* buf, guint64 bufsiz); gint64 Mono_Posix_Syscall_readv (int fd, struct Mono_Posix_Iovec* iov, int iovcnt); gint64 Mono_Posix_Syscall_recv (int socket, void* buffer, guint64 length, int flags); +gint64 Mono_Posix_Syscall_recvfrom (int socket, void* buffer, guint64 length, int flags, struct Mono_Posix__SockaddrHeader* address); int Mono_Posix_Syscall_remap_file_pages (void* start, guint64 size, int prot, gint64 pgoff, int flags); int Mono_Posix_Syscall_removexattr (const char* path, const char* name); int Mono_Posix_Syscall_rewinddir (void* dir); int Mono_Posix_Syscall_seekdir (void* dir, gint64 offset); gint64 Mono_Posix_Syscall_send (int socket, void* message, guint64 length, int flags); gint64 Mono_Posix_Syscall_sendfile (int out_fd, int in_fd, gint64* offset, guint64 count); +gint64 Mono_Posix_Syscall_sendto (int socket, void* message, guint64 length, int flags, struct Mono_Posix__SockaddrHeader* address); int Mono_Posix_Syscall_setdomainname (const char* name, guint64 len); int Mono_Posix_Syscall_setfsent (void); int Mono_Posix_Syscall_setgrent (void); @@ -2215,6 +2307,9 @@ gint64 Mono_Posix_Syscall_write (int fd, void* buf, guint64 count); gint64 Mono_Posix_Syscall_writev (int fd, struct Mono_Posix_Iovec* iov, int iovcnt); int Mono_Posix_Syscall_WSTOPSIG (int status); int Mono_Posix_Syscall_WTERMSIG (int status); +int Mono_Posix_ToIn6Addr (void* source, struct Mono_Posix_In6Addr* destination); +int Mono_Posix_ToInAddr (void* source, struct Mono_Posix_InAddr* destination); +int Mono_Posix_ToSockaddr (void* source, gint64 size, struct Mono_Posix__SockaddrHeader* destination); int Mono_Posix_ToStat (void* source, struct Mono_Posix_Stat* destination); int Mono_Posix_ToStatvfs (void* source, struct Mono_Posix_Statvfs* destination); void* Mono_Unix_UnixSignal_install (int signum); diff --git a/support/sys-socket.c b/support/sys-socket.c index 188df56a18e..5bfdabf46f1 100644 --- a/support/sys-socket.c +++ b/support/sys-socket.c @@ -11,6 +11,7 @@ #include <sys/time.h> #include <netinet/in.h> #include <sys/un.h> +#include <unistd.h> #include <stddef.h> @@ -20,6 +21,48 @@ G_BEGIN_DECLS int +Mono_Posix_SockaddrStorage_get_size (void) +{ + return sizeof (struct sockaddr_storage); +} + +int +Mono_Posix_SockaddrUn_get_sizeof_sun_path (void) +{ + struct sockaddr_un sun; + return sizeof (sun.sun_path); +} + +int +Mono_Posix_FromInAddr (struct Mono_Posix_InAddr* source, void* destination) +{ + memcpy (&((struct in_addr*)destination)->s_addr, &source->s_addr, 4); + return 0; +} + +int +Mono_Posix_ToInAddr (void* source, struct Mono_Posix_InAddr* destination) +{ + memcpy (&destination->s_addr, &((struct in_addr*)source)->s_addr, 4); + return 0; +} + +int +Mono_Posix_FromIn6Addr (struct Mono_Posix_In6Addr* source, void* destination) +{ + memcpy (&((struct in6_addr*)destination)->s6_addr, &source->addr0, 16); + return 0; +} + +int +Mono_Posix_ToIn6Addr (void* source, struct Mono_Posix_In6Addr* destination) +{ + memcpy (&destination->addr0, &((struct in6_addr*)source)->s6_addr, 16); + return 0; +} + + +int Mono_Posix_Syscall_socketpair (int domain, int type, int protocol, int* socket1, int* socket2) { int filedes[2] = {-1, -1}; @@ -123,6 +166,290 @@ Mono_Posix_Syscall_setsockopt_linger (int socket, int level, int option_name, st return setsockopt (socket, level, option_name, &ling, sizeof (struct linger)); } +static int +get_addrlen (struct Mono_Posix__SockaddrHeader* address, socklen_t* addrlen) +{ + if (!address) { + *addrlen = 0; + return 0; + } + + switch (address->type) { + case Mono_Posix_SockaddrType_SockaddrStorage: + mph_return_if_socklen_t_overflow (((struct Mono_Posix__SockaddrDynamic*) address)->len); + *addrlen = ((struct Mono_Posix__SockaddrDynamic*) address)->len; + return 0; + case Mono_Posix_SockaddrType_SockaddrUn: + mph_return_if_socklen_t_overflow (offsetof (struct sockaddr_un, sun_path) + ((struct Mono_Posix__SockaddrDynamic*) address)->len); + *addrlen = offsetof (struct sockaddr_un, sun_path) + ((struct Mono_Posix__SockaddrDynamic*) address)->len; + return 0; + case Mono_Posix_SockaddrType_Sockaddr: *addrlen = sizeof (struct sockaddr); return 0; + case Mono_Posix_SockaddrType_SockaddrIn: *addrlen = sizeof (struct sockaddr_in); return 0; + case Mono_Posix_SockaddrType_SockaddrIn6: *addrlen = sizeof (struct sockaddr_in6); return 0; + default: + *addrlen = 0; + errno = EINVAL; + return -1; + } +} + +int +Mono_Posix_Sockaddr_GetNativeSize (struct Mono_Posix__SockaddrHeader* address, gint64* size) +{ + socklen_t value; + int r; + + r = get_addrlen (address, &value); + *size = value; + return r; +} + +int +Mono_Posix_FromSockaddr (struct Mono_Posix__SockaddrHeader* source, void* destination) +{ + if (!source) + return 0; + + switch (source->type) { + case Mono_Posix_SockaddrType_SockaddrStorage: + // Do nothing, don't copy source->sa_family into addr->sa_family + return 0; + + case Mono_Posix_SockaddrType_SockaddrUn: + memcpy (((struct sockaddr_un*) destination)->sun_path, ((struct Mono_Posix__SockaddrDynamic*) source)->data, ((struct Mono_Posix__SockaddrDynamic*) source)->len); + break; + + case Mono_Posix_SockaddrType_Sockaddr: + break; + + case Mono_Posix_SockaddrType_SockaddrIn: + if (Mono_Posix_FromSockaddrIn ((struct Mono_Posix_SockaddrIn*) source, (struct sockaddr_in*) destination) != 0) + return -1; + break; + + case Mono_Posix_SockaddrType_SockaddrIn6: + if (Mono_Posix_FromSockaddrIn6 ((struct Mono_Posix_SockaddrIn6*) source, (struct sockaddr_in6*) destination) != 0) + return -1; + break; + + default: + errno = EINVAL; + return -1; + } + + int family; + if (Mono_Posix_FromUnixAddressFamily (source->sa_family, &family) != 0) + return -1; + ((struct sockaddr*) destination)->sa_family = family; + + return 0; +} + +int +Mono_Posix_ToSockaddr (void* source, gint64 size, struct Mono_Posix__SockaddrHeader* destination) +{ + struct Mono_Posix__SockaddrDynamic* destination_dyn; + + if (!destination) + return 0; + + switch (destination->type) { + case Mono_Posix_SockaddrType_Sockaddr: + if (size < offsetof (struct sockaddr, sa_family) + sizeof (sa_family_t)) { + errno = ENOBUFS; + return -1; + } + break; + + case Mono_Posix_SockaddrType_SockaddrStorage: + destination_dyn = ((struct Mono_Posix__SockaddrDynamic*) destination); + if (size > destination_dyn->len) { + errno = ENOBUFS; + return -1; + } + destination_dyn->len = size; + break; + + case Mono_Posix_SockaddrType_SockaddrUn: + destination_dyn = ((struct Mono_Posix__SockaddrDynamic*) destination); + if (size - offsetof (struct sockaddr_un, sun_path) > destination_dyn->len) { + errno = ENOBUFS; + return -1; + } + destination_dyn->len = size - offsetof (struct sockaddr_un, sun_path); + memcpy (destination_dyn->data, ((struct sockaddr_un*) source)->sun_path, size); + break; + + case Mono_Posix_SockaddrType_SockaddrIn: + if (size != sizeof (struct sockaddr_in)) { + errno = ENOBUFS; + return -1; + } + if (Mono_Posix_ToSockaddrIn ((struct sockaddr_in*) source, (struct Mono_Posix_SockaddrIn*) destination) != 0) + return -1; + break; + + case Mono_Posix_SockaddrType_SockaddrIn6: + if (size != sizeof (struct sockaddr_in6)) { + errno = ENOBUFS; + return -1; + } + if (Mono_Posix_ToSockaddrIn6 ((struct sockaddr_in6*) source, (struct Mono_Posix_SockaddrIn6*) destination) != 0) + return -1; + break; + + default: + errno = EINVAL; + return -1; + } + + if (Mono_Posix_ToUnixAddressFamily (((struct sockaddr*) source)->sa_family, &destination->sa_family) != 0) + destination->sa_family = Mono_Posix_UnixAddressFamily_Unknown; + + return 0; +} + +// Macro for allocating space for the native sockaddr_* structure +// Must be a macro because it is using alloca() + +#define ALLOC_SOCKADDR \ + socklen_t addrlen; \ + struct sockaddr* addr; \ + gboolean need_free = 0; \ + \ + if (get_addrlen (address, &addrlen) != 0) \ + return -1; \ + if (address == NULL) { \ + addr = NULL; \ + } else if (address->type == Mono_Posix_SockaddrType_SockaddrStorage) { \ + addr = (struct sockaddr*) ((struct Mono_Posix__SockaddrDynamic*) address)->data; \ + } else if (address->type == Mono_Posix_SockaddrType_SockaddrUn) { \ + /* Use alloca() for up to 2048 bytes, use malloc() otherwise */ \ + need_free = addrlen > 2048; \ + addr = need_free ? malloc (addrlen) : alloca (addrlen); \ + if (!addr) \ + return -1; \ + } else { \ + addr = alloca (addrlen); \ + } + + +int +Mono_Posix_Syscall_bind (int socket, struct Mono_Posix__SockaddrHeader* address) +{ + int r; + + ALLOC_SOCKADDR + if (Mono_Posix_FromSockaddr (address, addr) != 0) { + if (need_free) + free (addr); + return -1; + } + + r = bind (socket, addr, addrlen); + + if (need_free) + free (addr); + + return r; +} + +int +Mono_Posix_Syscall_connect (int socket, struct Mono_Posix__SockaddrHeader* address) +{ + int r; + + ALLOC_SOCKADDR + if (Mono_Posix_FromSockaddr (address, addr) != 0) { + if (need_free) + free (addr); + return -1; + } + + r = connect (socket, addr, addrlen); + + if (need_free) + free (addr); + + return r; +} + +int +Mono_Posix_Syscall_accept (int socket, struct Mono_Posix__SockaddrHeader* address) +{ + int r; + + ALLOC_SOCKADDR + + r = accept (socket, addr, &addrlen); + + if (r != -1 && Mono_Posix_ToSockaddr (addr, addrlen, address) != 0) { + close (r); + r = -1; + } + + if (need_free) + free (addr); + + return r; +} + +int +Mono_Posix_Syscall_accept4 (int socket, struct Mono_Posix__SockaddrHeader* address, int flags) +{ + int r; + + ALLOC_SOCKADDR + + r = accept4 (socket, addr, &addrlen, flags); + + if (r != -1 && Mono_Posix_ToSockaddr (addr, addrlen, address) != 0) { + close (r); + r = -1; + } + + if (need_free) + free (addr); + + return r; +} + +int +Mono_Posix_Syscall_getpeername (int socket, struct Mono_Posix__SockaddrHeader* address) +{ + int r; + + ALLOC_SOCKADDR + + r = getpeername (socket, addr, &addrlen); + + if (r != -1 && Mono_Posix_ToSockaddr (addr, addrlen, address) != 0) + r = -1; + + if (need_free) + free (addr); + + return r; +} + +int +Mono_Posix_Syscall_getsockname (int socket, struct Mono_Posix__SockaddrHeader* address) +{ + int r; + + ALLOC_SOCKADDR + + r = getsockname (socket, addr, &addrlen); + + if (r != -1 && Mono_Posix_ToSockaddr (addr, addrlen, address) != 0) + r = -1; + + if (need_free) + free (addr); + + return r; +} + gint64 Mono_Posix_Syscall_recv (int socket, void* message, guint64 length, int flags) { @@ -138,3 +465,52 @@ Mono_Posix_Syscall_send (int socket, void* message, guint64 length, int flags) return send (socket, message, length, flags); } + +gint64 +Mono_Posix_Syscall_recvfrom (int socket, void* buffer, guint64 length, int flags, struct Mono_Posix__SockaddrHeader* address) +{ + int r; + + mph_return_if_size_t_overflow (length); + + ALLOC_SOCKADDR + + r = recvfrom (socket, buffer, length, flags, addr, &addrlen); + + if (r != -1 && Mono_Posix_ToSockaddr (addr, addrlen, address) != 0) + r = -1; + + if (need_free) + free (addr); + + return r; +} + +gint64 +Mono_Posix_Syscall_sendto (int socket, void* message, guint64 length, int flags, struct Mono_Posix__SockaddrHeader* address) +{ + int r; + + mph_return_if_size_t_overflow (length); + + ALLOC_SOCKADDR + if (Mono_Posix_FromSockaddr (address, addr) != 0) { + if (need_free) + free (addr); + return -1; + } + + r = sendto (socket, message, length, flags, addr, addrlen); + + if (need_free) + free (addr); + + return r; +} + +// vim: noexpandtab +// Local Variables: +// tab-width: 4 +// c-basic-offset: 4 +// indent-tabs-mode: t +// End: |