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;
}

Reply via email to