diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/libc/gen/getlogin.c | 67 | ||||
-rw-r--r-- | lib/libc/sys/getlogin.2 | 23 |
2 files changed, 68 insertions, 22 deletions
diff --git a/lib/libc/gen/getlogin.c b/lib/libc/gen/getlogin.c index 044689d..5adc46c 100644 --- a/lib/libc/gen/getlogin.c +++ b/lib/libc/gen/getlogin.c @@ -38,43 +38,76 @@ static char sccsid[] = "@(#)getlogin.c 8.1 (Berkeley) 6/4/93"; #endif /* LIBC_SCCS and not lint */ #include <sys/param.h> +#include <errno.h> #include <pwd.h> #include <utmp.h> #include <stdio.h> #include <string.h> #include <unistd.h> -int _logname_valid; /* known to setlogin() */ +#include <libc_private.h> -char * -getlogin() +#ifndef _THREAD_SAFE +#define THREAD_LOCK() +#define THREAD_UNLOCK() +#else +#include <pthread.h> +#include "pthread_private.h" +static struct pthread_mutex logname_lock = PTHREAD_MUTEX_STATIC_INITIALIZER; +static pthread_mutex_t logname_mutex = &logname_lock; +#define THREAD_LOCK() if (__isthreaded) pthread_mutex_lock(&logname_mutex) +#define THREAD_UNLOCK() if (__isthreaded) pthread_mutex_unlock(&logname_mutex) +#endif /* _THREAD_SAFE */ + +int _logname_valid; /* known to setlogin() */ + +static char * +getlogin_basic(int *status) { static char logname[MAXLOGNAME]; if (_logname_valid == 0) { #ifdef __NETBSD_SYSCALLS - if (__getlogin(logname, sizeof(logname) - 1) < 0) + if (__getlogin(logname, sizeof(logname) - 1) < 0) { #else - if (_getlogin(logname, sizeof(logname)) < 0) + if (_getlogin(logname, sizeof(logname)) < 0) { #endif - return ((char *)NULL); + *status = errno; + return (NULL); + } _logname_valid = 1; } - return (*logname ? logname : (char *)NULL); + *status = 0; + return (*logname ? logname : NULL); } - char * +getlogin(void) +{ + char *result; + int status; + + THREAD_LOCK(); + result = getlogin_basic(&status); + THREAD_UNLOCK(); + return (result); +} + +int getlogin_r(char *logname, int namelen) { - if (_logname_valid == 0) { -#ifdef __NETBSD_SYSCALLS - if (__getlogin(logname, namelen - 1) < 0) -#else - if (_getlogin(logname, namelen) < 0) -#endif - return ((char *)NULL); - _logname_valid = 1; + char *result; + int len; + int status; + + THREAD_LOCK(); + result = getlogin_basic(&status); + if (status == 0) { + if ((len = strlen(result) + 1) > namelen) + status = ERANGE; + else + strncpy(logname, result, len); } - return (*logname ? logname : (char *)NULL); + THREAD_UNLOCK(); + return (status); } diff --git a/lib/libc/sys/getlogin.2 b/lib/libc/sys/getlogin.2 index cd12b3c..023ea1d 100644 --- a/lib/libc/sys/getlogin.2 +++ b/lib/libc/sys/getlogin.2 @@ -47,7 +47,7 @@ .Ft char * .Fn getlogin void .Fd #include <sys/param.h> -.Ft char * +.Ft int .Fn getlogin_r "char *name" "int len" .Ft int .Fn setlogin "const char *name" @@ -132,12 +132,12 @@ precautions to prevent security violations. .Sh RETURN VALUES If a call to .Fn getlogin -succeeds, it returns a pointer to a null-terminated string in a static buffer. -.Fn getlogin_r -returns a pointer to the buffer passed in by the caller on success. -Both return +succeeds, it returns a pointer to a null-terminated string in a static buffer, +or .Dv NULL if the name has not been set. +.Fn getlogin_r +returns zero if successful, or the error number upon failure. .Pp If a call to .Fn setlogin @@ -166,6 +166,8 @@ Login names are limited to characters, currently 17 including null. .It Bq Er EPERM The caller tried to set the login name and was not the super-user. +.It Bq Er ERANGE +The size of the buffer is smaller than the result to be returned. .El .Sh SEE ALSO .Xr setsid 2 , @@ -186,3 +188,14 @@ The .Fn getlogin function first appeared in .Bx 4.4 . +The return value of +.Fn getlogin_r +was changed from earlier versions of FreeBSD to be conformant with +.St -iso9945-1 . +.Sh STANDARDS +.Fn getlogin +and +.Fn getlogin_r +conform to +.St -iso9945-1 . + |