diff --git a/libc/bionic/grp_pwd.cpp b/libc/bionic/grp_pwd.cpp index 078a0b311..28236623a 100644 --- a/libc/bionic/grp_pwd.cpp +++ b/libc/bionic/grp_pwd.cpp @@ -467,7 +467,16 @@ int getgrouplist(const char* /*user*/, gid_t group, gid_t* groups, int* ngroups) char* getlogin() { // NOLINT: implementing bad function. passwd *pw = getpwuid(getuid()); // NOLINT: implementing bad function in terms of bad function. - return (pw != NULL) ? pw->pw_name : NULL; + return pw ? pw->pw_name : nullptr; +} + +int getlogin_r(char* buf, size_t size) { + char* login = getlogin(); + if (login == nullptr) return errno; + size_t login_length = strlen(login) + 1; + if (login_length > size) return ERANGE; + memcpy(buf, login, login_length); + return 0; } void setpwent() { diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp index 4a23feca5..7325dbd57 100644 --- a/libc/bionic/sysconf.cpp +++ b/libc/bionic/sysconf.cpp @@ -135,12 +135,12 @@ long sysconf(int name) { case _SC_TIMERS: return _POSIX_TIMERS; case _SC_GETGR_R_SIZE_MAX: return 1024; case _SC_GETPW_R_SIZE_MAX: return 1024; - case _SC_LOGIN_NAME_MAX: return 256; // Seems default on linux. + case _SC_LOGIN_NAME_MAX: return LOGIN_NAME_MAX; case _SC_THREAD_DESTRUCTOR_ITERATIONS: return PTHREAD_DESTRUCTOR_ITERATIONS; case _SC_THREAD_KEYS_MAX: return PTHREAD_KEYS_MAX; case _SC_THREAD_STACK_MIN: return PTHREAD_STACK_MIN; case _SC_THREAD_THREADS_MAX: return -1; // No specific limit. - case _SC_TTY_NAME_MAX: return 32; // Seems default on linux. + case _SC_TTY_NAME_MAX: return TTY_NAME_MAX; case _SC_THREADS: return _POSIX_THREADS; case _SC_THREAD_ATTR_STACKADDR: return _POSIX_THREAD_ATTR_STACKADDR; case _SC_THREAD_ATTR_STACKSIZE: return _POSIX_THREAD_ATTR_STACKSIZE; diff --git a/libc/include/limits.h b/libc/include/limits.h index 157f7a61f..51f4fadd2 100644 --- a/libc/include/limits.h +++ b/libc/include/limits.h @@ -137,6 +137,8 @@ #include #define HOST_NAME_MAX _POSIX_HOST_NAME_MAX +#define LOGIN_NAME_MAX 256 +#define TTY_NAME_MAX 32 #define _POSIX_VERSION 200809L #define _POSIX2_VERSION _POSIX_VERSION diff --git a/libc/include/unistd.h b/libc/include/unistd.h index e024527ef..8336976c5 100644 --- a/libc/include/unistd.h +++ b/libc/include/unistd.h @@ -118,6 +118,7 @@ int setresgid(gid_t __rgid, gid_t __egid, gid_t __sgid); int getresuid(uid_t* __ruid, uid_t* __euid, uid_t* __suid); int getresgid(gid_t* __rgid, gid_t* __egid, gid_t* __sgid); char* getlogin(void); +int getlogin_r(char* __buffer, size_t __buffer_size) __INTRODUCED_IN_FUTURE; long fpathconf(int __fd, int __name); long pathconf(const char* __path, int __name); diff --git a/libc/libc.arm.map b/libc/libc.arm.map index a4212dda7..45ca9eb45 100644 --- a/libc/libc.arm.map +++ b/libc/libc.arm.map @@ -1316,6 +1316,11 @@ LIBC_O { wctrans_l; # introduced=26 } LIBC_N; +LIBC_P { + global: + getlogin_r; # future +} LIBC_O; + LIBC_PRIVATE { global: ___Unwind_Backtrace; # arm @@ -1532,7 +1537,7 @@ LIBC_PRIVATE { vfdprintf; # arm x86 mips wait3; # arm x86 mips wcswcs; # arm x86 mips -} LIBC_O; +} LIBC_P; LIBC_DEPRECATED { global: @@ -1554,4 +1559,4 @@ LIBC_PLATFORM { malloc_disable; malloc_enable; malloc_iterate; -} LIBC_O; +} LIBC_P; diff --git a/libc/libc.arm64.map b/libc/libc.arm64.map index bf0341ad2..ed1e82cca 100644 --- a/libc/libc.arm64.map +++ b/libc/libc.arm64.map @@ -1238,6 +1238,11 @@ LIBC_O { wctrans_l; # introduced=26 } LIBC_N; +LIBC_P { + global: + getlogin_r; # future +} LIBC_O; + LIBC_PRIVATE { global: android_getaddrinfofornet; @@ -1249,7 +1254,7 @@ LIBC_PRIVATE { free_malloc_leak_info; get_malloc_leak_info; gMallocLeakZygoteChild; -} LIBC_O; +} LIBC_P; LIBC_DEPRECATED { global: @@ -1271,4 +1276,4 @@ LIBC_PLATFORM { malloc_disable; malloc_enable; malloc_iterate; -} LIBC_O; +} LIBC_P; diff --git a/libc/libc.map.txt b/libc/libc.map.txt index c271a57e4..8b1d6de42 100644 --- a/libc/libc.map.txt +++ b/libc/libc.map.txt @@ -1341,6 +1341,11 @@ LIBC_O { wctrans_l; # introduced=26 } LIBC_N; +LIBC_P { + global: + getlogin_r; # future +} LIBC_O; + LIBC_PRIVATE { global: ___Unwind_Backtrace; # arm @@ -1558,7 +1563,7 @@ LIBC_PRIVATE { vfdprintf; # arm x86 mips wait3; # arm x86 mips wcswcs; # arm x86 mips -} LIBC_O; +} LIBC_P; LIBC_DEPRECATED { global: @@ -1580,4 +1585,4 @@ LIBC_PLATFORM { malloc_disable; malloc_enable; malloc_iterate; -} LIBC_O; +} LIBC_P; diff --git a/libc/libc.mips.map b/libc/libc.mips.map index 214c7f506..256ca9ed4 100644 --- a/libc/libc.mips.map +++ b/libc/libc.mips.map @@ -1300,6 +1300,11 @@ LIBC_O { wctrans_l; # introduced=26 } LIBC_N; +LIBC_P { + global: + getlogin_r; # future +} LIBC_O; + LIBC_PRIVATE { global: __accept4; # arm x86 mips @@ -1373,7 +1378,7 @@ LIBC_PRIVATE { vfdprintf; # arm x86 mips wait3; # arm x86 mips wcswcs; # arm x86 mips -} LIBC_O; +} LIBC_P; LIBC_DEPRECATED { global: @@ -1395,4 +1400,4 @@ LIBC_PLATFORM { malloc_disable; malloc_enable; malloc_iterate; -} LIBC_O; +} LIBC_P; diff --git a/libc/libc.mips64.map b/libc/libc.mips64.map index bf0341ad2..ed1e82cca 100644 --- a/libc/libc.mips64.map +++ b/libc/libc.mips64.map @@ -1238,6 +1238,11 @@ LIBC_O { wctrans_l; # introduced=26 } LIBC_N; +LIBC_P { + global: + getlogin_r; # future +} LIBC_O; + LIBC_PRIVATE { global: android_getaddrinfofornet; @@ -1249,7 +1254,7 @@ LIBC_PRIVATE { free_malloc_leak_info; get_malloc_leak_info; gMallocLeakZygoteChild; -} LIBC_O; +} LIBC_P; LIBC_DEPRECATED { global: @@ -1271,4 +1276,4 @@ LIBC_PLATFORM { malloc_disable; malloc_enable; malloc_iterate; -} LIBC_O; +} LIBC_P; diff --git a/libc/libc.x86.map b/libc/libc.x86.map index 145b64ebf..2ebc86ce8 100644 --- a/libc/libc.x86.map +++ b/libc/libc.x86.map @@ -1298,6 +1298,11 @@ LIBC_O { wctrans_l; # introduced=26 } LIBC_N; +LIBC_P { + global: + getlogin_r; # future +} LIBC_O; + LIBC_PRIVATE { global: __accept4; # arm x86 mips @@ -1372,7 +1377,7 @@ LIBC_PRIVATE { vfdprintf; # arm x86 mips wait3; # arm x86 mips wcswcs; # arm x86 mips -} LIBC_O; +} LIBC_P; LIBC_DEPRECATED { global: @@ -1394,4 +1399,4 @@ LIBC_PLATFORM { malloc_disable; malloc_enable; malloc_iterate; -} LIBC_O; +} LIBC_P; diff --git a/libc/libc.x86_64.map b/libc/libc.x86_64.map index bf0341ad2..ed1e82cca 100644 --- a/libc/libc.x86_64.map +++ b/libc/libc.x86_64.map @@ -1238,6 +1238,11 @@ LIBC_O { wctrans_l; # introduced=26 } LIBC_N; +LIBC_P { + global: + getlogin_r; # future +} LIBC_O; + LIBC_PRIVATE { global: android_getaddrinfofornet; @@ -1249,7 +1254,7 @@ LIBC_PRIVATE { free_malloc_leak_info; get_malloc_leak_info; gMallocLeakZygoteChild; -} LIBC_O; +} LIBC_P; LIBC_DEPRECATED { global: @@ -1271,4 +1276,4 @@ LIBC_PLATFORM { malloc_disable; malloc_enable; malloc_iterate; -} LIBC_O; +} LIBC_P; diff --git a/tests/unistd_test.cpp b/tests/unistd_test.cpp index a81f11210..8dbcd4aad 100644 --- a/tests/unistd_test.cpp +++ b/tests/unistd_test.cpp @@ -1372,3 +1372,10 @@ TEST(UNISTD_TEST, exec_argv0_null) { ASSERT_EXIT(execve("/system/bin/run-as", args, envs), testing::ExitedWithCode(1), ": usage: run-as"); } + +TEST(UNISTD_TEST, getlogin_r) { + char buf[LOGIN_NAME_MAX] = {}; + EXPECT_EQ(ERANGE, getlogin_r(buf, 0)); + EXPECT_EQ(0, getlogin_r(buf, sizeof(buf))); + EXPECT_STREQ(getlogin(), buf); +}