Change the interface of getlogin_r to return an int. The former

interface was based on a draft version of POSIX whereas the final
(1996) version of POSIX specified that the error is returned.

While I'm here, fix getlogin_r so that it works for more than just
the first time it's called.

Reviewed by:	wes, wollman (man page)
This commit is contained in:
Daniel Eischen 2001-01-01 13:29:19 +00:00
parent 924836d50e
commit fc1d3c6dfb
2 changed files with 68 additions and 22 deletions

View File

@ -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>
#include <libc_private.h>
#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() */
char *
getlogin()
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);
}

View File

@ -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 .