Use the environ table over the environment library

This commit is contained in:
Jeremy Baxter 2023-07-02 08:15:17 +12:00
parent 97f527fde8
commit c62d4056e6
5 changed files with 123 additions and 154 deletions

View file

@ -5,8 +5,8 @@ CFLAGS = -std=c99 -pedantic -fpic -O2 -Wall -Wextra -Wno-override-init -I. -Il
CPPFLAGS = -D_DEFAULT_SOURCE -DLUA_USE_READLINE CPPFLAGS = -D_DEFAULT_SOURCE -DLUA_USE_READLINE
LDFLAGS = -lm -lreadline LDFLAGS = -lm -lreadline
OBJS = csto.o lcallisto.o lcl.o lenvironment.o lextra.o \ OBJS = csto.o lcallisto.o lcl.o lenviron.o lextra.o lfile.o \
lfile.o ljson.o lmath.o los.o lprocess.o lsocket.o util.o ljson.o lmath.o los.o lprocess.o lsocket.o util.o
LIBS = liblua.a cjson.a socket.a LIBS = liblua.a cjson.a socket.a
all: csto libcallisto.so all: csto libcallisto.so
@ -25,7 +25,7 @@ csto.o: csto.c lcallisto.h
lcallisto.o: lcallisto.c lcallisto.h lcallisto.o: lcallisto.c lcallisto.h
lcl.o: lcl.c lcallisto.h lcl.o: lcl.c lcallisto.h
lextra.o: lextra.c lcallisto.h lextra.o: lextra.c lcallisto.h
lenvironment.o: lenvironment.c lcallisto.h lenviron.o: lenviron.c lcallisto.h
lfile.o: lfile.c lcallisto.h lfile.o: lfile.c lcallisto.h
ljson.o: ljson.c lcallisto.h ljson.o: ljson.c lcallisto.h
lmath.o: lmath.c lcallisto.h lmath.o: lmath.c lcallisto.h

View file

