diff --git a/src/misc1.c b/src/misc1.c index b391cb1ee4..e78343291b 100644 --- a/src/misc1.c +++ b/src/misc1.c @@ -3256,34 +3256,17 @@ char_u *get_env_name(expand_T *xp, int idx) * Find all user names for user completion. * Done only once and then cached. */ -static void init_users(void) { +static void init_users(void) +{ static int lazy_init_done = FALSE; - if (lazy_init_done) + if (lazy_init_done) { return; + } lazy_init_done = TRUE; - ga_init2(&ga_users, sizeof(char_u *), 20); - -# if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H) - { - char_u* user; - struct passwd* pw; - - setpwent(); - while ((pw = getpwent()) != NULL) - /* pw->pw_name shouldn't be NULL but just in case... */ - if (pw->pw_name != NULL) { - if (ga_grow(&ga_users, 1) == FAIL) - break; - user = vim_strsave((char_u*)pw->pw_name); - if (user == NULL) - break; - ((char_u **)(ga_users.ga_data))[ga_users.ga_len++] = user; - } - endpwent(); - } -# endif + + mch_get_usernames(&ga_users); } /* diff --git a/src/os/os.h b/src/os/os.h index 48e3ffd0dd..87323fb025 100644 --- a/src/os/os.h +++ b/src/os/os.h @@ -13,5 +13,6 @@ int mch_can_exe(const char_u *name); const char *mch_getenv(const char *name); int mch_setenv(const char *name, const char *value, int overwrite); char *mch_getenvname_at_index(size_t index); +int mch_get_usernames(garray_T *usernames); #endif diff --git a/src/os/users.c b/src/os/users.c new file mode 100644 index 0000000000..b392118f1b --- /dev/null +++ b/src/os/users.c @@ -0,0 +1,57 @@ +/* vi:set ts=2 sts=2 sw=2: + * + * VIM - Vi IMproved by Bram Moolenaar + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ + +/* + * users.c -- operating system user information + */ + +#include + +#include "os.h" +#include "../garray.h" +#include "../misc2.h" +#ifdef HAVE_PWD_H +# include +#endif + +/* + * Initialize users garray and fill it with os usernames. + * Return Ok for success, FAIL for failure. + */ +int mch_get_usernames(garray_T *users) +{ + if (users == NULL) { + return FALSE; + } + ga_init2(users, sizeof(char *), 20); + +# if defined(HAVE_GETPWENT) && defined(HAVE_PWD_H) + char *user; + struct passwd *pw; + + setpwent(); + while ((pw = getpwent()) != NULL) { + /* pw->pw_name shouldn't be NULL but just in case... */ + if (pw->pw_name != NULL) { + if (ga_grow(users, 1) == FAIL) { + return FAIL; + } + user = (char *)vim_strsave((char_u*)pw->pw_name); + if (user == NULL) { + return FAIL; + } + ((char **)(users->ga_data))[users->ga_len++] = user; + } + } + endpwent(); +# endif + + return OK; +} + diff --git a/test/unit/os/users.moon b/test/unit/os/users.moon new file mode 100644 index 0000000000..366407d5c8 --- /dev/null +++ b/test/unit/os/users.moon @@ -0,0 +1,52 @@ +{:cimport, :internalize, :eq, :ffi, :lib, :cstr} = require 'test.unit.helpers' + +-- fs = cimport './src/os/os.h' +-- remove these statements once 'cimport' is working properly for misc1.h +users = lib +ffi.cdef [[ +typedef struct growarray { + int ga_len; + int ga_maxlen; + int ga_itemsize; + int ga_growsize; + void *ga_data; +} garray_T; +int mch_get_usernames(garray_T *usernames); +]] + +NULL = ffi.cast 'void*', 0 +OK = 1 +FAIL = 0 + +garray_new = () -> + ffi.new 'garray_T[1]' + +garray_get_len = (array) -> + array[0].ga_len + +garray_get_item = (array, index) -> + (ffi.cast 'void **', array[0].ga_data)[index] + + +describe 'users function', -> + + describe 'mch_get_usernames', -> + + -- will probably not work on windows + current_username = os.getenv 'USER' + + it 'returns FAIL if called with NULL', -> + eq FAIL, users.mch_get_usernames NULL + + it 'fills the names garray with os usernames and returns OK', -> + ga_users = garray_new! + eq OK, users.mch_get_usernames ga_users + user_count = garray_get_len ga_users + assert.is_true user_count > 0 + current_username_found = false + for i = 0, user_count - 1 + name = ffi.string (garray_get_item ga_users, i) + if name == current_username + current_username_found = true + assert.is_true current_username_found +