-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Fix Linux getlogin{_r,} implementation
The old implementation uses fd 0 to determine the login TTY. This was needed because using /dev/tty it is not possible to deduce the login TTY. For some time now there is the pseudo-file /proc/self/loginuid which directly helps us to find the user. Prefer using this file. It also works if stdin is closed, redirected, or re-opened.
- Loading branch information
Ulrich Drepper
committed
Mar 25, 2010
1 parent
fd8ccb0
commit c8727fa
Showing
6 changed files
with
161 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* Copyright (C) 2010 Free Software Foundation, Inc. | ||
This file is part of the GNU C Library. | ||
The GNU C Library is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU Lesser General Public | ||
License as published by the Free Software Foundation; either | ||
version 2.1 of the License, or (at your option) any later version. | ||
The GNU C Library 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 | ||
Lesser General Public License for more details. | ||
You should have received a copy of the GNU Lesser General Public | ||
License along with the GNU C Library; if not, write to the Free | ||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
02111-1307 USA. */ | ||
|
||
#include <pwd.h> | ||
#include <unistd.h> | ||
#include <not-cancel.h> | ||
|
||
#define STATIC static | ||
#define getlogin getlogin_fd0 | ||
#include <sysdeps/unix/getlogin.c> | ||
#undef getlogin | ||
|
||
|
||
/* Return the login name of the user, or NULL if it can't be determined. | ||
The returned pointer, if not NULL, is good only until the next call. */ | ||
|
||
char * | ||
getlogin (void) | ||
{ | ||
if (__getlogin_r_loginuid (name, sizeof (name)) == 0) | ||
return name; | ||
|
||
return getlogin_fd0 (); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
/* Copyright (C) 2010 Free Software Foundation, Inc. | ||
This file is part of the GNU C Library. | ||
The GNU C Library is free software; you can redistribute it and/or | ||
modify it under the terms of the GNU Lesser General Public | ||
License as published by the Free Software Foundation; either | ||
version 2.1 of the License, or (at your option) any later version. | ||
The GNU C Library 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 | ||
Lesser General Public License for more details. | ||
You should have received a copy of the GNU Lesser General Public | ||
License along with the GNU C Library; if not, write to the Free | ||
Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA | ||
02111-1307 USA. */ | ||
|
||
#include <pwd.h> | ||
#include <unistd.h> | ||
#include <not-cancel.h> | ||
|
||
#define STATIC static | ||
static int getlogin_r_fd0 (char *name, size_t namesize); | ||
#define getlogin_r getlogin_r_fd0 | ||
#include <sysdeps/unix/getlogin_r.c> | ||
#undef getlogin_r | ||
|
||
|
||
int | ||
attribute_hidden | ||
__getlogin_r_loginuid (name, namesize) | ||
char *name; | ||
size_t namesize; | ||
{ | ||
int fd = open_not_cancel_2 ("/proc/self/loginuid", O_RDONLY); | ||
if (fd == -1) | ||
return 1; | ||
|
||
ssize_t n = TEMP_FAILURE_RETRY (read_not_cancel (fd, name, namesize)); | ||
close_not_cancel_no_status (fd); | ||
|
||
uid_t uid; | ||
char *endp; | ||
if (n <= 0 | ||
|| (uid = strtoul (name, &endp, 10), endp == name || *endp != '\0')) | ||
return 1; | ||
|
||
size_t buflen = 1024; | ||
char *buf = alloca (buflen); | ||
bool use_malloc = false; | ||
struct passwd pwd; | ||
struct passwd *tpwd; | ||
int res; | ||
|
||
while ((res = __getpwuid_r (uid, &pwd, buf, buflen, &tpwd)) != 0) | ||
if (__libc_use_alloca (2 * buflen)) | ||
extend_alloca (buf, buflen, 2 * buflen); | ||
else | ||
{ | ||
buflen *= 2; | ||
char *newp = realloc (use_malloc ? buf : NULL, buflen); | ||
if (newp == NULL) | ||
{ | ||
fail: | ||
if (use_malloc) | ||
free (buf); | ||
return 1; | ||
} | ||
buf = newp; | ||
use_malloc = true; | ||
} | ||
|
||
if (tpwd == NULL) | ||
goto fail; | ||
|
||
strncpy (name, pwd.pw_name, namesize - 1); | ||
name[namesize - 1] = '\0'; | ||
|
||
if (use_malloc) | ||
free (buf); | ||
|
||
return 0; | ||
} | ||
|
||
|
||
/* Return the login name of the user, or NULL if it can't be determined. | ||
The returned pointer, if not NULL, is good only until the next call. */ | ||
|
||
int | ||
getlogin_r (name, namesize) | ||
char *name; | ||
size_t namesize; | ||
{ | ||
if (__getlogin_r_loginuid (name, namesize) == 0) | ||
return 0; | ||
|
||
return getlogin_r_fd0 (name, namesize); | ||
} | ||
libc_hidden_def (getlogin_r) |