don't set errno or return an error when getspnam[_r] finds no entry
authorRich Felker <dalias@aerifal.cx>
Fri, 28 Dec 2018 21:50:07 +0000 (16:50 -0500)
committerRich Felker <dalias@aerifal.cx>
Fri, 28 Dec 2018 21:50:07 +0000 (16:50 -0500)
this case is specified as success with a null result, rather than an
error, and errno is not to be set on success.

src/passwd/getspnam.c
src/passwd/getspnam_r.c

index 041f896525f1e68f6fbf8076a3bb42a154f0752b..709b526dc503abb5ea8ab3cc5ec405196a6d7c1a 100644 (file)
@@ -8,10 +8,11 @@ struct spwd *getspnam(const char *name)
        static char *line;
        struct spwd *res;
        int e;
+       int orig_errno = errno;
 
        if (!line) line = malloc(LINE_LIM);
        if (!line) return 0;
        e = getspnam_r(name, &sp, line, LINE_LIM, &res);
-       if (e) errno = e;
+       errno = e ? e : orig_errno;
        return res;
 }
index 541206fa14db8dcea55f26dc24e070c88583ac72..1b95dbb645aca9baf94983d05dd672fdb8deef3e 100644 (file)
@@ -67,6 +67,7 @@ int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct
        size_t k, l = strlen(name);
        int skip = 0;
        int cs;
+       int orig_errno = errno;
 
        *res = 0;
 
@@ -94,7 +95,11 @@ int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct
                }
        } else {
                f = fopen("/etc/shadow", "rbe");
-               if (!f) return errno;
+               if (!f) {
+                       if (errno != ENOENT && errno != ENOTDIR)
+                               return errno;
+                       return 0;
+               }
        }
 
        pthread_cleanup_push(cleanup, f);
@@ -113,6 +118,6 @@ int getspnam_r(const char *name, struct spwd *sp, char *buf, size_t size, struct
                break;
        }
        pthread_cleanup_pop(1);
-       if (rv) errno = rv;
+       errno = rv ? rv : orig_errno;
        return rv;
 }