case SocketOptionName_Type:
*system_name = SO_TYPE;
break;
+#ifdef SO_PEERCRED
+ case SocketOptionName_PeerCred:
+ *system_name = SO_PEERCRED;
+ break;
+#endif
case SocketOptionName_ExclusiveAddressUse:
case SocketOptionName_UseLoopback:
case SocketOptionName_MaxConnections:
return(-1);
}
- break; /// SocketOptionLevel_IPv6
+ break; /* SocketOptionLevel_IPv6 */
#endif
case SocketOptionLevel_Tcp:
extern MonoObject *ves_icall_System_Net_Sockets_Socket_LocalEndPoint_internal(SOCKET sock, gint32 *error)
{
- gchar sa[32]; /// sockaddr in not big enough for sockaddr_in6
+ gchar sa[32]; /* sockaddr in not big enough for sockaddr_in6 */
int salen;
int ret;
extern MonoObject *ves_icall_System_Net_Sockets_Socket_RemoteEndPoint_internal(SOCKET sock, gint32 *error)
{
- gchar sa[32]; /// sockaddr in not big enough for sockaddr_in6
+ gchar sa[32]; /* sockaddr in not big enough for sockaddr_in6 */
int salen;
int ret;
return(0);
}
- *sockaddr=create_object_from_sockaddr(sa, sa_size, error);
+ /* If we didn't get a socket size, then we're probably a
+ * connected connection-oriented socket and the stack hasn't
+ * returned the remote address. All we can do is return null.
+ */
+ if ( sa_size != 0 )
+ *sockaddr=create_object_from_sockaddr(sa, sa_size, error);
+ else
+ *sockaddr=NULL;
+
g_free(sa);
return(ret);
int lingersize=sizeof(linger);
struct timeval tv;
int tvsize=sizeof(tv);
+#ifdef SO_PEERCRED
+ struct ucred cred;
+ int credsize = sizeof(cred);
+#endif
MonoDomain *domain=mono_domain_get();
MonoObject *obj;
MonoClass *obj_class;
&tvsize);
break;
+#ifdef SO_PEERCRED
+ case SocketOptionName_PeerCred:
+ ret = _wapi_getsockopt (sock, system_level, system_name, &cred,
+ &credsize);
+ break;
+#endif
+
default:
ret = _wapi_getsockopt (sock, system_level, system_name, &val,
&valsize);
obj = int_to_object (domain, (tv.tv_sec * 1000) + (tv.tv_usec / 1000));
break;
+#ifdef SO_PEERCRED
+ case SocketOptionName_PeerCred:
+ {
+ /* build a Mono.Posix.PeerCred+PeerCredData if
+ * possible
+ */
+ MonoImage *mono_posix_image = mono_image_loaded ("Mono.Posix");
+ MonoPeerCredData *cred_data;
+
+ if (mono_posix_image == NULL) {
+ *error = WSAENOPROTOOPT;
+ return;
+ }
+
+ obj_class = mono_class_from_name(mono_posix_image,
+ "Mono.Posix",
+ "PeerCred/PeerCredData");
+ obj = mono_object_new(domain, obj_class);
+ cred_data = (MonoPeerCredData *)obj;
+ cred_data->pid = cred.pid;
+ cred_data->uid = cred.uid;
+ cred_data->gid = cred.gid;
+ break;
+ }
+#endif
+
default:
obj = int_to_object (domain, val);
}