From cf4afcb860df100cafbe0d036ae5b3acf267aa50 Mon Sep 17 00:00:00 2001 From: Tyler Hicks Date: Mon, 2 Mar 2015 09:54:57 -0600 Subject: [PATCH] parser: Fix return value of dirat_for_each() Seth pointed out that dirat_for_each() didn't correctly handle the return value from readdir_r(). On error, it directly returns a positive errno value. This would have resulted in that positive errno value being returned, with an undefined errno value set, from dirat_for_each(). However, the dirat_for_each() documentation states that -1 is returned, with errno set, on error. This patch results in readdir_r()'s return value being handled appropriately. In addition, it ensures that 0 is always returned on success. Signed-off-by: Tyler Hicks Reported-by: Seth Arnold Acked-by: Steve Beattie --- parser/lib.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/parser/lib.c b/parser/lib.c index c3657a89a..85e39e066 100644 --- a/parser/lib.c +++ b/parser/lib.c @@ -62,9 +62,9 @@ int dirat_for_each(DIR *dir, const char *name, void *data, int (* cb)(DIR *, const char *, struct stat *, void *)) { - struct dirent *dirent = NULL, *ent; + struct dirent *dirent = NULL; DIR *d = NULL; - int error = 0; + int error; if (!cb || (!dir && !name)) { errno = EINVAL; @@ -102,11 +102,19 @@ int dirat_for_each(DIR *dir, const char *name, void *data, d = dir; } - for (error = readdir_r(d, dirent, &ent); - error == 0 && ent != NULL; - error = readdir_r(d, dirent, &ent)) { + for (;;) { + struct dirent *ent; struct stat my_stat; + error = readdir_r(d, dirent, &ent); + if (error) { + PDEBUG("readdir_r failed"); + errno = error; /* readdir_r directly returns an errno */ + goto fail; + } else if (!ent) { + break; + } + if (strcmp(ent->d_name, ".") == 0 || strcmp(ent->d_name, "..") == 0) continue; @@ -126,7 +134,7 @@ int dirat_for_each(DIR *dir, const char *name, void *data, closedir(d); free(dirent); - return error; + return 0; fail: error = errno;