/* * mount constants * */ ssize_t alcove_sys_mount_define(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { int index = 0; int rindex = 0; char name[MAXATOMLEN] = {0}; /* flag */ 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_mount_constants)); return rindex; }
/* * fcntl contants * */ ssize_t alcove_sys_fcntl_constant(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { int index = 0; int rindex = 0; char name[MAXATOMLEN] = {0}; UNUSED(ap); /* constant */ if (alcove_decode_atom(arg, len, &index, name) < 0) return -1; ALCOVE_ERR(alcove_encode_version(reply, rlen, &rindex)); ALCOVE_ERR(alcove_encode_constant(reply, rlen, &rindex, name, alcove_fcntl_constants)); return rindex; }
/* * 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 }
/* * readdir(3) * */ ssize_t alcove_sys_readdir(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { int index = 0; int rindex = 0; char name[PATH_MAX] = {0}; size_t namelen = sizeof(name)-1; DIR *dirp = NULL; struct dirent *dent = NULL; UNUSED(ap); /* name */ if (alcove_decode_iolist(arg, len, &index, name, &namelen) < 0 || namelen == 0) return -1; dirp = opendir(name); if (dirp == NULL) return alcove_mk_errno(reply, rlen, errno); ALCOVE_ERR(alcove_encode_version(reply, rlen, &rindex)); ALCOVE_ERR(alcove_encode_tuple_header(reply, rlen, &rindex, 2)); ALCOVE_ERR(alcove_encode_atom(reply, rlen, &rindex, "ok")); errno = 0; while ( (dent = readdir(dirp))) { ALCOVE_ERR(alcove_encode_list_header(reply, rlen, &rindex, 1)); ALCOVE_ERR(alcove_encode_binary(reply, rlen, &rindex, dent->d_name, strlen(dent->d_name))); } if (errno != 0) return alcove_mk_errno(reply, rlen, errno); if (closedir(dirp) < 0) return alcove_mk_errno(reply, rlen, errno); ALCOVE_ERR(alcove_encode_empty_list(reply, rlen, &rindex)); return rindex; }
/* * getrlimit(2) * */ ssize_t alcove_sys_getrlimit(alcove_state_t *ap, const char *arg, size_t len, char *reply, size_t rlen) { int index = 0; int rindex = 0; int resource = 0; struct rlimit rlim = {0}; int rv = 0; /* resource */ switch (alcove_decode_define(arg, len, &index, &resource, alcove_rlimit_constants)) { case 0: break; case 1: return alcove_mk_error(reply, rlen, "unsupported"); default: return -1; } rv = getrlimit(resource, &rlim); if (rv < 0) return alcove_mk_errno(reply, rlen, errno); ALCOVE_ERR(alcove_encode_version(reply, rlen, &rindex)); ALCOVE_ERR(alcove_encode_tuple_header(reply, rlen, &rindex, 2)); ALCOVE_ERR(alcove_encode_atom(reply, rlen, &rindex, "ok")); ALCOVE_ERR(alcove_encode_tuple_header(reply, rlen, &rindex, 3)); ALCOVE_ERR(alcove_encode_atom(reply, rlen, &rindex, "alcove_rlimit")); ALCOVE_ERR(alcove_encode_ulonglong(reply, rlen, &rindex, rlim.rlim_cur)); ALCOVE_ERR(alcove_encode_ulonglong(reply, rlen, &rindex, rlim.rlim_max)); return rindex; }
/* * 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 }