refactored part of expand_env_esc() into mch_get_user_directory()

This commit is contained in:
Stefan Hoffmann 2014-03-07 13:43:55 +01:00 committed by Thiago de Arruda
parent ad77ff53d3
commit 33eb031c01
5 changed files with 41 additions and 20 deletions

View File

@ -2895,25 +2895,14 @@ expand_env_esc (
*var = NUL; *var = NUL;
# ifdef UNIX # ifdef UNIX
/* /*
* If the system supports getpwnam(), use it. * Use mch_get_user_directory() to get the user directory.
* Otherwise, or if getpwnam() fails, the shell is used to * If this function fails, the shell is used to
* expand ~user. This is slower and may fail if the shell * expand ~user. This is slower and may fail if the shell
* does not support ~user (old versions of /bin/sh). * does not support ~user (old versions of /bin/sh).
*/ */
# if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H) var = (char_u *)mch_get_user_directory((char *)dst + 1);
{ mustfree = TRUE;
struct passwd *pw;
/* Note: memory allocated by getpwnam() is never freed.
* Calling endpwent() apparently doesn't help. */
pw = getpwnam((char *)dst + 1);
if (pw != NULL)
var = (char_u *)pw->pw_dir;
else
var = NULL;
}
if (var == NULL) if (var == NULL)
# endif
{ {
expand_T xpc; expand_T xpc;

View File

@ -16,5 +16,6 @@ char *mch_getenvname_at_index(size_t index);
int mch_get_usernames(garray_T *usernames); int mch_get_usernames(garray_T *usernames);
int mch_get_user_name(char *s, size_t len); int mch_get_user_name(char *s, size_t len);
int mch_get_uname(uid_t uid, char *s, size_t len); int mch_get_uname(uid_t uid, char *s, size_t len);
char *mch_get_user_directory(const char *name);
#endif #endif

View File

@ -84,3 +84,25 @@ int mch_get_uname(uid_t uid, char *s, size_t len)
return FAIL; // a number is not a name return FAIL; // a number is not a name
} }
/*
* Returns the user directory for the given username.
* The caller has to free() the returned string.
* If the username is not found, NULL is returned.
*/
char *mch_get_user_directory(const char *name)
{
#if defined(HAVE_GETPWNAM) && defined(HAVE_PWD_H)
struct passwd *pw;
if (name == NULL) {
return NULL;
}
pw = getpwnam(name);
if (pw != NULL) {
// save the string from the static passwd entry into malloced memory
char *user_directory = (char *)vim_strsave((char_u *)pw->pw_dir);
return user_directory;
}
#endif
return NULL;
}

View File

@ -121,10 +121,6 @@
#define BASENAMELEN (MAXNAMLEN - 5) #define BASENAMELEN (MAXNAMLEN - 5)
#ifdef HAVE_PWD_H
# include <pwd.h>
#endif
/* /*
* Unix system-dependent file names * Unix system-dependent file names
*/ */

View File

@ -14,6 +14,7 @@ typedef struct growarray {
int mch_get_usernames(garray_T *usernames); int mch_get_usernames(garray_T *usernames);
int mch_get_user_name(char *s, size_t len); int mch_get_user_name(char *s, size_t len);
int mch_get_uname(int uid, char *s, size_t len); int mch_get_uname(int uid, char *s, size_t len);
char *mch_get_user_directory(const char *name);
int getuid(void); int getuid(void);
]] ]]
@ -75,3 +76,15 @@ describe 'users function', ->
eq FAIL, users.mch_get_uname(user_id, name_out, 100) eq FAIL, users.mch_get_uname(user_id, name_out, 100)
eq '2342', ffi.string name_out eq '2342', ffi.string name_out
describe 'mch_get_user_directory', ->
it 'should return NULL if called with NULL', ->
eq NULL, users.mch_get_user_directory NULL
it 'should return $HOME for the current user', ->
home = os.getenv('HOME')
eq home, ffi.string (users.mch_get_user_directory current_username)
it 'should return NULL if the user is not found', ->
eq NULL, users.mch_get_user_directory 'neovim_user_not_found_test'