/* * clearenv(3) * */ ssize_t alcove_sys_clearenv(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { #ifdef __linux__ int rv = 0; UNUSED(ap); UNUSED(arg); UNUSED(len); rv = clearenv(); return (rv < 0) ? alcove_mk_errno(reply, rlen, errno) : alcove_mk_atom(reply, rlen, "ok"); #else UNUSED(ap); UNUSED(arg); UNUSED(len); environ = NULL; return alcove_mk_atom(reply, rlen, "ok"); #endif }
/* * umount(2) * */ ssize_t alcove_sys_umount(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { int index = 0; char source[PATH_MAX] = {0}; size_t slen = sizeof(source)-1; int rv = 0; UNUSED(ap); /* source */ if (alcove_decode_iolist(arg, len, &index, source, &slen) < 0 || slen == 0) return -1; #if defined(__linux__) || defined(__sunos__) rv = umount(source); #else rv = unmount(source, 0); #endif return (rv < 0) ? alcove_mk_errno(reply, rlen, errno) : alcove_mk_atom(reply, rlen, "ok"); }
ssize_t alcove_sys_setenv(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { int index = 0; char name[MAXMSGLEN] = {0}; size_t namelen = sizeof(name)-1; char value[MAXMSGLEN] = {0}; size_t valuelen = sizeof(value)-1; int overwrite = 0; int rv = 0; UNUSED(ap); /* name */ if (alcove_decode_iolist(arg, len, &index, name, &namelen) < 0 || namelen == 0) return -1; /* value */ if (alcove_decode_iolist(arg, len, &index, value, &valuelen) < 0) return -1; /* overwrite */ if (alcove_decode_int(arg, len, &index, &overwrite) < 0) return -1; rv = setenv(name, value, overwrite); return (rv < 0) ? alcove_mk_errno(reply, rlen, errno) : alcove_mk_atom(reply, rlen, "ok"); }
/* * chown(2) * */ ssize_t alcove_sys_chown(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { int index = 0; char path[PATH_MAX] = {0}; size_t plen = sizeof(path)-1; uid_t owner = {0}; gid_t group = {0}; int rv = 0; /* path */ if (alcove_decode_iolist(arg, len, &index, path, &plen) < 0 || plen == 0) return -1; /* owner */ if (alcove_decode_uint(arg, len, &index, &owner) < 0) return -1; /* group */ if (alcove_decode_uint(arg, len, &index, &group) < 0) return -1; rv = chown(path, owner, group); return (rv < 0) ? alcove_mk_errno(reply, rlen, errno) : alcove_mk_atom(reply, rlen, "ok"); }
/* * kill(2) * */ ssize_t alcove_sys_kill(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { int index = 0; pid_t pid = 0; int signum = 0; int rv = 0; UNUSED(ap); /* pid */ if (alcove_decode_int(arg, len, &index, &pid) < 0) return -1; /* signal */ switch (alcove_decode_constant(arg, len, &index, &signum, alcove_signal_constants)) { case 0: break; case 1: return alcove_mk_error(reply, rlen, "enotsup"); default: return -1; } rv = kill(pid, signum); return (rv < 0) ? alcove_mk_errno(reply, rlen, errno) : alcove_mk_atom(reply, rlen, "ok"); }
/* * close(2) * */ ssize_t alcove_sys_close(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { int index = 0; int fd = 0; /* fd */ if (alcove_decode_int(arg, len, &index, &fd) < 0) return -1; return (close(fd) < 0) ? alcove_mk_errno(reply, rlen, errno) : alcove_mk_atom(reply, rlen, "ok"); }
/* * rmdir(2) * */ ssize_t alcove_sys_rmdir(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { int index = 0; char pathname[PATH_MAX] = {0}; size_t pathlen = sizeof(pathname)-1; int rv = 0; /* pathname */ if (alcove_decode_iolist(arg, len, &index, pathname, &pathlen) < 0 || pathlen == 0) return -1; rv = rmdir(pathname); return (rv < 0) ? alcove_mk_errno(reply, rlen, errno) : alcove_mk_atom(reply, rlen, "ok"); }
/* * syscalls * */ ssize_t alcove_sys_syscall_define(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { #ifdef __linux__ int index = 0; int rindex = 0; char name[MAXATOMLEN] = {0}; /* name */ if (alcove_decode_atom(arg, len, &index, name) < 0) return -1; ALCOVE_ERR(alcove_encode_version(reply, rlen, &rindex)); ALCOVE_ERR(alcove_encode_define(reply, rlen, &rindex, name, alcove_syscall_constants)); return rindex; #else return alcove_mk_atom(reply, rlen, "false"); #endif }
/* * cap_fcntls_get(2) * */ ssize_t alcove_sys_cap_fcntls_get(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { #if defined(__FreeBSD__) int index = 0; int rindex = 0; int rv = 0; int fd = -1; uint32_t rights = 0; UNUSED(ap); /* fd */ if (alcove_decode_int(arg, len, &index, &fd) < 0) return -1; rv = cap_fcntls_get(fd, &rights); if (rv < 0) return alcove_mk_errno(reply, rlen, errno); ALCOVE_OK( reply, rlen, &rindex, alcove_encode_ulong(reply, rlen, &rindex, rights) ); return rindex; #else UNUSED(ap); UNUSED(arg); UNUSED(len); return alcove_mk_atom(reply, rlen, "undef"); #endif }
/* * setpriority(2) */ ssize_t alcove_sys_setpriority(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { int index = 0; int which = 0; int who = 0; int prio = 0; switch (alcove_decode_define(arg, len, &index, &which, alcove_prio_constants)) { case 0: break; case 1: return alcove_mk_error(reply, rlen, "unsupported"); default: return -1; } switch (alcove_decode_define(arg, len, &index, &who, alcove_prio_constants)) { case 0: break; case 1: return alcove_mk_error(reply, rlen, "unsupported"); default: return -1; } if (alcove_decode_int(arg, len, &index, &prio) < 0) return -1; if (setpriority(which, who, prio) < 0) return alcove_mk_errno(reply, rlen, errno); return alcove_mk_atom(reply, rlen, "ok"); }
/* * setgroups(2) * */ ssize_t alcove_sys_setgroups(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { int index = 0; gid_t *list = NULL; int n; int type = 0; int arity = 0; UNUSED(ap); if (alcove_get_type(arg, len, &index, &type, &arity) < 0) return -1; if (arity > 0) { list = calloc(arity, sizeof(gid_t)); if (list == NULL) return alcove_mk_errno(reply, rlen, errno); } if (alcove_list_to_groups(arg, len, &index, type, list, arity) < 0) { free(list); return -1; } n = setgroups(arity, list); if (n < 0) { free(list); return alcove_mk_errno(reply, rlen, errno); } free(list); return alcove_mk_atom(reply, rlen, "ok"); }
/* * ptrace(2) * */ ssize_t alcove_sys_ptrace(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { #if defined(__linux__) int index = 0; int rindex = 0; int type = 0; int arity = 0; int request = 0; pid_t pid = 0; alcove_ptrace_arg_t addr = {0}; alcove_ptrace_arg_t data = {0}; alcove_alloc_t *elem = NULL; ssize_t nelem = 0; long rv = 0; UNUSED(ap); /* request */ switch (alcove_decode_constant(arg, len, &index, &request, alcove_ptrace_constants)) { case 0: break; case 1: return alcove_mk_error(reply, rlen, "enotsup"); default: return -1; } /* pid */ if (alcove_decode_int(arg, len, &index, &pid) < 0) return -1; /* addr */ if (alcove_get_type(arg, len, &index, &type, &arity) < 0) return -1; switch (type) { case ERL_SMALL_INTEGER_EXT: case ERL_INTEGER_EXT: addr.type = ALCOVE_PTRACEARG_INT; if (alcove_decode_ulong(arg, len, &index, &addr.arg) < 0) return -1; break; case ERL_LIST_EXT: addr.type = ALCOVE_PTRACEARG_CSTRUCT; addr.len = sizeof(addr.data); if (alcove_decode_cstruct(arg, len, &index, addr.data, &(addr.len), &elem, &nelem) < 0) return -1; break; case ERL_BINARY_EXT: addr.type = ALCOVE_PTRACEARG_BINARY; if (arity > sizeof(addr.data)) return -1; if (alcove_decode_binary(arg, len, &index, addr.data, &addr.len) < 0) return -1; break; default: return -1; } /* data */ if (alcove_get_type(arg, len, &index, &type, &arity) < 0) return -1; switch (type) { case ERL_SMALL_INTEGER_EXT: case ERL_INTEGER_EXT: data.type = ALCOVE_PTRACEARG_INT; if (alcove_decode_ulong(arg, len, &index, &data.arg) < 0) return -1; break; case ERL_LIST_EXT: data.type = ALCOVE_PTRACEARG_CSTRUCT; data.len = sizeof(data.data); if (alcove_decode_cstruct(arg, len, &index, data.data, &(data.len), &elem, &nelem) < 0) return -1; break; case ERL_BINARY_EXT: data.type = ALCOVE_PTRACEARG_BINARY; if (arity > sizeof(data.data)) return -1; if (alcove_decode_binary(arg, len, &index, data.data, &data.len) < 0) return -1; break; default: return -1; } errno = 0; rv = ptrace(request, pid, PRTRACEARG(addr), PRTRACEARG(data)); if (errno) return alcove_mk_errno(reply, rlen, errno); ALCOVE_ERR(alcove_encode_version(reply, rlen, &rindex)); ALCOVE_ERR(alcove_encode_tuple_header(reply, rlen, &rindex, 4)); ALCOVE_ERR(alcove_encode_atom(reply, rlen, &rindex, "ok")); ALCOVE_ERR(alcove_encode_long(reply, rlen, &rindex, rv)); switch (addr.type) { case ALCOVE_PTRACEARG_CSTRUCT: ALCOVE_ERR(alcove_encode_cstruct(reply, rlen, &rindex, addr.data, addr.len, elem, nelem)); break; case ALCOVE_PTRACEARG_INT: /* return an empty binary */ case ALCOVE_PTRACEARG_BINARY: ALCOVE_ERR(alcove_encode_binary(reply, rlen, &rindex, addr.data, addr.len)); break; default: return -1; } switch (data.type) { case ALCOVE_PTRACEARG_CSTRUCT: ALCOVE_ERR(alcove_encode_cstruct(reply, rlen, &rindex, data.data, data.len, elem, nelem)); break; case ALCOVE_PTRACEARG_INT: /* return an empty binary */ case ALCOVE_PTRACEARG_BINARY: ALCOVE_ERR(alcove_encode_binary(reply, rlen, &rindex, data.data, data.len)); break; default: return -1; } return rindex; #else UNUSED(ap); UNUSED(arg); UNUSED(len); return alcove_mk_atom(reply, rlen, "undef"); #endif }