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:
parent
924836d50e
commit
fc1d3c6dfb
@ -38,43 +38,76 @@ static char sccsid[] = "@(#)getlogin.c 8.1 (Berkeley) 6/4/93";
|
|||||||
#endif /* LIBC_SCCS and not lint */
|
#endif /* LIBC_SCCS and not lint */
|
||||||
|
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
|
#include <errno.h>
|
||||||
#include <pwd.h>
|
#include <pwd.h>
|
||||||
#include <utmp.h>
|
#include <utmp.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
int _logname_valid; /* known to setlogin() */
|
#include <libc_private.h>
|
||||||
|
|
||||||
char *
|
#ifndef _THREAD_SAFE
|
||||||
getlogin()
|
#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];
|
static char logname[MAXLOGNAME];
|
||||||
|
|
||||||
if (_logname_valid == 0) {
|
if (_logname_valid == 0) {
|
||||||
#ifdef __NETBSD_SYSCALLS
|
#ifdef __NETBSD_SYSCALLS
|
||||||
if (__getlogin(logname, sizeof(logname) - 1) < 0)
|
if (__getlogin(logname, sizeof(logname) - 1) < 0) {
|
||||||
#else
|
#else
|
||||||
if (_getlogin(logname, sizeof(logname)) < 0)
|
if (_getlogin(logname, sizeof(logname)) < 0) {
|
||||||
#endif
|
#endif
|
||||||
return ((char *)NULL);
|
*status = errno;
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
_logname_valid = 1;
|
_logname_valid = 1;
|
||||||
}
|
}
|
||||||
return (*logname ? logname : (char *)NULL);
|
*status = 0;
|
||||||
|
return (*logname ? logname : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
|
getlogin(void)
|
||||||
|
{
|
||||||
|
char *result;
|
||||||
|
int status;
|
||||||
|
|
||||||
|
THREAD_LOCK();
|
||||||
|
result = getlogin_basic(&status);
|
||||||
|
THREAD_UNLOCK();
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
getlogin_r(char *logname, int namelen)
|
getlogin_r(char *logname, int namelen)
|
||||||
{
|
{
|
||||||
if (_logname_valid == 0) {
|
char *result;
|
||||||
#ifdef __NETBSD_SYSCALLS
|
int len;
|
||||||
if (__getlogin(logname, namelen - 1) < 0)
|
int status;
|
||||||
#else
|
|
||||||
if (_getlogin(logname, namelen) < 0)
|
THREAD_LOCK();
|
||||||
#endif
|
result = getlogin_basic(&status);
|
||||||
return ((char *)NULL);
|
if (status == 0) {
|
||||||
_logname_valid = 1;
|
if ((len = strlen(result) + 1) > namelen)
|
||||||
|
status = ERANGE;
|
||||||
|
else
|
||||||
|
strncpy(logname, result, len);
|
||||||
}
|
}
|
||||||
return (*logname ? logname : (char *)NULL);
|
THREAD_UNLOCK();
|
||||||
|
return (status);
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@
|
|||||||
.Ft char *
|
.Ft char *
|
||||||
.Fn getlogin void
|
.Fn getlogin void
|
||||||
.Fd #include <sys/param.h>
|
.Fd #include <sys/param.h>
|
||||||
.Ft char *
|
.Ft int
|
||||||
.Fn getlogin_r "char *name" "int len"
|
.Fn getlogin_r "char *name" "int len"
|
||||||
.Ft int
|
.Ft int
|
||||||
.Fn setlogin "const char *name"
|
.Fn setlogin "const char *name"
|
||||||
@ -132,12 +132,12 @@ precautions to prevent security violations.
|
|||||||
.Sh RETURN VALUES
|
.Sh RETURN VALUES
|
||||||
If a call to
|
If a call to
|
||||||
.Fn getlogin
|
.Fn getlogin
|
||||||
succeeds, it returns a pointer to a null-terminated string in a static buffer.
|
succeeds, it returns a pointer to a null-terminated string in a static buffer,
|
||||||
.Fn getlogin_r
|
or
|
||||||
returns a pointer to the buffer passed in by the caller on success.
|
|
||||||
Both return
|
|
||||||
.Dv NULL
|
.Dv NULL
|
||||||
if the name has not been set.
|
if the name has not been set.
|
||||||
|
.Fn getlogin_r
|
||||||
|
returns zero if successful, or the error number upon failure.
|
||||||
.Pp
|
.Pp
|
||||||
If a call to
|
If a call to
|
||||||
.Fn setlogin
|
.Fn setlogin
|
||||||
@ -166,6 +166,8 @@ Login names are limited to
|
|||||||
characters, currently 17 including null.
|
characters, currently 17 including null.
|
||||||
.It Bq Er EPERM
|
.It Bq Er EPERM
|
||||||
The caller tried to set the login name and was not the super-user.
|
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
|
.El
|
||||||
.Sh SEE ALSO
|
.Sh SEE ALSO
|
||||||
.Xr setsid 2 ,
|
.Xr setsid 2 ,
|
||||||
@ -186,3 +188,14 @@ The
|
|||||||
.Fn getlogin
|
.Fn getlogin
|
||||||
function first appeared in
|
function first appeared in
|
||||||
.Bx 4.4 .
|
.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 .
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user