Project

General

Profile

Bug #16787 » allow-dir.home-for-non-login-procs-v2.patch

patch: allow-dir.home-for-non-login-procs-v2.patch - salewski (Alan Salewski), 04/15/2020 09:52 PM

View differences:

configure.ac
AC_CHECK_FUNCS(getpgrp)
AC_CHECK_FUNCS(getpriority)
AC_CHECK_FUNCS(getpwnam_r)
AC_CHECK_FUNCS(getpwuid)
AC_CHECK_FUNCS(getpwuid_r)
AC_CHECK_FUNCS(getrandom)
AC_CHECK_FUNCS(getresgid)
AC_CHECK_FUNCS(getresuid)
file.c
#include "ruby/thread.h"
#include "ruby/util.h"
#if defined(HAVE_PWD_H)
# if defined(HAVE_GETPWUID_R)
# define USE_GETPWUID_R 1
# define GETPW_R_SIZE_DEFAULT 0x1000
# define GETPW_R_SIZE_LIMIT 0x10000
# if defined(_SC_GETPW_R_SIZE_MAX)
# define GETPW_R_SIZE_INIT sysconf(_SC_GETPW_R_SIZE_MAX)
# else
# define GETPW_R_SIZE_INIT GETPW_R_SIZE_DEFAULT
# endif
# elif defined(HAVE_GETPWUID)
# define USE_GETPWUID 1
# endif
#endif
VALUE rb_cFile;
VALUE rb_mFileTest;
VALUE rb_cStat;
......
rb_default_home_dir(VALUE result)
{
const char *dir = getenv("HOME");
if (dir)
return copy_home_path(result, dir);
#if defined HAVE_PWD_H
if (!dir) {
const char *login = getlogin();
if (login) {
struct passwd *pw = getpwnam(login);
if (pw) {
copy_home_path(result, pw->pw_dir);
endpwent();
return result;
}
endpwent();
rb_raise(rb_eArgError, "couldn't find HOME for login `%s' -- expanding `~'",
login);
}
else {
rb_raise(rb_eArgError, "couldn't find login name -- expanding `~'");
#if !defined(USE_GETPWUID_R) && !defined(USE_GETPWUID)
rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding `~'");
#else
/* We'll look up the user's dflt home dir in the password db, by uid */
uid_t ruid = getuid();
struct passwd *pwptr;
# ifdef USE_GETPWUID_R
struct passwd pwd;
char *buf;
long bufsize = GETPW_R_SIZE_INIT; /* maybe -1 */
if (bufsize < 0)
bufsize = GETPW_R_SIZE_DEFAULT;
VALUE getpw_tmp = rb_str_tmp_new(bufsize);
buf = RSTRING_PTR(getpw_tmp);
bufsize = rb_str_capacity(getpw_tmp);
rb_str_set_len(getpw_tmp, bufsize);
int e;
errno = 0;
while ((e = getpwuid_r(ruid, &pwd, buf, bufsize, &pwptr)) != 0) {
if (e != ERANGE || bufsize >= GETPW_R_SIZE_LIMIT) {
rb_str_resize(getpw_tmp, 0);
rb_syserr_fail(e, "getpwuid_r");
}
rb_str_modify_expand(getpw_tmp, bufsize);
buf = RSTRING_PTR(getpw_tmp);
bufsize = rb_str_capacity(getpw_tmp);
}
#endif
if (!dir) {
rb_raise(rb_eArgError, "couldn't find HOME environment -- expanding `~'");
if (pwptr == NULL) {
/* no record in the password database for the uid */
rb_str_resize(getpw_tmp, 0);
rb_raise(rb_eArgError, "getpwuid_r couldn't find HOME for uid `%ld' -- expanding `~'",
(long)ruid);
}
copy_home_path(result, pwptr->pw_dir);
rb_str_resize(getpw_tmp, 0);
# elif defined(USE_GETPWUID)
errno = 0;
pwptr = getpwuid(ruid);
if (pwptr == NULL) {
if (errno) {
rb_syserr_fail(errno, "getpwuid");
}
rb_raise(rb_eArgError, "getpwuid couldn't find HOME for uid `%ld' -- expanding `~'",
(long)ruid);
}
return copy_home_path(result, dir);
copy_home_path(result, pwptr->pw_dir);
# else
# error Hello! Ruby developers believe this message must not happen.
# error BUG: Either USE_GETPWUID_R or USE_GETPWUID should be defined here.
# error If you encounter this message, can you file a bug report?
# error Remember to attach a detailed description of your environment.
# error Thank you!
# endif
return result;
#endif /* !defined(USE_GETPWUID_R) && !defined(USE_GETPWUID) */
}
static VALUE
(2-2/10)