Skip to content

Commit

Permalink
Add IO_getenv, IO_setenv, IO_unsetenv
Browse files Browse the repository at this point in the history
  • Loading branch information
fingolfin committed Oct 18, 2022
1 parent 8b21185 commit bd20d0d
Show file tree
Hide file tree
Showing 5 changed files with 121 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ This file describes changes in the IO package.

X.Y.Z (YYYY-MM-DD)
- Change minimal required GAP version to 4.11
- Add IO_getenv, IO_setenv, IO_unsetenv

4.7.3 (2022-09-25)
- Fix a build issue where running `make clean` would break the build
Expand Down
35 changes: 35 additions & 0 deletions doc/main.xml
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ The following functions from the C library are made available as
<C>fork</C>,
<C>fstat</C>,
<C>getcwd</C>,
<C>getenv</C>,
<C>gethostbyname</C>,
<C>gethostname</C>,
<C>getpid</C>,
Expand Down Expand Up @@ -165,12 +166,14 @@ The following functions from the C library are made available as
<C>select</C>,
<C>send</C>,
<C>sendto</C>,
<C>setenv</C>,
<C>setsockopt</C>,
<C>socket</C>,
<C>stat</C>,
<C>symlink</C>,
<C>telldir</C>,
<C>unlink</C>,
<C>unsetenv</C>,
<C>write</C>. <P/>

Use the <C>man</C> command in your shell to get information about these
Expand Down Expand Up @@ -501,6 +504,17 @@ For details see <Q><C>man 3 getcwd</C></Q>.
</Description>
</ManSection>

<ManSection>
<Func Name="IO_getenv" Arg="name"
Comm="Return the value of an environment variable."/>
<Returns> a string or <K>fail</K> </Returns>
<Description>
Return the current value of the environment variable <A>name</A>.
If the variable is not in the current environment, <C>fail</C> is returned.
For details see <Q><C>man 3 getenv</C></Q>.
</Description>
</ManSection>

<ManSection>
<Func Name="IO_gethostbyname" Arg="name"
Comm="Return host information by name."/>
Expand Down Expand Up @@ -898,6 +912,17 @@ that no 7th argument is necessary.
</Description>
</ManSection>

<ManSection>
<Func Name="IO_setenv" Arg="name, value, overvwrite"
Comm="Set the value of an environment variable."/>
<Returns> <K>true</K> or <K>fail</K> </Returns>
<Description>
Set the current value of the environment variable <A>name</A> to <A>value</A>
if it has either not been set before, or <A>overwrite</A> is <C>true</C>.
For details see <Q><C>man 3 setenv</C></Q>.
</Description>
</ManSection>

<ManSection>
<Func Name="IO_setsockopt" Arg="fd, level, optname, optval"
Comm="Sets a socket option."/>
Expand Down Expand Up @@ -965,6 +990,16 @@ For details see <Q><C>man 2 unlink</C></Q>.
</Description>
</ManSection>

<ManSection>
<Func Name="IO_unsetenv" Arg="name"
Comm="Remove an environment variable."/>
<Returns> <K>true</K> or <K>fail</K> </Returns>
<Description>
Remove the environment variable <A>name</A>.
For details see <Q><C>man 3 unsetenv</C></Q>.
</Description>
</ManSection>

<ManSection>
<Func Name="IO_WaitPid" Arg="pid, wait"
Comm="Waits for the termination of a child process."/>
Expand Down
47 changes: 47 additions & 0 deletions src/io.c
Original file line number Diff line number Diff line change
Expand Up @@ -1863,6 +1863,49 @@ static Obj FuncIO_gethostname(Obj self)
}
#endif

static Obj FuncIO_getenv(Obj self, Obj name)
{
if (!IS_STRING_REP(name)) {
SyClearErrorNo();
return Fail;
}
char * res = getenv(CONST_CSTR_STRING(name));
if (res == NULL) {
SySetErrorNo();
return Fail;
}
return MakeString(res);
}

static Obj FuncIO_setenv(Obj self, Obj name, Obj value, Obj overwrite)
{
if (!IS_STRING_REP(name) || !IS_STRING_REP(value) ||
(overwrite != True && overwrite != False)) {
SyClearErrorNo();
return Fail;
}
int res = setenv(CONST_CSTR_STRING(name), CONST_CSTR_STRING(value),
overwrite == True);
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True;
}

static Obj FuncIO_unsetenv(Obj self, Obj name)
{
if (!IS_STRING_REP(name)) {
SyClearErrorNo();
return Fail;
}
int res = unsetenv(CONST_CSTR_STRING(name));
if (res < 0) {
SySetErrorNo();
return Fail;
}
return True;
}

//
// list of functions to export
Expand Down Expand Up @@ -2104,6 +2147,10 @@ static StructGVarFunc GVarFuncs[] = {
GVAR_FUNC(IO_gethostname, 0, ""),
#endif

GVAR_FUNC(IO_getenv, 1, "name"),
GVAR_FUNC(IO_setenv, 3, "name, value, overwrite"),
GVAR_FUNC(IO_unsetenv, 1, "name"),

{ 0 }

};
Expand Down
12 changes: 12 additions & 0 deletions tst/all.tst
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,10 @@ fail
gap> IsString(IO_getcwd());
true

# IO_getenv(name)
gap> IO_getenv(fail);
fail

# IO_gethostbyname(name)
gap> IO_gethostbyname(fail);
fail
Expand Down Expand Up @@ -239,6 +243,10 @@ fail
gap> IO_sendto(fail, fail, fail, fail, fail, fail);
fail

# IO_setenv(name, value, overwrite)
gap> IO_setenv(fail, fail, fail);
fail

# IO_setsockopt(fd, level, optname, optval)
gap> IO_setsockopt(fail, fail, fail, fail);
fail
Expand All @@ -262,6 +270,10 @@ gap> #IO_telldir(); # TODO: test this
gap> IO_unlink(fail);
fail

# IO_unsetenv(name)
gap> IO_unsetenv(fail);
fail

# IO_WaitPid(pid, wait)
gap> IO_WaitPid(fail, fail);
fail
Expand Down
26 changes: 26 additions & 0 deletions tst/funcs.tst
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,29 @@ gap> r:=IO_lstat(".");; IsRecord(r); Set(RecNames(r));
true
[ "atime", "blksize", "blocks", "ctime", "dev", "gid", "ino", "mode",
"mtime", "nlink", "rdev", "size", "uid" ]

#
gap> env:=RecNames(GAPInfo.SystemEnvironment)[1];;
gap> IO_getenv(env) = GAPInfo.SystemEnvironment.(env);
true

# find an environment variable name hopefully not yet set
gap> env := Concatenation("GAP_IO_TEST_VAR_", String(Random(10^15,10^16-1)));;
gap> IO_getenv(env);
fail
gap> IO_setenv(env, "A", true);
true
gap> IO_getenv(env);
"A"
gap> IO_setenv(env, "B", false);
true
gap> IO_getenv(env);
"A"
gap> IO_setenv(env, "B", true);
true
gap> IO_getenv(env);
"B"
gap> IO_unsetenv(env);
true
gap> IO_getenv(env);
fail

0 comments on commit bd20d0d

Please sign in to comment.