libs/libc/pwd: Add getlogin() and getlogin_r().

POSIX specifies getlogin() and getlogin_r(), and NuttX did not have
them.  NuttX has no login sessions, so the login name is the name of
the real user ID in the user database, from getpwuid_r(): "root" when
there is no passwd file.

Assisted-by: Claude Code:claude-opus-5-5
Signed-off-by: Marco Casaroli <marco.casaroli@gmail.com>
This commit is contained in:
Marco Casaroli 2026-10-09 08:41:44 +02:00 • committed by Xiang Xiao
parent 73760338dc
commit 12d5e1c0ba
4 changed files with 121 additions and 2 deletions

View file

@ -399,6 +399,11 @@ int isatty(int fd);
FAR char *ttyname(int fd);
int ttyname_r(int fd, FAR char *buf, size_t buflen);
/* The name of the user */
FAR char *getlogin(void);
int getlogin_r(FAR char *buf, size_t bufsize);
/* Memory management */
#if defined(CONFIG_ARCH_ADDRENV) && defined(CONFIG_MM_PGALLOC) && \

View file

@ -26,7 +26,8 @@ set(SRCS
lib_getpwuidr.c
lib_getpwent.c
lib_pwd_globals.c
lib_getspnam.c)
lib_getspnam.c
lib_getlogin.c)
if(CONFIG_LIBC_PASSWD_FILE)
list(APPEND SRCS lib_find_pwdfile.c lib_getspnamr.c)

View file

@ -23,7 +23,7 @@
# Add the pwd C files to the build
CSRCS += lib_getpwnam.c lib_getpwnamr.c lib_getpwuid.c lib_getpwuidr.c
CSRCS += lib_getpwent.c lib_pwd_globals.c lib_getspnam.c
CSRCS += lib_getpwent.c lib_pwd_globals.c lib_getspnam.c lib_getlogin.c
ifeq ($(CONFIG_LIBC_PASSWD_FILE),y)
CSRCS += lib_find_pwdfile.c lib_getspnamr.c

View file

@ -0,0 +1,113 @@
/****************************************************************************
* libs/libc/pwd/lib_getlogin.c
*
* SPDX-License-Identifier: Apache-2.0
*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership. The
* ASF licenses this file to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance with the
* License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <errno.h>
#include <limits.h>
#include <pwd.h>
#include <string.h>
#include <unistd.h>
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
/* Size of the buffer for the strings of one user database entry */
#define GETLOGIN_PWBUF_SIZE 256
/****************************************************************************
* Public Functions
****************************************************************************/
/****************************************************************************
* Name: getlogin_r
*
* Description:
* Put the login name of the user into buf. NuttX has no login sessions,
* so the login name is the name of the real user ID in the user database.
*
* Input Parameters:
* buf - The buffer for the name.
* bufsize - The size of buf in bytes.
*
* Returned Value:
* Zero on success. ERANGE if the name does not fit in buf, ENXIO if the
* user database has no entry for the real user ID.
*
****************************************************************************/
int getlogin_r(FAR char *buf, size_t bufsize)
{
char pwbuf[GETLOGIN_PWBUF_SIZE];
FAR struct passwd *result;
struct passwd pwd;
int ret;
ret = getpwuid_r(getuid(), &pwd, pwbuf, sizeof(pwbuf), &result);
if (ret != 0)
{
return ret;
}
if (result == NULL)
{
return ENXIO;
}
if (strlcpy(buf, pwd.pw_name, bufsize) >= bufsize)
{
return ERANGE;
}
return 0;
}
/****************************************************************************
* Name: getlogin
*
* Description:
* Return the login name of the user. See getlogin_r(). The string is
* overwritten by the next call to getlogin().
*
* Returned Value:
* A pointer to the name, or NULL with errno set if there is no name.
*
****************************************************************************/
FAR char *getlogin(void)
{
static char name[NAME_MAX + 1];
int ret;
ret = getlogin_r(name, sizeof(name));
if (ret != 0)
{
set_errno(ret);
return NULL;
}
return name;
}