The GNU/Linux implementation of getlogin_r does not pad with zeroes for the rest of the buffer. When the bufsize is insufficient, it does not touch the buffer at all, but this divergent behavior is fine for now.
45 lines
1.1 KiB
C
45 lines
1.1 KiB
C
#define _GNU_SOURCE
|
|
|
|
#include <dlfcn.h>
|
|
#include <errno.h>
|
|
#include <pwd.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <sys/types.h>
|
|
|
|
int strlcpy(char *restrict dest, const char *restrict src, size_t bufsize) {
|
|
size_t i;
|
|
for (i = 0; i < bufsize; ++i) {
|
|
dest[i] = src[i];
|
|
if (src[i] == '\0') {
|
|
return 0;
|
|
}
|
|
}
|
|
return ERANGE;
|
|
}
|
|
|
|
char *getlogin(void) {
|
|
return getenv("USER");
|
|
}
|
|
|
|
int getlogin_r(char *buf, size_t bufsize) {
|
|
return strlcpy(buf, getlogin(), bufsize);
|
|
}
|
|
|
|
struct passwd *getpwuid(uid_t uid) {
|
|
struct passwd *(*getpwuid)(uid_t) = dlsym(RTLD_NEXT, "getpwuid");
|
|
if (getpwuid == NULL) {
|
|
fprintf(stderr, "Unable to find the adress of the getpwuid function: %s\n", dlerror());
|
|
return NULL;
|
|
}
|
|
struct passwd *pass = getpwuid(uid);
|
|
char *name = getenv("USER");
|
|
if (name == NULL) {
|
|
fprintf(stderr, "Could not find the USER environment variable. Using the real username.\n");
|
|
return pass;
|
|
}
|
|
pass->pw_name = name;
|
|
return pass;
|
|
}
|