diff options
Diffstat (limited to 'sysdeps/unix')
-rw-r--r-- | sysdeps/unix/sysv/linux/if_index.c | 107 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sparc/sparc32/Makefile | 2 | ||||
-rw-r--r-- | sysdeps/unix/sysv/linux/sys/mount.h | 22 |
3 files changed, 84 insertions, 47 deletions
diff --git a/sysdeps/unix/sysv/linux/if_index.c b/sysdeps/unix/sysv/linux/if_index.c index 615a81d14a..7d7fc02717 100644 --- a/sysdeps/unix/sysv/linux/if_index.c +++ b/sysdeps/unix/sysv/linux/if_index.c @@ -113,62 +113,85 @@ if_nameindex (void) int fd = opensock (); struct ifconf ifc; unsigned int rq_ifs = 4, nifs, i; + int rq_len; struct if_nameindex *idx = NULL; +#ifdef SIOCGIFCOUNT + static int siocgifcount_works = 1; +#endif if (fd < 0) return NULL; +#ifdef SIOCGIFCOUNT + /* We may be able to find out how many interfaces really exist, rather + than guessing. This ioctl is not present in kernels before version + 2.1.50. */ + if (siocgifcount_works) + { + int serrno = errno; + + if (ioctl (fd, SIOCGIFCOUNT, &nifs) < 0) + { + if (errno == EINVAL) + { + siocgifcount_works = 0; + __set_errno (serrno); + } + } + else + rq_ifs = nifs + 1; + } +#endif + ifc.ifc_buf = NULL; /* Read all the interfaces out of the kernel. */ do { - rq_ifs *= 2; - ifc.ifc_len = rq_ifs * sizeof (struct ifreq); - ifc.ifc_buf = realloc (ifc.ifc_buf, ifc.ifc_len); - if (ifc.ifc_buf == NULL) + rq_len = ifc.ifc_len = rq_ifs * sizeof (struct ifreq); + ifc.ifc_buf = alloca (ifc.ifc_len); + if ((ifc.ifc_buf == NULL) || (ioctl (fd, SIOCGIFCONF, &ifc) < 0)) { - close(fd); + close (fd); return NULL; } - if (ioctl (fd, SIOCGIFCONF, &ifc) < 0) - goto jump; + rq_ifs *= 2; } - while ((unsigned int) ifc.ifc_len == (rq_ifs * sizeof (struct ifreq))); + while (ifc.ifc_len == rq_len); nifs = ifc.ifc_len / sizeof (struct ifreq); - ifc.ifc_buf = realloc (ifc.ifc_buf, ifc.ifc_len); - idx = malloc ((nifs+1) * sizeof (struct if_nameindex)); + idx = malloc ((nifs + 1) * sizeof (struct if_nameindex)); if (idx == NULL) - goto jump; + { + close (fd); + return NULL; + } for (i = 0; i < nifs; ++i) { struct ifreq *ifr = &ifc.ifc_req[i]; - if ((idx[i].if_name = malloc (strlen (ifr->ifr_name)+1)) == NULL) - { - free (idx); - idx = NULL; - goto jump; - } - strcpy (idx[i].if_name, ifr->ifr_name); - if (ioctl (fd, SIOGIFINDEX, ifr) < 0) + idx[i].if_name = __strdup (ifr->ifr_name); + if (idx[i].if_name == NULL + || ioctl (fd, SIOGIFINDEX, ifr) < 0) { int saved_errno = errno; + unsigned int j; + + for (j = 0; j < i; ++j) + free (idx[j].if_name); free (idx); - idx = NULL; + close (fd); if (saved_errno == EINVAL) __set_errno (ENOSYS); - goto jump; + return NULL; } idx[i].if_index = ifr->ifr_ifindex; } + idx[i].if_index = 0; idx[i].if_name = NULL; -jump: - free (ifc.ifc_buf); close (fd); return idx; #endif @@ -181,10 +204,46 @@ if_indextoname (unsigned int ifindex, char *ifname) __set_errno (ENOSYS); return NULL; #else - struct if_nameindex *idx = if_nameindex (); + struct if_nameindex *idx; struct if_nameindex *p; char *result = NULL; +#ifdef SIOGIFNAME + /* We may be able to do the conversion directly, rather than searching a + list. This ioctl is not present in kernels before version 2.1.50. */ + struct ifreq ifr; + int fd; + static int siogifname_works = 1; + + if (siogifname_works) + { + int serrno = errno; + + fd = opensock (); + + if (fd < 0) + return NULL; + + ifr.ifr_ifindex = ifindex; + if (ioctl (fd, SIOGIFNAME, &ifr) < 0) + { + if (errno == EINVAL) + siogifname_works = 0; /* Don't make the same mistake twice. */ + } + else + { + close (fd); + return strncpy (ifname, ifr.ifr_name, IFNAMSIZ); + } + + close (fd); + + __set_errno (serrno); + } +#endif + + idx = if_nameindex (); + if (idx != NULL) { for (p = idx; p->if_index || p->if_name; ++p) diff --git a/sysdeps/unix/sysv/linux/sparc/sparc32/Makefile b/sysdeps/unix/sysv/linux/sparc/sparc32/Makefile index 4cbd3bd004..01a0e8310f 100644 --- a/sysdeps/unix/sysv/linux/sparc/sparc32/Makefile +++ b/sysdeps/unix/sysv/linux/sparc/sparc32/Makefile @@ -3,7 +3,7 @@ sysdep_routines += __sigtrampoline endif asm-CPPFLAGS=-D__ASSEMBLY__ -as-FLAGS-.so=-fPIC +ASFLAGS-.os=-fPIC # When I get this to work, this is the right thing ifeq ($(subdir),elf) diff --git a/sysdeps/unix/sysv/linux/sys/mount.h b/sysdeps/unix/sysv/linux/sys/mount.h index 08a2e3158f..f7d45704d2 100644 --- a/sysdeps/unix/sysv/linux/sys/mount.h +++ b/sysdeps/unix/sysv/linux/sys/mount.h @@ -57,28 +57,6 @@ __BEGIN_DECLS #define MS_MGC_MSK 0xffff0000 /* Magic flag number mask */ -/* Note that read-only etc flags are inode-specific: setting some - file-system flags just means all the inodes inherit those flags by - default. It might be possible to override it selectively if you - really wanted to with some ioctl() that is not currently - implemented. - - Exception: MS_RDONLY is always applied to the entire file system. */ -#define IS_RDONLY(inode) \ - (((inode)->i_sb) && ((inode)->i_sb->s_flags & MS_RDONLY)) -#define DO_UPDATE_ATIME(inode) \ - (!((inode)->i_flags & MS_NOATIME) && !IS_RDONLY (inode)) -#define IS_NOSUID(inode) ((inode)->i_flags & MS_NOSUID) -#define IS_NODEV(inode) ((inode)->i_flags & MS_NODEV) -#define IS_NOEXEC(inode) ((inode)->i_flags & MS_NOEXEC) -#define IS_SYNC(inode) ((inode)->i_flags & MS_SYNCHRONOUS) -#define IS_MANDLOCK(inode) ((inode)->i_flags & MS_MANDLOCK) - -#define IS_WRITABLE(inode) ((inode)->i_flags & S_WRITE) -#define IS_APPEND(inode) ((inode)->i_flags & S_APPEND) -#define IS_IMMUTABLE(inode) ((inode)->i_flags & S_IMMUTABLE) - - /* The read-only stuff doesn't really belong here, but any other place is probably as bad and I don't want to create yet another include file. */ |