Package: libc6 Version: 2.13-38+deb7u1 As part of trying to determine the error behaviour of if_nametoindex, I wrote and ran the attached test program. I discovered by looking at the strace of a test run that if_nametoindex doesn't always properly check the errno values from its system calls.
To reproduce: * Compile the attached test program cc -Wall if-nametoindex-test.c -o if-nametoindex-test * Run it in a way which will make it fail strace sh -c 'ulimit -n 4; exec ./t x * Observe the strace output. In my setup I see this: open("/dev/null", O_RDONLY) = 3 access("/proc/net", R_OK) = 0 access("/proc/net/unix", R_OK) = 0 socket(PF_FILE, SOCK_DGRAM|SOCK_CLOEXEC, 0) = -1 EMFILE (Too many open files) socket(PF_INET, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_IP) = -1 EMFILE (Too many open files) access("/proc/net/if_inet6", R_OK) = 0 socket(PF_INET6, SOCK_DGRAM|SOCK_CLOEXEC, IPPROTO_IP) = -1 EMFILE (Too many open files) access("/proc/net/ax25", R_OK) = -1 ENOENT (No such file or directory) access("/proc/net/nr", R_OK) = -1 ENOENT (No such file or directory) access("/proc/net/rose", R_OK) = -1 ENOENT (No such file or directory) access("/proc/net/ipx", R_OK) = -1 ENOENT (No such file or directory) access("/proc/net/appletalk", R_OK) = -1 ENOENT (No such file or directory) access("/proc/sys/net/econet", R_OK) = -1 ENOENT (No such file or directory) access("/proc/sys/net/ash", R_OK) = -1 ENOENT (No such file or directory) access("/proc/net/x25", R_OK) = -1 ENOENT (No such file or directory) write(2, "got 0, No such file or directory"..., 33got 0, No such file or directory ) = 33 I think if_nametoindex should have immediately stopped when it got EMFILE, and returned to the caller with errno still set to EMFILE. It's also far from clear that ENOENT is the right return value to provide if the protocol type walk falls off the end. ENXIO would seem better. But I haven't looked at the glibc source code to see exactly what code I'm exercising here. Ian.
#include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <net/if.h> #include <stdio.h> #include <errno.h> #include <string.h> #include <unistd.h> #include <sys/fcntl.h> #include <assert.h> int main(int argc, char **argv) { int fd = open("/dev/null",O_RDONLY); assert(fd>=0); errno = 0; int x = if_nametoindex(argv[1]); fprintf(stderr, "got %d, %s\n", x, strerror(errno)); return 0; }