forked from ground/ground-old
Ground -> unistd interface
This commit is contained in:
316
libs/unistd/unistd.c
Normal file
316
libs/unistd/unistd.c
Normal file
@@ -0,0 +1,316 @@
|
||||
#include <errno.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <groundvm.h>
|
||||
#include <groundext.h>
|
||||
|
||||
// Allows Ground to access the POSIX standard library.
|
||||
// Read more here: https://en.wikipedia.org/wiki/Unistd.h
|
||||
|
||||
// Misc functions
|
||||
|
||||
GroundValue groundCrypt(GroundScope* scope, List args) {
|
||||
char* hash = crypt(args.values[0].data.stringVal, args.values[1].data.stringVal);
|
||||
if (hash == NULL) {
|
||||
ERROR(strerror(errno), "CryptError");
|
||||
}
|
||||
return groundCreateValue(STRING, hash);
|
||||
}
|
||||
|
||||
GroundValue groundGetHostId(GroundScope* scope, List args) {
|
||||
return groundCreateValue(INT, (int64_t) gethostid());
|
||||
}
|
||||
|
||||
GroundValue groundSetHostId(GroundScope* scope, List args) {
|
||||
int result = sethostid((long) args.values[0].data.intVal);
|
||||
if (result < 0) {
|
||||
ERROR(strerror(errno), "SetHostIdError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
GroundValue groundGetHostname(GroundScope* scope, List args) {
|
||||
char* buf = malloc(256);
|
||||
if (buf == NULL) {
|
||||
ERROR("Couldn't allocate memory to store hostname", "GetHostnameError");
|
||||
}
|
||||
int result = gethostname(buf, 255);
|
||||
if (result < 0) {
|
||||
ERROR(strerror(errno), "GetHostnameError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
GroundValue groundSetHostname(GroundScope* scope, List args) {
|
||||
int result = sethostname(args.values[0].data.stringVal, strlen(args.values[0].data.stringVal));
|
||||
if (result < 0) {
|
||||
ERROR(strerror(errno), "SetHostnameError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
// Signals
|
||||
|
||||
GroundValue groundAlarm(GroundScope* scope, List args) {
|
||||
unsigned result = alarm((unsigned) args.values[0].data.intVal);
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
GroundValue groundPause(GroundScope* scope, List args) {
|
||||
int result = pause();
|
||||
ERROR(strerror(errno), "PauseError");
|
||||
}
|
||||
|
||||
// Filesystem
|
||||
|
||||
GroundValue groundAccess(GroundScope* scope, List args) {
|
||||
int result = access(args.values[0].data.stringVal, (int) args.values[1].data.intVal);
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
GroundValue groundChdir(GroundScope* scope, List args) {
|
||||
int result = chdir(args.values[0].data.stringVal);
|
||||
if (result < 0) {
|
||||
ERROR(strerror(errno), "ChdirError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
GroundValue groundChown(GroundScope* scope, List args) {
|
||||
int result = chown(args.values[0].data.stringVal, (uid_t) args.values[1].data.intVal, (gid_t) args.values[2].data.intVal);
|
||||
if (result < 0) {
|
||||
ERROR(strerror(errno), "ChownError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
GroundValue groundLink(GroundScope* scope, List args) {
|
||||
int result = link(args.values[0].data.stringVal, args.values[1].data.stringVal);
|
||||
if (result < 1) {
|
||||
ERROR(strerror(errno), "LinkError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
GroundValue groundRmdir(GroundScope* scope, List args) {
|
||||
int result = rmdir(args.values[0].data.stringVal);
|
||||
if (result < 1) {
|
||||
ERROR(strerror(errno), "RmdirError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
GroundValue groundSymlink(GroundScope* scope, List args) {
|
||||
int result = symlink(args.values[0].data.stringVal, args.values[1].data.stringVal);
|
||||
if (result < 1) {
|
||||
ERROR(strerror(errno), "SymlinkError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
// Process
|
||||
|
||||
GroundValue groundExit(GroundScope* scope, List args) {
|
||||
_exit(args.values[0].data.intVal);
|
||||
ERROR("Couldn't exit (huh?)", "ExitError");
|
||||
}
|
||||
|
||||
GroundValue groundExecv(GroundScope* scope, List args) {
|
||||
char** argv = malloc(sizeof(char*) * args.values[1].data.listVal.size + 1);
|
||||
if (argv == NULL) {
|
||||
ERROR("Couldn't allocate memory for execv list", "ExecvError");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < args.values[1].data.listVal.size; i++) {
|
||||
if (args.values[1].data.listVal.values[i].type != STRING) {
|
||||
ERROR("Expecting all arguments in list to be of String type", "ExecvError");
|
||||
}
|
||||
argv[i] = args.values[1].data.listVal.values[i].data.stringVal;
|
||||
}
|
||||
argv[args.values[1].data.listVal.size] = NULL;
|
||||
|
||||
int result = execv(args.values[0].data.stringVal, argv);
|
||||
|
||||
ERROR(strerror(errno), "ExecvError");
|
||||
}
|
||||
|
||||
GroundValue groundExecvp(GroundScope* scope, List args) {
|
||||
char** argv = malloc(sizeof(char*) * args.values[1].data.listVal.size + 1);
|
||||
if (argv == NULL) {
|
||||
ERROR("Couldn't allocate memory for execv list", "ExecvpError");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < args.values[1].data.listVal.size; i++) {
|
||||
if (args.values[1].data.listVal.values[i].type != STRING) {
|
||||
ERROR("Expecting all arguments in list to be of String type", "ExecvpError");
|
||||
}
|
||||
argv[i] = args.values[1].data.listVal.values[i].data.stringVal;
|
||||
}
|
||||
argv[args.values[1].data.listVal.size] = NULL;
|
||||
|
||||
int result = execvp(args.values[0].data.stringVal, argv);
|
||||
|
||||
ERROR(strerror(errno), "ExecvpError");
|
||||
}
|
||||
|
||||
GroundValue groundFork(GroundScope* scope, List args) {
|
||||
pid_t id = fork();
|
||||
if (id < 0) {
|
||||
ERROR(strerror(errno), "ForkError");
|
||||
}
|
||||
return groundCreateValue(INT, id);
|
||||
}
|
||||
|
||||
GroundValue groundGetPid(GroundScope* scope, List args) {
|
||||
return groundCreateValue(INT, (int64_t) getpid());
|
||||
}
|
||||
|
||||
GroundValue groundGetPPid(GroundScope* scope, List args) {
|
||||
return groundCreateValue(INT, (int64_t) getppid());
|
||||
}
|
||||
|
||||
GroundValue groundGetSid(GroundScope* scope, List args) {
|
||||
pid_t result = getsid((pid_t) args.values[0].data.intVal);
|
||||
if (result < 0) {
|
||||
ERROR(strerror(errno), "GetSidError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
GroundValue groundNice(GroundScope* scope, List args) {
|
||||
int result = nice((int) args.values[0].data.intVal);
|
||||
if (result < 0) {
|
||||
ERROR(strerror(errno), "NiceError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
GroundValue groundSetSid(GroundScope* scope, List args) {
|
||||
pid_t result = setsid();
|
||||
if (result < 0) {
|
||||
ERROR(strerror(errno), "SetSidError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
GroundValue groundSleep(GroundScope* scope, List args) {
|
||||
unsigned int result = sleep((unsigned int) args.values[0].data.intVal);
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
// User/Group
|
||||
|
||||
GroundValue groundGetGid(GroundScope* scope, List args) {
|
||||
return groundCreateValue(INT, (int64_t) getgid());
|
||||
}
|
||||
|
||||
GroundValue groundGetEGid(GroundScope* scope, List args) {
|
||||
return groundCreateValue(INT, (int64_t) getegid());
|
||||
}
|
||||
|
||||
GroundValue groundGetUid(GroundScope* scope, List args) {
|
||||
return groundCreateValue(INT, (int64_t) getuid());
|
||||
}
|
||||
|
||||
GroundValue groundGetEUid(GroundScope* scope, List args) {
|
||||
return groundCreateValue(INT, (int64_t) geteuid());
|
||||
}
|
||||
|
||||
GroundValue groundGetLogin(GroundScope* scope, List args) {
|
||||
char* login = getlogin();
|
||||
if (login == NULL) {
|
||||
ERROR(strerror(errno), "GetLoginError");
|
||||
}
|
||||
return groundCreateValue(STRING, login);
|
||||
}
|
||||
|
||||
GroundValue groundSetEUid(GroundScope* scope, List args) {
|
||||
int result = seteuid((uid_t) args.values[0].data.intVal);
|
||||
if (result < -1) {
|
||||
ERROR(strerror(errno), "SetEUidError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
GroundValue groundSetEGid(GroundScope* scope, List args) {
|
||||
int result = setegid((uid_t) args.values[0].data.intVal);
|
||||
if (result < -1) {
|
||||
ERROR(strerror(errno), "SetEGidError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
GroundValue groundSetREUid(GroundScope* scope, List args) {
|
||||
int result = setreuid((uid_t) args.values[0].data.intVal, (uid_t) args.values[1].data.intVal);
|
||||
if (result < -1) {
|
||||
ERROR(strerror(errno), "SetREUidError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
GroundValue groundSetREGid(GroundScope* scope, List args) {
|
||||
int result = setregid((gid_t) args.values[0].data.intVal, (gid_t) args.values[1].data.intVal);
|
||||
if (result < -1) {
|
||||
ERROR(strerror(errno), "SetREGidError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
GroundValue groundSetUid(GroundScope* scope, List args) {
|
||||
int result = setuid((uid_t) args.values[0].data.intVal);
|
||||
if (result < -1) {
|
||||
ERROR(strerror(errno), "SetUidError");
|
||||
}
|
||||
return groundCreateValue(INT, (int64_t) result);
|
||||
}
|
||||
|
||||
void ground_init(GroundScope* scope) {
|
||||
|
||||
// Misc
|
||||
groundAddNativeFunction(scope, "unistd_Crypt", groundCrypt, STRING, 2, STRING, "key", STRING, "value");
|
||||
groundAddNativeFunction(scope, "unistd_GetHostId", groundGetHostId, STRING, 0);
|
||||
groundAddNativeFunction(scope, "unistd_SetHostId", groundSetHostId, INT, 1, INT, "hostid");
|
||||
groundAddNativeFunction(scope, "unistd_GetHostname", groundGetHostname, INT, 0);
|
||||
groundAddNativeFunction(scope, "unistd_SetHostname", groundGetHostname, INT, 1, STRING, "name");
|
||||
|
||||
// Signals
|
||||
groundAddNativeFunction(scope, "unistd_Alarm", groundAlarm, INT, 1, INT, "seconds");
|
||||
groundAddNativeFunction(scope, "unistd_Pause", groundPause, INT, 0);
|
||||
|
||||
// Filesystem
|
||||
groundAddValueToScope(scope, "unistd_F_OK", groundCreateValue(INT, F_OK));
|
||||
groundAddValueToScope(scope, "unistd_R_OK", groundCreateValue(INT, R_OK));
|
||||
groundAddValueToScope(scope, "unistd_W_OK", groundCreateValue(INT, W_OK));
|
||||
groundAddValueToScope(scope, "unistd_X_OK", groundCreateValue(INT, X_OK));
|
||||
|
||||
groundAddNativeFunction(scope, "unistd_Access", groundAccess, INT, 2, STRING, "path", INT, "mode");
|
||||
groundAddNativeFunction(scope, "unistd_Chdir", groundAccess, INT, 1, STRING, "path");
|
||||
groundAddNativeFunction(scope, "unistd_Chown", groundChown, INT, 3, STRING, "path", INT, "owner", INT, "group");
|
||||
groundAddNativeFunction(scope, "unistd_Link", groundLink, INT, 2, STRING, "oldpath", STRING, "newpath");
|
||||
groundAddNativeFunction(scope, "unistd_Rmdir", groundRmdir, INT, 1, STRING, "path");
|
||||
groundAddNativeFunction(scope, "unistd_Symlink", groundSymlink, INT, 2, STRING, "target", STRING, "linkpath");
|
||||
|
||||
// Process
|
||||
groundAddNativeFunction(scope, "unistd_Exit", groundExit, INT, 1, INT, "status");
|
||||
groundAddNativeFunction(scope, "unistd_Execv", groundExecv, INT, 2, STRING, "path", LIST, "argv");
|
||||
groundAddNativeFunction(scope, "unistd_Execvp", groundExecvp, INT, 2, STRING, "path", LIST, "argv");
|
||||
groundAddNativeFunction(scope, "unistd_Fork", groundFork, INT, 0);
|
||||
groundAddNativeFunction(scope, "unistd_GetPid", groundGetPid, INT, 0);
|
||||
groundAddNativeFunction(scope, "unistd_GetPPid", groundGetPPid, INT, 0);
|
||||
groundAddNativeFunction(scope, "unistd_GetSid", groundGetSid, INT, 1, INT, "pid");
|
||||
groundAddNativeFunction(scope, "unistd_Nice", groundNice, INT, 1, INT, "inc");
|
||||
groundAddNativeFunction(scope, "unistd_SetSid", groundSetSid, INT, 0);
|
||||
groundAddNativeFunction(scope, "unistd_Sleep", groundSleep, INT, 1, INT, "seconds");
|
||||
|
||||
// User/Group
|
||||
groundAddNativeFunction(scope, "unistd_GetGid", groundGetGid, INT, 0);
|
||||
groundAddNativeFunction(scope, "unistd_GetEGid", groundGetEGid, INT, 0);
|
||||
groundAddNativeFunction(scope, "unistd_GetUid", groundGetUid, INT, 0);
|
||||
groundAddNativeFunction(scope, "unistd_GetEUid", groundGetEUid, INT, 0);
|
||||
groundAddNativeFunction(scope, "unistd_GetLogin", groundGetLogin, STRING, 0);
|
||||
groundAddNativeFunction(scope, "unistd_SetEUid", groundSetEUid, INT, 1, INT, "euid");
|
||||
groundAddNativeFunction(scope, "unistd_SetEGid", groundSetEGid, INT, 1, INT, "euid");
|
||||
groundAddNativeFunction(scope, "unistd_SetREUid", groundSetEGid, INT, 1, INT, "ruid", INT, "euid");
|
||||
groundAddNativeFunction(scope, "unistd_SetREGid", groundSetEGid, INT, 1, INT, "rgid", INT, "egid");
|
||||
}
|
||||
Reference in New Issue
Block a user