aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Johnson <davijoh3@cisco.com>2011-10-04 15:03:49 -0700
committerStephen Hemminger <shemminger@vyatta.com>2011-10-04 15:03:49 -0700
commit4decdea3afe1f90f8335ce8156d678aee4582141 (patch)
tree012cb76bc908e8daf619c700c881db02479ec967
parent7fc99b7f0f3a5e022a09b6525ef18c58ec25f66d (diff)
downloadandroid_external_brctl-4decdea3afe1f90f8335ce8156d678aee4582141.tar.gz
android_external_brctl-4decdea3afe1f90f8335ce8156d678aee4582141.tar.bz2
android_external_brctl-4decdea3afe1f90f8335ce8156d678aee4582141.zip
bug with older glibc: "brctl show" shows nothing
Older glibc has a bug in scandir() where if the last call to filter is a failure and filter sets errno, scandir() will fail and return that errno to the caller. If running "brctl show" on a system where the last (sorted) directory in /sys/class/net is not a bridge, isbridge() will leave errno set to ENOENT and trigger this bug in glibc. Attached patch against bridge-utils v1.5 saves/restores errno in isbridge() to workaround this bug in older glibc.
-rw-r--r--libbridge/libbridge_init.c10
1 files changed, 9 insertions, 1 deletions
diff --git a/libbridge/libbridge_init.c b/libbridge/libbridge_init.c
index 177a391..f3a551e 100644
--- a/libbridge/libbridge_init.c
+++ b/libbridge/libbridge_init.c
@@ -48,6 +48,7 @@ static int isbridge(const struct dirent *entry)
{
char path[SYSFS_PATH_MAX];
struct stat st;
+ int ret, saved_errno;
if (entry->d_name[0] == '.'
&& (entry->d_name[1] == '\0'
@@ -57,7 +58,14 @@ static int isbridge(const struct dirent *entry)
snprintf(path, SYSFS_PATH_MAX,
SYSFS_CLASS_NET "%s/bridge", entry->d_name);
- return stat(path, &st) == 0 && S_ISDIR(st.st_mode);
+
+ /* Workaround old glibc breakage.
+ If errno is set, then it fails scandir! */
+ saved_errno = errno;
+ ret = (stat(path, &st) == 0 && S_ISDIR(st.st_mode));
+ errno = saved_errno;
+
+ return ret;
}
/*