Refactor getlogin
and getpw*
functions
- Extract functions to check not-found conditions - Set the length to the result of `rb_getlogin` - Reentrant versions return an error numeber but not `errno` - Check maybe-undefined macros with `defined`
This commit is contained in:
parent
630bfd36f9
commit
08e142b209
Notes:
git
2024-09-05 07:56:12 +00:00
102
process.c
102
process.c
@ -5700,6 +5700,12 @@ check_gid_switch(void)
|
|||||||
|
|
||||||
|
|
||||||
#if defined(HAVE_PWD_H)
|
#if defined(HAVE_PWD_H)
|
||||||
|
static inline bool
|
||||||
|
login_not_found(int err)
|
||||||
|
{
|
||||||
|
return (err == ENOTTY || err == ENXIO || err == ENOENT);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Best-effort attempt to obtain the name of the login user, if any,
|
* Best-effort attempt to obtain the name of the login user, if any,
|
||||||
* associated with the process. Processes not descended from login(1) (or
|
* associated with the process. Processes not descended from login(1) (or
|
||||||
@ -5708,18 +5714,18 @@ check_gid_switch(void)
|
|||||||
VALUE
|
VALUE
|
||||||
rb_getlogin(void)
|
rb_getlogin(void)
|
||||||
{
|
{
|
||||||
#if ( !defined(USE_GETLOGIN_R) && !defined(USE_GETLOGIN) )
|
# if !defined(USE_GETLOGIN_R) && !defined(USE_GETLOGIN)
|
||||||
return Qnil;
|
return Qnil;
|
||||||
#else
|
# else
|
||||||
char MAYBE_UNUSED(*login) = NULL;
|
char MAYBE_UNUSED(*login) = NULL;
|
||||||
|
|
||||||
# ifdef USE_GETLOGIN_R
|
# ifdef USE_GETLOGIN_R
|
||||||
|
|
||||||
#if defined(__FreeBSD__)
|
# if defined(__FreeBSD__)
|
||||||
typedef int getlogin_r_size_t;
|
typedef int getlogin_r_size_t;
|
||||||
#else
|
# else
|
||||||
typedef size_t getlogin_r_size_t;
|
typedef size_t getlogin_r_size_t;
|
||||||
#endif
|
# endif
|
||||||
|
|
||||||
long loginsize = GETLOGIN_R_SIZE_INIT; /* maybe -1 */
|
long loginsize = GETLOGIN_R_SIZE_INIT; /* maybe -1 */
|
||||||
|
|
||||||
@ -5733,10 +5739,8 @@ rb_getlogin(void)
|
|||||||
rb_str_set_len(maybe_result, loginsize);
|
rb_str_set_len(maybe_result, loginsize);
|
||||||
|
|
||||||
int gle;
|
int gle;
|
||||||
errno = 0;
|
|
||||||
while ((gle = getlogin_r(login, (getlogin_r_size_t)loginsize)) != 0) {
|
while ((gle = getlogin_r(login, (getlogin_r_size_t)loginsize)) != 0) {
|
||||||
|
if (login_not_found(gle)) {
|
||||||
if (gle == ENOTTY || gle == ENXIO || gle == ENOENT) {
|
|
||||||
rb_str_resize(maybe_result, 0);
|
rb_str_resize(maybe_result, 0);
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
@ -5756,17 +5760,19 @@ rb_getlogin(void)
|
|||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rb_str_set_len(maybe_result, strlen(login));
|
||||||
return maybe_result;
|
return maybe_result;
|
||||||
|
|
||||||
# elif USE_GETLOGIN
|
# elif defined(USE_GETLOGIN)
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
login = getlogin();
|
login = getlogin();
|
||||||
if (errno) {
|
int err = errno;
|
||||||
if (errno == ENOTTY || errno == ENXIO || errno == ENOENT) {
|
if (err) {
|
||||||
|
if (login_not_found(err)) {
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
rb_syserr_fail(errno, "getlogin");
|
rb_syserr_fail(err, "getlogin");
|
||||||
}
|
}
|
||||||
|
|
||||||
return login ? rb_str_new_cstr(login) : Qnil;
|
return login ? rb_str_new_cstr(login) : Qnil;
|
||||||
@ -5775,10 +5781,26 @@ rb_getlogin(void)
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* avoid treating as errors errno values that indicate "not found" */
|
||||||
|
static inline bool
|
||||||
|
pwd_not_found(int err)
|
||||||
|
{
|
||||||
|
switch (err) {
|
||||||
|
case 0:
|
||||||
|
case ENOENT:
|
||||||
|
case ESRCH:
|
||||||
|
case EBADF:
|
||||||
|
case EPERM:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
VALUE
|
VALUE
|
||||||
rb_getpwdirnam_for_login(VALUE login_name)
|
rb_getpwdirnam_for_login(VALUE login_name)
|
||||||
{
|
{
|
||||||
#if ( !defined(USE_GETPWNAM_R) && !defined(USE_GETPWNAM) )
|
#if !defined(USE_GETPWNAM_R) && !defined(USE_GETPWNAM)
|
||||||
return Qnil;
|
return Qnil;
|
||||||
#else
|
#else
|
||||||
|
|
||||||
@ -5787,7 +5809,7 @@ rb_getpwdirnam_for_login(VALUE login_name)
|
|||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *login = RSTRING_PTR(login_name);
|
const char *login = RSTRING_PTR(login_name);
|
||||||
|
|
||||||
struct passwd *pwptr;
|
struct passwd *pwptr;
|
||||||
|
|
||||||
@ -5807,11 +5829,8 @@ rb_getpwdirnam_for_login(VALUE login_name)
|
|||||||
rb_str_set_len(getpwnm_tmp, bufsizenm);
|
rb_str_set_len(getpwnm_tmp, bufsizenm);
|
||||||
|
|
||||||
int enm;
|
int enm;
|
||||||
errno = 0;
|
|
||||||
while ((enm = getpwnam_r(login, &pwdnm, bufnm, bufsizenm, &pwptr)) != 0) {
|
while ((enm = getpwnam_r(login, &pwdnm, bufnm, bufsizenm, &pwptr)) != 0) {
|
||||||
|
if (pwd_not_found(enm)) {
|
||||||
if (enm == ENOENT || enm== ESRCH || enm == EBADF || enm == EPERM) {
|
|
||||||
/* not found; non-errors */
|
|
||||||
rb_str_resize(getpwnm_tmp, 0);
|
rb_str_resize(getpwnm_tmp, 0);
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
@ -5837,21 +5856,21 @@ rb_getpwdirnam_for_login(VALUE login_name)
|
|||||||
rb_str_resize(getpwnm_tmp, 0);
|
rb_str_resize(getpwnm_tmp, 0);
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
# elif USE_GETPWNAM
|
# elif defined(USE_GETPWNAM)
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
pwptr = getpwnam(login);
|
if (!(pwptr = getpwnam(login))) {
|
||||||
if (pwptr) {
|
int err = errno;
|
||||||
/* found it */
|
|
||||||
return rb_str_new_cstr(pwptr->pw_dir);
|
if (pwd_not_found(err)) {
|
||||||
}
|
return Qnil;
|
||||||
if (errno
|
}
|
||||||
/* avoid treating as errors errno values that indicate "not found" */
|
|
||||||
&& ( errno != ENOENT && errno != ESRCH && errno != EBADF && errno != EPERM)) {
|
rb_syserr_fail(err, "getpwnam");
|
||||||
rb_syserr_fail(errno, "getpwnam");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Qnil; /* not found */
|
/* found it */
|
||||||
|
return rb_str_new_cstr(pwptr->pw_dir);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@ -5887,11 +5906,8 @@ rb_getpwdiruid(void)
|
|||||||
rb_str_set_len(getpwid_tmp, bufsizeid);
|
rb_str_set_len(getpwid_tmp, bufsizeid);
|
||||||
|
|
||||||
int eid;
|
int eid;
|
||||||
errno = 0;
|
|
||||||
while ((eid = getpwuid_r(ruid, &pwdid, bufid, bufsizeid, &pwptr)) != 0) {
|
while ((eid = getpwuid_r(ruid, &pwdid, bufid, bufsizeid, &pwptr)) != 0) {
|
||||||
|
if (pwd_not_found(eid)) {
|
||||||
if (eid == ENOENT || eid== ESRCH || eid == EBADF || eid == EPERM) {
|
|
||||||
/* not found; non-errors */
|
|
||||||
rb_str_resize(getpwid_tmp, 0);
|
rb_str_resize(getpwid_tmp, 0);
|
||||||
return Qnil;
|
return Qnil;
|
||||||
}
|
}
|
||||||
@ -5920,18 +5936,18 @@ rb_getpwdiruid(void)
|
|||||||
# elif defined(USE_GETPWUID)
|
# elif defined(USE_GETPWUID)
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
pwptr = getpwuid(ruid);
|
if (!(pwptr = getpwuid(ruid))) {
|
||||||
if (pwptr) {
|
int err = errno;
|
||||||
/* found it */
|
|
||||||
return rb_str_new_cstr(pwptr->pw_dir);
|
if (pwd_not_found(err)) {
|
||||||
}
|
return Qnil;
|
||||||
if (errno
|
}
|
||||||
/* avoid treating as errors errno values that indicate "not found" */
|
|
||||||
&& ( errno == ENOENT || errno == ESRCH || errno == EBADF || errno == EPERM)) {
|
rb_syserr_fail(err, "getpwuid");
|
||||||
rb_syserr_fail(errno, "getpwuid");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return Qnil; /* not found */
|
/* found it */
|
||||||
|
return rb_str_new_cstr(pwptr->pw_dir);
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
#endif /* !defined(USE_GETPWUID_R) && !defined(USE_GETPWUID) */
|
#endif /* !defined(USE_GETPWUID_R) && !defined(USE_GETPWUID) */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user