@ -11,7 +11,7 @@
static const luaL_Reg loadedlibs[] = { static const luaL_Reg loadedlibs[] = {
{CALLISTO_CLLIBNAME, callistoopen_cl}, {CALLISTO_CLLIBNAME, callistoopen_cl},
{CALLISTO_ENVLIBNAME, callistoopen_environment}, {CALLISTO_ENVLIBNAME, callistoopen_environ},
{CALLISTO_EXTLIBNAME, callistoopen_extra}, {CALLISTO_EXTLIBNAME, callistoopen_extra},
{CALLISTO_FILELIBNAME, callistoopen_file}, {CALLISTO_FILELIBNAME, callistoopen_file},
{CALLISTO_JSONLIBNAME, callistoopen_json}, {CALLISTO_JSONLIBNAME, callistoopen_json},

View file

@ -16,7 +16,7 @@
#define CALLISTO_COPYRIGHT CALLISTO_VERSION " (" LUA_RELEASE ") Copyright (C) 1994-2022 Lua.org, PUC-Rio" #define CALLISTO_COPYRIGHT CALLISTO_VERSION " (" LUA_RELEASE ") Copyright (C) 1994-2022 Lua.org, PUC-Rio"
#define CALLISTO_CLLIBNAME "cl" #define CALLISTO_CLLIBNAME "cl"
#define CALLISTO_ENVLIBNAME "environment" #define CALLISTO_ENVLIBNAME "environ"
#define CALLISTO_EXTLIBNAME "_G" /* global table */ #define CALLISTO_EXTLIBNAME "_G" /* global table */
#define CALLISTO_FILELIBNAME "file" #define CALLISTO_FILELIBNAME "file"
#define CALLISTO_JSONLIBNAME "json" #define CALLISTO_JSONLIBNAME "json"
@ -25,8 +25,10 @@
#define CALLISTO_PROCLIBNAME "process" #define CALLISTO_PROCLIBNAME "process"
#define CALLISTO_SOCKLIBNAME "socket" #define CALLISTO_SOCKLIBNAME "socket"
#define CALLISTO_ENVIRON "environ"
int callistoopen_cl(lua_State *); int callistoopen_cl(lua_State *);
int callistoopen_environment(lua_State *); int callistoopen_environ(lua_State *);
int callistoopen_extra(lua_State *); int callistoopen_extra(lua_State *);
int callistoopen_file(lua_State *); int callistoopen_file(lua_State *);
int callistoopen_json(lua_State *); int callistoopen_json(lua_State *);

115
lenviron.c Normal file
View file

@ -0,0 +1,115 @@
/***
* Getting and setting environment variables.
* @module environ
*/
#include <stdlib.h>
#include <errno.h>
#include <lua.h>
#include <lauxlib.h>
#include "lcallisto.h"
extern char **environ;
/***
* Table enabling easy access to environment
* variables.
*
* Has metamethods *\_\_index* and *\_\_newindex*,
* which allow for the table to be indexed with a
* string to get values of environment variables,
* or for fields to be set to set an environment
* variable.
*
* @table environ
* @usage
-- Print the value of an environment variable:
print(environ["MYVAR"])
-- Set an environment variable:
environ["MYVAR"] = 1
*/
/*
* Returns the value of the given environment variable.
*/
static int
environ_index(lua_State *L)
{
const char *variable; /* parameter 2 (string) */
char *ret;
variable = luaL_checkstring(L, 2);
ret = getenv(variable);
if (ret == NULL) /* no environment variable? */
lua_pushnil(L);
else
lua_pushstring(L, ret); /* push variable value */
return 1;
}
/*
* Sets the value of the given environment variable.
*/
static int
environ_newindex(lua_State *L)
{
int ret;
const char *variable; /* parameter 2 (string) */
const char *value; /* parameter 3 (string) */
variable = luaL_checkstring(L, 2);
if (lua_isnil(L, 3)) {
ret = unsetenv(variable); /* remove variable from environ */
if (ret == 0) /* did unsetenv succeed? */
return 0;
/* if unsetenv didn't succeed:
* (unsetenv only sets errno to EINVAL on error) */
return luaL_error(L, "invalid input string");
}
value = luaL_checkstring(L, 3);
ret = setenv(variable, value, 1);
if (ret == 0) /* did setenv succeed? */
return 0;
switch (errno) {
case EINVAL:
return luaL_error(L, "invalid input string");
break;
case ENOMEM:
return luaL_error(L, "insufficient memory");
break;
}
return 0;
}
static const luaL_Reg mt[] = {
{"__index", environ_index},
{"__newindex", environ_newindex},
{NULL, NULL}
};
int
callistoopen_environ(lua_State *L)
{
const luaL_Reg *lib;
lua_newtable(L);
luaL_newmetatable(L, CALLISTO_ENVIRON); /* metatable for environ */
for (lib = mt; lib->func; lib++) {
lua_pushcfunction(L, lib->func);
lua_setfield(L, -2, lib->name);
}
lua_setmetatable(L, -2);
return 1;
}

View file

@ -1,148 +0,0 @@
/***
* Getting and setting
* environment variables.
* @module environment
*/
#include <stdlib.h>
#include <errno.h>
#ifdef BSD
# include <string.h>
#endif
#include <lua.h>
#include <lauxlib.h>
#include "lcallisto.h"
#include "util.h"
extern char **environ;
/***
* Returns the value of the given environment
* variable.
*
* If *var* does not exist in the environment
* and *defaultvalue* is not nil,
* *defaultvalue* will be returned.
*
* @function get
* @usage environment.get("HOME", "/root")
* @tparam string var The environment variable to get.
* @param[opt] defaultvalue The value to return in case the environment variable was not found.
*/
static int
environment_get(lua_State *L)
{
const char *variable;
char *ret;
variable = luaL_checkstring(L, 1);
ret = getenv(variable);
if (ret == NULL)
if (!lua_isnoneornil(L, 2))
lua_pushvalue(L, 2);
else
lua_pushnil(L);
else
lua_pushstring(L, ret);
return 1;
}
/***
* Sets the value of the given environment variable.
*
* This function will throw an error if the value of
* *var* is invalid for the name of an environment
* variable, or if there is insufficient memory
* available to perform the operation.
*
* @function set
* @usage environment.set("MYVAR", "1")
* @tparam string var The environment variable to set.
* @tparam string value The value to set for *var*.
*/
static int
environment_set(lua_State *L)
{
int ret;
const char *variable;
const char *value;
variable = luaL_checkstring(L, 1);
value = luaL_checkstring(L, 2);
ret = setenv(variable, value, 1);
if (ret == 0)
return 0;
switch (errno) {
case EINVAL:
return luaL_error(L, "invalid input string");
break;
case ENOMEM:
return luaL_error(L, "insufficient memory");
break;
}
return 0;
}
/***
* Clears the environment.
*
* If *var* is not nil, only clears the value of that
* environment variable (not the whole environment).
*
* This function will throw an error if the value of
* *var* is invalid for the name of an environment
* variable, or if there is insufficient memory
* available to perform the operation.
*
* @function clear
* @usage environment.clear("MYVAR")
* @tparam[opt] string var The environment variable to clear.
*/
static int
environment_clear(lua_State *L)
{
const char *variable;
int ret;
if (lua_isnoneornil(L, 1)) {
environ = NULL;
return 0;
}
variable = luaL_checkstring(L, 1);
ret = unsetenv(variable);
if (ret == 0)
return 0;
switch (errno) {
case EINVAL:
return luaL_error(L, "invalid input string");
break;
case ENOMEM:
return luaL_error(L, "insufficient memory");
break;
}
return 0;
}
static const luaL_Reg envlib[] = {
{"get", environment_get},
{"set", environment_set},
{"clear", environment_clear},
{NULL, NULL}
};
int
callistoopen_environment(lua_State *L)
{
luaL_newlib(L, envlib);
return 1;
}