Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sys: add sys_getenv() #721

Merged
merged 6 commits into from
Mar 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/re_sys.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const char *sys_arch_get(void);
const char *sys_os_get(void);
const char *sys_libre_version_get(void);
const char *sys_username(void);
int sys_getenv(char **env, const char *name);
int sys_coredump_set(bool enable);
int sys_daemon(void);
void sys_usleep(unsigned int us);
Expand Down
67 changes: 67 additions & 0 deletions src/sys/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <string.h>
#include <re_types.h>
#include <re_fmt.h>
#include <re_mem.h>
#include <re_sys.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
Expand All @@ -21,6 +22,19 @@
#include <sys/resource.h>
#endif

#ifdef WIN32
#ifndef WIN32_LEAN_AND_MEAN
#define WIN32_LEAN_AND_MEAN
#endif
#include <windows.h>
#endif

#ifdef WIN32
enum {
MAX_ENVSZ = 32767
};
#endif


/**
* Get kernel name and version
Expand Down Expand Up @@ -180,3 +194,56 @@ int sys_coredump_set(bool enable)
return ENOSYS;
#endif
}


/**
* Get an environment variable
*
* @param env Pointer to destination env var
* @param name Environment variable name
*
* @return 0 if success, otherwise errorcode
*/
int sys_getenv(char **env, const char *name)
{
if (!env || !name)
return EINVAL;

#ifdef WIN32
uint32_t rc = 1;
uint32_t bufsz = rc;
char *buf;

buf = mem_zalloc(bufsz, NULL);
if (!buf)
return ENOMEM;

while (1) {
rc = GetEnvironmentVariableA(name, buf, bufsz);
if (!rc || rc == bufsz || rc > MAX_ENVSZ) {
mem_deref(buf);
return ENODATA;
}

/* success */
if (rc < bufsz) {
*env = buf;
return 0;
}

/* failed, getenv needs more space */
bufsz = rc;
buf = mem_realloc(buf, bufsz);
if (!buf) {
mem_deref(buf);
return ENOMEM;
}
}
#else
char *tmp = getenv(name);
if (!tmp)
return ENODATA;

return str_dup(env, tmp);
#endif
}
24 changes: 24 additions & 0 deletions test/sys.c
Original file line number Diff line number Diff line change
Expand Up @@ -204,3 +204,27 @@ int test_sys_fs_fopen(void)
out:
return err;
}


int test_sys_getenv(void)
{
int err = 0;
char *env = NULL;

#ifdef WIN32
err = sys_getenv(&env, "HOMEPATH");
#else
err = sys_getenv(&env, "HOME");
#endif
TEST_ERR(err);

TEST_EQUALS(true, str_isset(env));
mem_deref(env);

err = sys_getenv(&env, "DOESNOTEXIST");
TEST_EQUALS(ENODATA, err);
err = 0;

out:
return err;
}
1 change: 1 addition & 0 deletions test/test.c
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ static const struct test tests[] = {
TEST(test_sys_fs_isdir),
TEST(test_sys_fs_isfile),
TEST(test_sys_fs_fopen),
TEST(test_sys_getenv),
TEST(test_tcp),
TEST(test_telev),
#ifdef USE_TLS
Expand Down
1 change: 1 addition & 0 deletions test/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,7 @@ int test_sys_rand(void);
int test_sys_fs_isdir(void);
int test_sys_fs_isfile(void);
int test_sys_fs_fopen(void);
int test_sys_getenv(void);
int test_tcp(void);
int test_telev(void);
int test_thread(void);
Expand Down