diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index 4cb7b93745a..0825fa05864 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -279,13 +279,25 @@ PHPAPI zend_result php_get_gid_by_name(const char *name, gid_t *gid) struct group *retgrptr; long grbuflen = sysconf(_SC_GETGR_R_SIZE_MAX); char *grbuf; + int err; if (grbuflen < 1) { - return FAILURE; + grbuflen = 1024; } - +# if ZEND_DEBUG + /* Test retry logic */ + grbuflen = 1; +# endif grbuf = emalloc(grbuflen); - if (getgrnam_r(name, &gr, grbuf, grbuflen, &retgrptr) != 0 || retgrptr == NULL) { + +try_again: + err = getgrnam_r(name, &gr, grbuf, grbuflen, &retgrptr); + if (err != 0 || retgrptr == NULL) { + if (err == ERANGE) { + grbuflen *= 2; + grbuf = erealloc(grbuf, grbuflen); + goto try_again; + } efree(grbuf); return FAILURE; } @@ -405,13 +417,25 @@ PHPAPI zend_result php_get_uid_by_name(const char *name, uid_t *uid) struct passwd *retpwptr = NULL; long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); char *pwbuf; + int err; if (pwbuflen < 1) { - return FAILURE; + pwbuflen = 1024; } - +# if ZEND_DEBUG + /* Test retry logic */ + pwbuflen = 1; +# endif pwbuf = emalloc(pwbuflen); - if (getpwnam_r(name, &pw, pwbuf, pwbuflen, &retpwptr) != 0 || retpwptr == NULL) { + +try_again: + err = getpwnam_r(name, &pw, pwbuf, pwbuflen, &retpwptr); + if (err != 0 || retpwptr == NULL) { + if (err == EAGAIN) { + pwbuflen *= 2; + pwbuf = erealloc(pwbuf, pwbuflen); + goto try_again; + } efree(pwbuf); return FAILURE; } diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index 5ea432d6cef..99a082846b4 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -374,26 +374,38 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle) if (s) { /* if there is no path name after the file, do not bother */ char user[32]; /* to try open the directory */ - struct passwd *pw; -#if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX) - struct passwd pwstruc; - long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); - char *pwbuf; - if (pwbuflen < 1) { - return FAILURE; - } - - pwbuf = emalloc(pwbuflen); -#endif length = s - (path_info + 2); if (length > sizeof(user) - 1) { length = sizeof(user) - 1; } memcpy(user, path_info + 2, length); user[length] = '\0'; + + struct passwd *pw; #if defined(ZTS) && defined(HAVE_GETPWNAM_R) && defined(_SC_GETPW_R_SIZE_MAX) - if (getpwnam_r(user, &pwstruc, pwbuf, pwbuflen, &pw)) { + struct passwd pwstruc; + long pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); + char *pwbuf; + int err; + + if (pwbuflen < 1) { + pwbuflen = 1024; + } +# if ZEND_DEBUG + /* Test retry logic */ + pwbuflen = 1; +# endif + pwbuf = emalloc(pwbuflen); + +try_again: + err = getpwnam_r(user, &pwstruc, pwbuf, pwbuflen, &pw); + if (err) { + if (err == ERANGE) { + pwbuflen *= 2; + pwbuf = erealloc(pwbuf, pwbuflen); + goto try_again; + } efree(pwbuf); return FAILURE; } diff --git a/main/main.c b/main/main.c index fb20ec2777c..aa80837f657 100644 --- a/main/main.c +++ b/main/main.c @@ -1475,12 +1475,25 @@ PHPAPI char *php_get_current_user(void) struct passwd *retpwptr = NULL; int pwbuflen = sysconf(_SC_GETPW_R_SIZE_MAX); char *pwbuf; + int err; if (pwbuflen < 1) { - return ""; + pwbuflen = 1024; } +# if ZEND_DEBUG + /* Test retry logic */ + pwbuflen = 1; +# endif pwbuf = emalloc(pwbuflen); - if (getpwuid_r(pstat->st_uid, &_pw, pwbuf, pwbuflen, &retpwptr) != 0) { + +try_again: + err = getpwuid_r(pstat->st_uid, &_pw, pwbuf, pwbuflen, &retpwptr); + if (err != 0) { + if (err == ERANGE) { + pwbuflen *= 2; + pwbuf = erealloc(pwbuf, pwbuflen); + goto try_again; + } efree(pwbuf); return ""; }