summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Eggert <eggert@cs.ucla.edu>2017-07-10 11:56:48 -0700
committerPaul Eggert <eggert@cs.ucla.edu>2017-07-10 12:02:09 -0700
commit24605b2f03bfa8367a9149835c687c9073aacc2c (patch)
tree55ef05fadaeaec93569187156a7db516a362717c
parent8cb994d1fc4a957359780e1a4187b4f250c1cea5 (diff)
downloadgnulib-24605b2f03bfa8367a9149835c687c9073aacc2c.tar.gz
getlogin: don’t assume one name per uid
Problem reported by Wolfgang F. Muthmann (Bug#27640). * modules/getlogin-tests (Files): Add tests/test-getlogin_r.c. (ttyname): Remove test. * modules/getlogin_r-tests (ttyname): Remove test. * tests/test-getlogin.c: Replace this near-clone of test-getlogin_r.c with ‘#define TEST_LOGIN’ followed by ‘#include "test-getlogin_r.c"’. * tests/test-getlogin_r.c: If TEST_GETLOGIN is defined, test getlogin rather than getlogin_r. This avoids code duplication. (main): Use isatty and fstat rather than ttyname and stat. Use getpwnam instead of getpwuid, to be portable to test platforms that have multiple login names for the same uid.
-rw-r--r--ChangeLog15
-rw-r--r--modules/getlogin-tests2
-rw-r--r--modules/getlogin_r-tests1
-rw-r--r--tests/test-getlogin.c112
-rw-r--r--tests/test-getlogin_r.c35
5 files changed, 39 insertions, 126 deletions
diff --git a/ChangeLog b/ChangeLog
index af99a9cbbe..e5bfb7e4eb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,18 @@
+2017-07-10 Paul Eggert <eggert@cs.ucla.edu>
+
+ getlogin: don’t assume one name per uid
+ Problem reported by Wolfgang F. Muthmann (Bug#27640).
+ * modules/getlogin-tests (Files): Add tests/test-getlogin_r.c.
+ (ttyname): Remove test.
+ * modules/getlogin_r-tests (ttyname): Remove test.
+ * tests/test-getlogin.c: Replace this near-clone of test-getlogin_r.c
+ with ‘#define TEST_LOGIN’ followed by ‘#include "test-getlogin_r.c"’.
+ * tests/test-getlogin_r.c: If TEST_GETLOGIN is defined, test
+ getlogin rather than getlogin_r. This avoids code duplication.
+ (main): Use isatty and fstat rather than ttyname and stat.
+ Use getpwnam instead of getpwuid, to be portable to test platforms
+ that have multiple login names for the same uid.
+
2017-07-10 Tim Rühsen <tim.ruehsen@gmx.de>
Bruno Haible <bruno@clisp.org>
diff --git a/modules/getlogin-tests b/modules/getlogin-tests
index c8cdb05eb0..d7d6aeafa8 100644
--- a/modules/getlogin-tests
+++ b/modules/getlogin-tests
@@ -1,12 +1,12 @@
Files:
tests/test-getlogin.c
+tests/test-getlogin_r.c
tests/signature.h
tests/macros.h
Depends-on:
configure.ac:
-AC_CHECK_FUNCS_ONCE([ttyname])
Makefile.am:
TESTS += test-getlogin
diff --git a/modules/getlogin_r-tests b/modules/getlogin_r-tests
index 868b1b6f73..845658fdc2 100644
--- a/modules/getlogin_r-tests
+++ b/modules/getlogin_r-tests
@@ -6,7 +6,6 @@ tests/macros.h
Depends-on:
configure.ac:
-AC_CHECK_FUNCS_ONCE([ttyname])
Makefile.am:
TESTS += test-getlogin_r
diff --git a/tests/test-getlogin.c b/tests/test-getlogin.c
index 86b2a9ef1f..6a6d26964b 100644
--- a/tests/test-getlogin.c
+++ b/tests/test-getlogin.c
@@ -1,110 +1,2 @@
-/* Test of getting user name.
- Copyright (C) 2010-2017 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see <http://www.gnu.org/licenses/>. */
-
-/* Written by Bruno Haible <bruno@clisp.org>, 2010. */
-
-#include <config.h>
-
-#include <unistd.h>
-
-#include "signature.h"
-SIGNATURE_CHECK (getlogin, char *, (void));
-
-#include <errno.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-#if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
-# include <pwd.h>
-#endif
-
-#include <sys/stat.h>
-#include <sys/types.h>
-
-#include "macros.h"
-
-int
-main (void)
-{
- char *buf;
-
- /* Test value. */
- buf = getlogin ();
- if (buf == NULL)
- {
- if (errno == ENOENT)
- {
- /* This can happen on GNU/Linux. */
- fprintf (stderr, "Skipping test: no entry in utmp file.\n");
- return 77;
- }
-
- /* getlogin() fails when stdin is not connected to a tty. */
- ASSERT (errno == ENOTTY
- || errno == EINVAL /* seen on Linux/SPARC */
- || errno == ENXIO
- );
-#if !defined __hpux /* On HP-UX 11.11 it fails anyway. */
- ASSERT (! isatty (0));
-#endif
- fprintf (stderr, "Skipping test: stdin is not a tty.\n");
- return 77;
- }
-
- /* Compare against the value from the environment. */
-#if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
- /* Unix platform */
- {
-# if HAVE_TTYNAME
- const char *tty;
- struct stat stat_buf;
- struct passwd *pwd;
-
- tty = ttyname (STDIN_FILENO);
- if (tty == NULL)
- {
- fprintf (stderr, "Skipping test: stdin is not a tty.\n");
- return 77;
- }
-
- ASSERT (stat (tty, &stat_buf) == 0);
-
- pwd = getpwuid (stat_buf.st_uid);
- if (! pwd)
- {
- long int uid = stat_buf.st_uid;
- fprintf (stderr, "Skipping test: no name found for uid %ld\n", uid);
- return 77;
- }
-
- ASSERT (strcmp (pwd->pw_name, buf) == 0);
-# endif
- }
-#endif
-#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
- /* Native Windows platform.
- Note: This test would fail on Cygwin in an ssh session, because sshd
- sets USERNAME=SYSTEM. */
- {
- const char *name = getenv ("USERNAME");
- if (name != NULL && name[0] != '\0')
- ASSERT (strcmp (buf, name) == 0);
- }
-#endif
-
- return 0;
-}
+#define TEST_GETLOGIN
+#include "test-getlogin_r.c"
diff --git a/tests/test-getlogin_r.c b/tests/test-getlogin_r.c
index f7cdc3a7d3..0a7e105dd3 100644
--- a/tests/test-getlogin_r.c
+++ b/tests/test-getlogin_r.c
@@ -21,7 +21,11 @@
#include <unistd.h>
#include "signature.h"
+#ifdef TEST_GETLOGIN
+SIGNATURE_CHECK (getlogin, char *, (void));
+#else
SIGNATURE_CHECK (getlogin_r, int, (char *, size_t));
+#endif
#include <errno.h>
#include <stdio.h>
@@ -40,11 +44,17 @@ SIGNATURE_CHECK (getlogin_r, int, (char *, size_t));
int
main (void)
{
+ /* Test value. */
+#ifdef TEST_GETLOGIN
+ char *buf = getlogin ();
+ int err = buf ? 0 : errno;
+ ASSERT (buf || err);
+#else
/* Test with a large enough buffer. */
char buf[1024];
- int err;
+ int err = getlogin_r (buf, sizeof buf);
+#endif
- err = getlogin_r (buf, sizeof (buf));
if (err != 0)
{
if (err == ENOENT)
@@ -54,7 +64,7 @@ main (void)
return 77;
}
- /* getlogin_r() fails when stdin is not connected to a tty. */
+ /* It fails when stdin is not connected to a tty. */
ASSERT (err == ENOTTY
|| err == EINVAL /* seen on Linux/SPARC */
|| err == ENXIO
@@ -70,30 +80,25 @@ main (void)
#if !((defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__)
/* Unix platform */
{
-# if HAVE_TTYNAME
- const char *tty;
struct stat stat_buf;
struct passwd *pwd;
- tty = ttyname (STDIN_FILENO);
- if (tty == NULL)
+ if (!isatty (STDIN_FILENO))
{
fprintf (stderr, "Skipping test: stdin is not a tty.\n");
return 77;
}
- ASSERT (stat (tty, &stat_buf) == 0);
+ ASSERT (fstat (STDIN_FILENO, &stat_buf) == 0);
- pwd = getpwuid (stat_buf.st_uid);
+ pwd = getpwnam (buf);
if (! pwd)
{
- fprintf (stderr, "Skipping test: no name found for uid %d\n",
- stat_buf.st_uid);
- return 77;
+ fprintf (stderr, "Skipping test: %s: no such user\n", buf);
+ return 77;
}
- ASSERT (strcmp (pwd->pw_name, buf) == 0);
-# endif
+ ASSERT (pwd->pw_uid == stat_buf.st_uid);
}
#endif
#if (defined _WIN32 || defined __WIN32__) && !defined __CYGWIN__
@@ -107,6 +112,7 @@ main (void)
}
#endif
+#ifndef TEST_GETLOGIN
/* Test with a small buffer. */
{
char smallbuf[1024];
@@ -130,6 +136,7 @@ main (void)
ASSERT (getlogin_r (hugebuf, sizeof (hugebuf)) == 0);
ASSERT (strcmp (hugebuf, buf) == 0);
}
+#endif
return 0;
}