Hi, While adding support for SCM_RIGHTS to glibc, I've created a testcase that sends and receives some ports on the result of a socketpair() call. The ports sent were initially the two ports result of another socketpair() call, and it was working fine, but then I tried with the result of a couple of open() calls, and socket_recv() was returning EMIGSERVERDIED.
I've reduced the testcase to not call glibc functions, so we see the problem is in Hurd and not in my patch (which only touches glibc). The testcase has an #if that you can toggle to 0 or 1. If at 0, it will send a socket's port and everything will work, but if at 1, it will send a file's port and socket_recv will send an error. I have added some code to pflocal and socket_send seems to be working fine and returning the correct number of ports (1 in this case). So I've stepped over the MiG client stub for socket_send, and it has this: /* msgh_size passed as argument */ InP->Head.msgh_request_port = sock; InP->Head.msgh_reply_port = __mig_get_reply_port(); InP->Head.msgh_seqno = 0; InP->Head.msgh_id = 26015; msg_result = __mach_msg(&InP->Head, MACH_SEND_MSG|MACH_RCV_MSG|MACH_MSG_OPTION_NONE, 40, sizeof(Reply), InP->Head.msgh_reply_port, MACH_MSG_TIMEOUT_NONE, MACH_PORT_NULL); if (msg_result != MACH_MSG_SUCCESS) { __mig_dealloc_reply_port(InP->Head.msgh_reply_port); return msg_result; } __mig_put_reply_port(InP->Head.msgh_reply_port); if (OutP->Head.msgh_id != 26115) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; else { __mig_dealloc_reply_port(InP->Head.msgh_reply_port); return MIG_REPLY_MISMATCH; } } It's returning because of this: if (OutP->Head.msgh_id != 26115) { if (OutP->Head.msgh_id == MACH_NOTIFY_SEND_ONCE) return MIG_SERVER_DIED; But I'm not sure how to interpret it, and why a non-socket port in the ports argument would cause this. Any ideas? Regards, Emilio #define _GNU_SOURCE #include <error.h> #include <fcntl.h> #include <sys/socket.h> #include <hurd.h> #include <hurd/fd.h> #include <hurd/socket.h> int main (int argc, char **argv) { error_t err; addr_port_t aport; socket_t server, sock1, sock2; int flags; mach_msg_type_number_t dlen, clen, amount; char *cdata, *data, c; mach_port_t *ports; mach_msg_type_number_t nports = 0; server = file_name_lookup ("/servers/socket/1", 0, 0); if (server == MACH_PORT_NULL) return -1; err = socket_create (server, SOCK_STREAM, 0, &sock1); if (! err) err = socket_create (server, SOCK_STREAM, 0, &sock2); if (! err) err = socket_connect2 (sock1, sock2); if (err) error (1, err, "could not create sockets"); #if 0 file_t file = file_name_lookup ("/tmp/file1", 0, O_RDONLY); if (file == MACH_PORT_NULL) error (1, err, "file not found: %s", "/tmp/file1"); #else socket_t file; err = socket_create (server, SOCK_STREAM, 0, &file); if (err) error (1, err, "could not create socket"); #endif amount = 0; err = socket_send (sock1, MACH_PORT_NULL /* address */, 0 /* flags */, &c, sizeof (c), &file, MACH_MSG_TYPE_MOVE_SEND, 1, NULL /* control */, 0 /* len */, &amount); if (err) error (1, err, "socket_send"); dlen = sizeof (data); err = socket_recv (sock2, &aport, 0 /* flags */, &data, &dlen, &ports, &nports, &cdata, &clen, &flags, amount); if (err) error (1, err, "socket_recv"); return 0; }