Hi, As a follow up on the latest IRC discussion, and after reading the recent rpc.mdwn, I still have some questions. Let's take a look at the function setsocketopt.
Start with glibc: locate setsockopt.c results in two hits. eglibc-2.13/socket/setsockopt.c eglibc-2.13/sysdeps/mach/hurd/setsockopt.c The first is just stub code while the second is becoming RPC code #include <errno.h> #include <sys/socket.h> #include <hurd.h> #include <hurd/socket.h> #include <hurd/fd.h> /* Set socket FD's option OPTNAME at protocol level LEVEL to *OPTVAL (which is OPTLEN bytes long). Returns 0 on success, -1 for errors. */ int __setsockopt (int fd, int level, int optname, const void *optval, socklen_t optlen) { error_t err = HURD_DPORT_USE (fd, __socket_setopt (port, level, optname, optval, optlen)); if (err) return __hurd_dfail (fd, err); return 0; } weak_alias (__setsockopt, setsockopt) Q1: Where to find that the second code is uesed when building eglibc: Is the the presence of the second that makes this defining that function? And if there were no mach/hurd/*.c code, the stub would define it? Q2: The build log does not show any traces of setsockopt.c being compiled?? The generated code seems to be built up with the HURD_DPORT_USE macro and __hurd_dfail in /usr/include/hurd/fd.h Still puzzling is the build log: for call in ... socket_getopt socket_setopt socket_send ...; do \ echo "weak_alias (__$call, $call)" >> /home/srs/DEBs/SRC/eglibc/eglibc-2.13/build-tree/hurd-i386-libc/hurd/tmp_${call}.c; >> \ /bin/bash ../scripts/move-if-change /home/srs/DEBs/SRC/eglibc/eglibc-2.13/build-tree/hurd-i386-libc/hurd/tmp_${call}.c \ /home/srs/DEBs/SRC/eglibc/eglibc-2.13/build-tree/hurd-i386-libc/hurd/RPC_${call}.c; \ done Q3: I cannot see where the code is included/the macros expanded, going from setsockopt.c to RPC_socket_setopt.c?? What am I missing? There is some mig stuff before the above in the build log: echo '#include <mach/mach.defs>' | \ CC='gcc-4.7' CPP='gcc-4.7 -E -x c' mig - /dev/null -prefix __ \ -DMACH_IPC_COMPAT=0 -DSTANDALONE -DTypeCheck=0 -I../include -I/home/srs/DEBs/SRC/eglibc/eglibc-2.13/build-tree/hurd-i386- libc/mach -I/home/srs/DEBs/SRC/eglibc/eglibc-2.13/build-tree/hurd-i386-libc -I../sysdeps/i386/elf -I../libpthread/sysdeps/mach/hurd/i386 -I../libpthread/sysdeps/ia32 -I../sysdeps/mach/hurd/i386 -I../libpthread/sysdeps/mach/hurd -I../libpthread/sysdeps/hurd -I../sysdeps/ma ch/hurd -I../sysdeps/gnu -I../sysdeps/unix/bsd/bsd4.4 -I../sysdeps/unix/mman -I../sysdeps/mach/i386 -I../libpthread/sysdeps/mach -I../sy sdeps/mach -I../sysdeps/i386/i486 -I../sysdeps/i386/fpu -I../libpthread/sysdeps/i386 -I../sysdeps/i386 -I../sysdeps/wordsize-32 -I../sys deps/ieee754/ldbl-96 -I../sysdeps/ieee754/dbl-64 -I../sysdeps/ieee754/flt-32 -I../sysdeps/unix/bsd -I../sysdeps/unix/common -I../sysdeps /unix/inet -I../sysdeps/unix -I../sysdeps/posix -I../libpthread/sysdeps/posix -I../sysdeps/ieee754 -I../sysdeps/generic/elf -I../sysdeps /generic -I../libpthread -I../hurd -I/home/srs/DEBs/SRC/eglibc/eglibc-2.13/build-tree/hurd-i386-libc/hurd/ -I../mach -I/home/srs/DEBs/SR C/eglibc/eglibc-2.13/build-tree/hurd-i386-libc/mach/ -I.. -I../libio -I. -I../libpthread/include -Dvm_map=vm_map_rpc -Dvm_allocate=vm_a llocate_rpc -Dvm_deallocate=vm_deallocate_rpc -Dtask_create=task_create_rpc -Dtask_terminate=task_terminate_rpc -Dtask_suspend=task_susp end_rpc -Dtask_set_special_port=task_set_special_port_rpc -Dmach_port_allocate=mach_port_allocate_rpc -Dmach_port_deallocate=mach_port_d eallocate_rpc -Dmach_port_insert_right=mach_port_insert_right_rpc -Dmach_port_allocate_name=mach_port_allocate_name_rpc -Dthread_depress _abort=thread_depress_abort_rpc -subrprefix __ \ -i /home/srs/DEBs/SRC/eglibc/eglibc-2.13/build-tree/hurd-i386-libc/mach/tmp_ -server /dev/null -user /dev/null -header /dev/null Q4: Is that where the build-tree/hurd-i386-libc/mach/tmp_*.c functions are created? Then looking at the generated RPC_socket_setopt.c file it seems that mach is invoked in the generated code: __mach_msg(...) That was where I lost track of the function. According to the IRC discussion this is taken up again in the pflocal hurd server via: S_socket_setopt() hurd-20120710/pfinet/socket-ops.c:S_socket_setopt (struct sock_user *user, hurd-20120710/pflocal/socket.c:S_socket_setopt (struct sock_user *user, Now we have two definitions of S_socket_setopt Q5: Which one is used? And from the build of hurd: hurd-20120710/build/pflocal/socketServer.c: mig_external kern_return_t S_socket_setopt but there is also: mig_internal void _Xsocket_setopt Q6: Where do the _X and S_ definitions come into play? We also have: hurd-20120710/build/hurd/socket.msgids:socket 26000 socket_setopt 13 26013 26113 hurd-20120710/build/hurd/hurd.msgids:socket 26000 socket_setopt 13 26013 26113 The socket_setopt function is defined in hurd-20120710/hurd/socket.defs: /* Set a socket option. */ routine socket_setopt ( sock: socket_t; level: int; option: int; optval: data_t SCP); Note: the gnumach and hurd (incomplete) reference manuals does _not_ reveal this information (at least not easily). The real code used seems to be in: error_t S_socket_setopt (struct sock_user *user, int level, int opt, char *value, size_t value_len) { int ret = 0; if (!user) return EOPNOTSUPP; mutex_lock (&user->sock->lock); switch (level) { default: ret = ENOPROTOOPT; break; } mutex_unlock (&user->sock->lock); return ret; } Q8: How can I modify it to support SO_REUSEADDR option? case SOL_SOCKET: switch (opt) { case SO_REUSEADDR: Q9: Where to find what to add here? } Q10: If gnumach is kernel space and hurd user space, what is the eglibc code? Is this really a client-server implementation? Don't say that the eglibc-gnumach-hurd combination is simple, then you are not serious :( And one can understand why people have problems contributing to such a complicated software structure. Q11: Is the complexity mainly due to that most things should happen in userspace, or is there any other reason? If somebody can explain this properly to me, I will write it down and add to the existing (incomplete) documentation. Source code is OK, but you should be able to know where to look too, especially when there are three big chunks of code to go though: eglibc, gnumach and hurd ;)