#define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "py/runtime.h" #include "py/smallint.h" /* Module "_posix". This module provides the most common POSIX functions and system calls for MicroPython. */ #define MP_OBJ_NEW_INT_LL(value) \ ((MP_SMALL_INT_FITS(value)) ? (mp_obj_new_int(value)) : \ (mp_obj_new_int_from_ll(value))) /* extern char **environ; */ static mp_obj_t posixmod__environ(void) { extern char **environ; mp_obj_t environ_list_obj; char **ptr; environ_list_obj = mp_obj_new_list(0, NULL); for (ptr = environ; *ptr; ptr++) { mp_obj_list_append(environ_list_obj, mp_obj_new_str_from_cstr(*ptr)); } return environ_list_obj; } static MP_DEFINE_CONST_FUN_OBJ_0(posixmod__environ_obj, posixmod__environ); /* */ static mp_obj_t posixmod_fcntl(mp_obj_t fd_obj, mp_obj_t cmd_obj, mp_obj_t flags_obj) { int res, fd, cmd, flags; fd = mp_obj_get_int(fd_obj); cmd = mp_obj_get_int(cmd_obj); switch (cmd) { case F_DUPFD: case F_GETFL: case F_GETFD: case F_GETOWN: res = fcntl(fd, cmd); if (res == -1) { mp_raise_OSError(errno); } return mp_obj_new_int(res); case F_SETFL: case F_SETFD: case F_SETOWN: flags = mp_obj_get_int(flags_obj); res = fcntl(fd, cmd, flags); if (res == -1) { mp_raise_OSError(errno); } return mp_obj_new_int(res); default: mp_raise_NotImplementedError(MP_ERROR_TEXT("fcntl() for specified cmd " "is not implemented")); return mp_const_none; } } static MP_DEFINE_CONST_FUN_OBJ_3(posixmod_fcntl_obj, posixmod_fcntl); static mp_obj_t posixmod_open(mp_obj_t path_obj, mp_obj_t flags_obj, mp_obj_t mode_obj) { int fd, flags; long long mode_ll; mode_t mode; const char *path; path = mp_obj_str_get_str(path_obj); flags = mp_obj_get_int(flags_obj); mode_ll = mp_obj_get_ll(mode_obj); mode = (mode_t) mode_ll; if (mode_ll != mode /* overflow */) { mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("overflow converting integer to mode_t")); } fd = open(path, flags, mode); if (fd < 0) { mp_raise_OSError(errno); } return mp_obj_new_int(fd); } static MP_DEFINE_CONST_FUN_OBJ_3(posixmod_open_obj, posixmod_open); /* */ static mp_obj_t posixmod_gai_strerror(mp_obj_t errnum_obj) { char buf[64]; int errnum; const char *errstr; errnum = mp_obj_get_int(errnum_obj); errno = 0; errstr = gai_strerror(errnum); if (errno || !errstr) { snprintf(buf, sizeof(buf), "Unknown error %d", errnum); errstr = buf; } return mp_obj_new_str_from_cstr(errstr); } static MP_DEFINE_CONST_FUN_OBJ_1(posixmod_gai_strerror_obj, posixmod_gai_strerror); static mp_obj_t posixmod_getaddrinfo(size_t n_args, const mp_obj_t *args) { int res, family, type, proto, flags; const char *host, *port; struct addrinfo hints, *pai, *p; mp_obj_t ai_items[5], tuple_obj, ret_obj; if (n_args != 6) { mp_raise_ValueError(NULL); } ret_obj = mp_obj_new_list(0, NULL); host = mp_obj_str_get_str(args[0]); port = mp_obj_str_get_str(args[1]); family = mp_obj_get_int(args[2]); type = mp_obj_get_int(args[3]); proto = mp_obj_get_int(args[4]); flags = mp_obj_get_int(args[5]); memset(&hints, 0, sizeof(hints)); hints.ai_family = family; hints.ai_socktype = type; hints.ai_protocol = proto; hints.ai_flags = flags; res = getaddrinfo(host, port, &hints, &pai); if (res) { mp_raise_OSError(res); } for (p = pai; p; p = p->ai_next) { ai_items[0] = mp_obj_new_int(pai->ai_family); ai_items[1] = mp_obj_new_int(pai->ai_socktype); ai_items[2] = mp_obj_new_int(pai->ai_protocol); if (pai->ai_canonname) { ai_items[3] = mp_obj_new_str_from_cstr(pai->ai_canonname); } else { ai_items[3] = mp_obj_new_str(NULL, 0); } ai_items[4] = mp_obj_new_bytearray(pai->ai_addrlen, pai->ai_addr); tuple_obj = mp_obj_new_tuple(5, ai_items); mp_obj_list_append(ret_obj, tuple_obj); } freeaddrinfo(pai); return ret_obj; } static MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(posixmod_getaddrinfo_obj, 6, 6, posixmod_getaddrinfo); static mp_obj_t posixmod_getnameinfo(mp_obj_t sockaddr_obj, mp_obj_t flags_obj) { int res, flags; mp_buffer_info_t bufinfo; char host[NI_MAXHOST] = {0}, service[NI_MAXSERV] = {0}; mp_obj_t ret_items[2]; mp_get_buffer_raise(sockaddr_obj, &bufinfo, MP_BUFFER_READ); flags = mp_obj_get_int(flags_obj); res = getnameinfo((struct sockaddr *) bufinfo.buf, bufinfo.len, host, sizeof(host), service, sizeof(service), flags); if (res) { mp_raise_OSError(res); } ret_items[0] = mp_obj_new_str_from_cstr(host); ret_items[1] = mp_obj_new_str_from_cstr(service); return mp_obj_new_tuple(2, ret_items); } static MP_DEFINE_CONST_FUN_OBJ_2(posixmod_getnameinfo_obj, posixmod_getnameinfo); /* */ static mp_obj_t sigdict_obj = NULL; static void sighandler(int signalnum) { if (!sigdict_obj) { return; } mp_obj_t signalnum_obj = mp_obj_new_int(signalnum); mp_map_elem_t *elem = mp_map_lookup(&((mp_obj_dict_t *) sigdict_obj)->map, signalnum_obj, MP_MAP_LOOKUP); if (!elem || !elem->value || !mp_obj_is_callable(elem->value)) { return; } mp_call_function_2(elem->value, signalnum_obj, mp_const_none); } static mp_obj_t posixmod_signal(mp_obj_t signalnum_obj, mp_obj_t handler_obj) { int signalnum; long long handler_ll; sighandler_t handler; mp_map_elem_t *elem; mp_obj_t old_handler_obj; if (!sigdict_obj) { sigdict_obj = mp_obj_new_dict(0); } if (!mp_obj_is_int(signalnum_obj)) { mp_raise_TypeError(MP_ERROR_TEXT("signalnum must be an interger")); } signalnum = mp_obj_get_int(signalnum_obj); elem = mp_map_lookup(&((mp_obj_dict_t *) sigdict_obj)->map, signalnum_obj, MP_MAP_LOOKUP); if (elem && elem->value) { old_handler_obj = elem->value; } else { old_handler_obj = MP_OBJ_NEW_INT_LL((intptr_t) SIG_DFL); } if (mp_obj_is_callable(handler_obj)) { handler = sighandler; } else { handler_ll = mp_obj_get_ll(handler_obj); handler = (sighandler_t) (intptr_t) handler_ll; if ((handler_ll != (intptr_t) handler /* overflow */) || (handler != SIG_IGN && handler != SIG_DFL)) { mp_raise_TypeError(MP_ERROR_TEXT("signal handler must be SIG_IGN, " "SIG_DFL, or a callable object")); } } if (signal(signalnum, handler) == SIG_ERR) { mp_raise_OSError(errno); } mp_obj_dict_store(sigdict_obj, signalnum_obj, handler_obj); return old_handler_obj; } static MP_DEFINE_CONST_FUN_OBJ_2(posixmod_signal_obj, posixmod_signal); static mp_obj_t posixmod_kill(mp_obj_t pid_obj, mp_obj_t sig_obj) { int res, sig; long long pid_ll; pid_t pid; pid_ll = mp_obj_get_ll(pid_obj); pid = (pid_t) pid_ll; if (pid != pid_ll /* overflow */) { mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("overflow converting integer to pid_t")); } sig = mp_obj_get_int(sig_obj); res = kill(pid, sig); if (res) { mp_raise_OSError(errno); } return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_2(posixmod_kill_obj, posixmod_kill); /* */ static mp_obj_t posixmod_strerror(mp_obj_t errnum_obj) { char buf[64]; int errnum; const char *errstr; errnum = mp_obj_get_int(errnum_obj); errno = 0; errstr = strerror(errnum); if (errno || !errstr) { snprintf(buf, sizeof(buf), "Unknown error %d", errnum); errstr = buf; } return mp_obj_new_str_from_cstr(errstr); } static MP_DEFINE_CONST_FUN_OBJ_1(posixmod_strerror_obj, posixmod_strerror); /* */ static mp_obj_t posixmod_getpeername(mp_obj_t fd_obj) { int res, fd; struct sockaddr_storage addr; socklen_t addr_len; fd = mp_obj_get_int(fd_obj); addr_len = sizeof(addr); res = getpeername(fd, (struct sockaddr *) &addr, &addr_len); if (res) { mp_raise_OSError(errno); } return mp_obj_new_bytearray(addr_len, &addr); } static MP_DEFINE_CONST_FUN_OBJ_1(posixmod_getpeername_obj, posixmod_getpeername); static mp_obj_t posixmod_getsockname(mp_obj_t fd_obj) { int res, fd; struct sockaddr_storage addr; socklen_t addr_len; fd = mp_obj_get_int(fd_obj); addr_len = sizeof(addr); res = getsockname(fd, (struct sockaddr *) &addr, &addr_len); if (res) { mp_raise_OSError(errno); } return mp_obj_new_bytearray(addr_len, &addr); } static MP_DEFINE_CONST_FUN_OBJ_1(posixmod_getsockname_obj, posixmod_getsockname); static mp_obj_t posixmod_shutdown(mp_obj_t fd_obj, mp_obj_t how_obj) { int res, fd, how; fd = mp_obj_get_int(fd_obj); how = mp_obj_get_int(how_obj); res = shutdown(fd, how); if (res) { mp_raise_OSError(errno); } return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_2(posixmod_shutdown_obj, posixmod_shutdown); /* */ static mp_obj_t posixmod_lstat(mp_obj_t path_obj) { int res; const char *path; struct stat statbuf; mp_obj_t ret[10]; path = mp_obj_str_get_str(path_obj); res = lstat(path, &statbuf); if (res) { mp_raise_OSError(errno); } ret[0] = MP_OBJ_NEW_INT_LL(statbuf.st_mode); ret[1] = MP_OBJ_NEW_INT_LL(statbuf.st_ino); ret[2] = MP_OBJ_NEW_INT_LL(statbuf.st_dev); ret[3] = MP_OBJ_NEW_INT_LL(statbuf.st_nlink); ret[4] = MP_OBJ_NEW_INT_LL(statbuf.st_uid); ret[5] = MP_OBJ_NEW_INT_LL(statbuf.st_gid); ret[6] = MP_OBJ_NEW_INT_LL(statbuf.st_size); ret[7] = MP_OBJ_NEW_INT_LL(statbuf.st_atime); ret[8] = MP_OBJ_NEW_INT_LL(statbuf.st_mtime); ret[9] = MP_OBJ_NEW_INT_LL(statbuf.st_ctime); return mp_obj_new_tuple(10, ret); } static MP_DEFINE_CONST_FUN_OBJ_1(posixmod_lstat_obj, posixmod_lstat); static mp_obj_t posixmod_stat(mp_obj_t path_obj) { int res; const char *path; struct stat statbuf; mp_obj_t ret[10]; path = mp_obj_str_get_str(path_obj); res = stat(path, &statbuf); if (res) { mp_raise_OSError(errno); } ret[0] = MP_OBJ_NEW_INT_LL(statbuf.st_mode); ret[1] = MP_OBJ_NEW_INT_LL(statbuf.st_ino); ret[2] = MP_OBJ_NEW_INT_LL(statbuf.st_dev); ret[3] = MP_OBJ_NEW_INT_LL(statbuf.st_nlink); ret[4] = MP_OBJ_NEW_INT_LL(statbuf.st_uid); ret[5] = MP_OBJ_NEW_INT_LL(statbuf.st_gid); ret[6] = MP_OBJ_NEW_INT_LL(statbuf.st_size); ret[7] = MP_OBJ_NEW_INT_LL(statbuf.st_atime); ret[8] = MP_OBJ_NEW_INT_LL(statbuf.st_mtime); ret[9] = MP_OBJ_NEW_INT_LL(statbuf.st_ctime); return mp_obj_new_tuple(10, ret); } static MP_DEFINE_CONST_FUN_OBJ_1(posixmod_stat_obj, posixmod_stat); /* */ static mp_obj_t posixmod_uname(void) { int res; struct utsname name; mp_obj_t ret[5]; res = uname(&name); if (res < 0) { mp_raise_OSError(errno); } ret[0] = mp_obj_new_str_from_cstr(name.sysname); ret[1] = mp_obj_new_str_from_cstr(name.nodename); ret[2] = mp_obj_new_str_from_cstr(name.release); ret[3] = mp_obj_new_str_from_cstr(name.version); ret[4] = mp_obj_new_str_from_cstr(name.machine); return mp_obj_new_tuple(5, ret); } static MP_DEFINE_CONST_FUN_OBJ_0(posixmod_uname_obj, posixmod_uname); /* */ static mp_obj_t posixmod_waitpid(mp_obj_t pid_obj, mp_obj_t options_obj) { int status, options; long long pid_ll; pid_t pid, pid_ret; mp_obj_t ret[2]; pid_ll = mp_obj_get_ll(pid_obj); pid = (pid_t) pid_ll; if (pid != pid_ll /* overflow */) { mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("overflow converting integer to pid_t")); } options = mp_obj_get_int(options_obj); pid_ret = waitpid(pid, &status, options); if (pid_ret < 0) { mp_raise_OSError(errno); } ret[0] = MP_OBJ_NEW_INT_LL(pid_ret); ret[1] = mp_obj_new_int(status); return mp_obj_new_tuple(2, ret); } static MP_DEFINE_CONST_FUN_OBJ_2(posixmod_waitpid_obj, posixmod_waitpid); /* */ static mp_obj_t posixmod__exit(mp_obj_t status_obj) { int status; status = mp_obj_get_int(status_obj); _exit(status); return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_1(posixmod__exit_obj, posixmod__exit); static mp_obj_t posixmod_access(mp_obj_t path_obj, mp_obj_t mode_obj) { int res, mode; const char *path; path = mp_obj_str_get_str(path_obj); mode = mp_obj_get_int(mode_obj); res = access(path, mode); return mp_obj_new_bool(!res); } static MP_DEFINE_CONST_FUN_OBJ_2(posixmod_access_obj, posixmod_access); static mp_obj_t posixmod_close(mp_obj_t fd_obj) { int res, fd; fd = mp_obj_get_int(fd_obj); res = close(fd); if (res) { mp_raise_OSError(errno); } return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_1(posixmod_close_obj, posixmod_close); static mp_obj_t posixmod_dup(mp_obj_t fd_obj) { int fd, fd2; fd = mp_obj_get_int(fd_obj); fd2 = dup(fd); if (fd2 < 0) { mp_raise_OSError(errno); } return mp_obj_new_int(fd2); } static MP_DEFINE_CONST_FUN_OBJ_1(posixmod_dup_obj, posixmod_dup); static mp_obj_t posixmod_dup2(mp_obj_t fd_obj, mp_obj_t fd2_obj) { int fd, fd2; fd = mp_obj_get_int(fd_obj); fd2 = mp_obj_get_int(fd2_obj); fd2 = dup2(fd, fd2); if (fd2 < 0) { mp_raise_OSError(errno); } return mp_obj_new_int(fd2); } static MP_DEFINE_CONST_FUN_OBJ_2(posixmod_dup2_obj, posixmod_dup2); static mp_obj_t posixmod_execv(mp_obj_t path_obj, mp_obj_t args_obj) { int err; const char *path, **argv; size_t len_args, i; mp_obj_t len_args_obj, iter_args, item; mp_obj_iter_buf_t iter_buf_args; path = mp_obj_str_get_str(path_obj); len_args_obj = mp_obj_len(args_obj); len_args = mp_obj_get_int(len_args_obj); argv = m_new(const char *, len_args + 1); i = 0; iter_args = mp_getiter(args_obj, &iter_buf_args); while (i < len_args && ((item = mp_iternext(iter_args)) != MP_OBJ_STOP_ITERATION)) { argv[i++] = mp_obj_str_get_str(item); } argv[i] = NULL; execv(path, (char * const *) argv); err = errno; m_del(const char *, argv, len_args + 1); mp_raise_OSError(err); return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_2(posixmod_execv_obj, posixmod_execv); static mp_obj_t posixmod_execve(mp_obj_t path_obj, mp_obj_t args_obj, mp_obj_t env_obj) { int err; const char *path, **argv, **envp; size_t len_args, len_env, i; mp_obj_t len_args_obj, len_env_obj, iter_args, iter_env, item; mp_obj_iter_buf_t iter_buf_args, iter_buf_env; path = mp_obj_str_get_str(path_obj); len_args_obj = mp_obj_len(args_obj); len_args = mp_obj_get_int(len_args_obj); len_env_obj = mp_obj_len(env_obj); len_env = mp_obj_get_int(len_env_obj); argv = m_new(const char *, len_args + 1); envp = m_new(const char *, len_env + 1); i = 0; iter_args = mp_getiter(args_obj, &iter_buf_args); while (i < len_args && ((item = mp_iternext(iter_args)) != MP_OBJ_STOP_ITERATION)) { argv[i++] = mp_obj_str_get_str(item); } argv[i] = NULL; i = 0; iter_env = mp_getiter(env_obj, &iter_buf_env); while (i < len_env && ((item = mp_iternext(iter_env)) != MP_OBJ_STOP_ITERATION)) { envp[i++] = mp_obj_str_get_str(item); } envp[i] = NULL; execve(path, (char * const *) argv, (char * const *) envp); err = errno; m_del(const char *, argv, len_args + 1); m_del(const char *, envp, len_env + 1); mp_raise_OSError(err); return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_3(posixmod_execve_obj, posixmod_execve); static mp_obj_t posixmod_execvp(mp_obj_t path_obj, mp_obj_t args_obj) { int err; const char *path, **argv; size_t len_args, i; mp_obj_t len_args_obj, iter_args, item; mp_obj_iter_buf_t iter_buf_args; path = mp_obj_str_get_str(path_obj); len_args_obj = mp_obj_len(args_obj); len_args = mp_obj_get_int(len_args_obj); argv = m_new(const char *, len_args + 1); i = 0; iter_args = mp_getiter(args_obj, &iter_buf_args); while (i < len_args && ((item = mp_iternext(iter_args)) != MP_OBJ_STOP_ITERATION)) { argv[i++] = mp_obj_str_get_str(item); } argv[i] = NULL; execvp(path, (char * const *) argv); err = errno; m_del(const char *, argv, len_args + 1); mp_raise_OSError(err); return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_2(posixmod_execvp_obj, posixmod_execvp); static mp_obj_t posixmod_execvpe(mp_obj_t path_obj, mp_obj_t args_obj, mp_obj_t env_obj) { int err; const char *path, **argv, **envp; size_t len_args, len_env, i; mp_obj_t len_args_obj, len_env_obj, iter_args, iter_env, item; mp_obj_iter_buf_t iter_buf_args, iter_buf_env; path = mp_obj_str_get_str(path_obj); len_args_obj = mp_obj_len(args_obj); len_args = mp_obj_get_int(len_args_obj); len_env_obj = mp_obj_len(env_obj); len_env = mp_obj_get_int(len_env_obj); argv = m_new(const char *, len_args + 1); envp = m_new(const char *, len_env + 1); i = 0; iter_args = mp_getiter(args_obj, &iter_buf_args); while (i < len_args && ((item = mp_iternext(iter_args)) != MP_OBJ_STOP_ITERATION)) { argv[i++] = mp_obj_str_get_str(item); } argv[i] = NULL; i = 0; iter_env = mp_getiter(env_obj, &iter_buf_env); while (i < len_env && ((item = mp_iternext(iter_env)) != MP_OBJ_STOP_ITERATION)) { envp[i++] = mp_obj_str_get_str(item); } envp[i] = NULL; execvpe(path, (char * const *) argv, (char * const *) envp); err = errno; m_del(const char *, argv, len_args + 1); m_del(const char *, envp, len_env + 1); mp_raise_OSError(err); return mp_const_none; } static MP_DEFINE_CONST_FUN_OBJ_3(posixmod_execvpe_obj, posixmod_execvpe); static mp_obj_t posixmod_fork(void) { pid_t child; child = fork(); if (child < 0) { mp_raise_OSError(errno); } return mp_obj_new_int(child); } static MP_DEFINE_CONST_FUN_OBJ_0(posixmod_fork_obj, posixmod_fork); static mp_obj_t posixmod_getuid(void) { long long uid; uid = getuid(); return mp_obj_new_int(uid); } static MP_DEFINE_CONST_FUN_OBJ_0(posixmod_getuid_obj, posixmod_getuid); static mp_obj_t posixmod_isatty(mp_obj_t fd_obj) { int fd; fd = mp_obj_get_int(fd_obj); return mp_obj_new_bool(isatty(fd)); } static MP_DEFINE_CONST_FUN_OBJ_1(posixmod_isatty_obj, posixmod_isatty); static mp_obj_t posixmod_pipe(void) { int res, pipefd[2]; mp_obj_t pipefd_obj[2]; res = pipe(pipefd); if (res) { mp_raise_OSError(errno); } pipefd_obj[0] = mp_obj_new_int(pipefd[0]); pipefd_obj[1] = mp_obj_new_int(pipefd[1]); return mp_obj_new_tuple(2, pipefd_obj); } static MP_DEFINE_CONST_FUN_OBJ_0(posixmod_pipe_obj, posixmod_pipe); static mp_obj_t posixmod_read(mp_obj_t fd_obj, mp_obj_t nbyte_obj) { int fd, err; long long nbyte_ll; size_t nbyte; ssize_t nread; byte *buf; mp_obj_t ret; fd = mp_obj_get_int(fd_obj); nbyte_ll = mp_obj_get_ll(nbyte_obj); nbyte = (size_t) nbyte_ll; if (nbyte_ll != (long long) nbyte /* overflow */) { mp_raise_msg(&mp_type_OverflowError, MP_ERROR_TEXT("overflow converting integer to size_t")); } buf = m_new(byte, nbyte); nread = read(fd, buf, nbyte); if (nread < 0) { err = errno; m_del(byte, buf, nbyte); mp_raise_OSError(err); } ret = mp_obj_new_bytes(buf, nread); m_del(byte, buf, nbyte); return ret; } static MP_DEFINE_CONST_FUN_OBJ_2(posixmod_read_obj, posixmod_read); static mp_obj_t posixmod_readlink(mp_obj_t path_obj) { const char *path; char buf[PATH_MAX + 1]; ssize_t len; path = mp_obj_str_get_str(path_obj); len = readlink(path, buf, sizeof(buf)); if (len < 0) { mp_raise_OSError(errno); } else if (len > PATH_MAX) { mp_raise_OSError(ENAMETOOLONG); } buf[len] = 0; return mp_obj_new_str_from_cstr(buf); } static MP_DEFINE_CONST_FUN_OBJ_1(posixmod_readlink_obj, posixmod_readlink); static mp_obj_t posixmod_write(mp_obj_t fd_obj, mp_obj_t str_obj) { int fd; ssize_t written; mp_buffer_info_t bufinfo; fd = mp_obj_get_int(fd_obj); mp_get_buffer_raise(str_obj, &bufinfo, MP_BUFFER_READ); written = write(fd, bufinfo.buf, bufinfo.len); if (written < 0) { mp_raise_OSError(errno); } return MP_OBJ_NEW_INT_LL(written); } static MP_DEFINE_CONST_FUN_OBJ_2(posixmod_write_obj, posixmod_write); #define DEFINE_FUN_FOR_MACRO(name, type) \ static mp_obj_t posixmod_##name(mp_obj_t in) { \ return mp_obj_new_##type(name(mp_obj_get_int(in))); \ } \ static MP_DEFINE_CONST_FUN_OBJ_1(posixmod_##name##_obj, posixmod_##name) /* */ DEFINE_FUN_FOR_MACRO(S_ISBLK, bool); DEFINE_FUN_FOR_MACRO(S_ISCHR, bool); DEFINE_FUN_FOR_MACRO(S_ISDIR, bool); DEFINE_FUN_FOR_MACRO(S_ISFIFO, bool); DEFINE_FUN_FOR_MACRO(S_ISREG, bool); DEFINE_FUN_FOR_MACRO(S_ISLNK, bool); DEFINE_FUN_FOR_MACRO(S_ISSOCK, bool); /* */ DEFINE_FUN_FOR_MACRO(WIFEXITED, bool); DEFINE_FUN_FOR_MACRO(WEXITSTATUS, int); DEFINE_FUN_FOR_MACRO(WIFSIGNALED, bool); DEFINE_FUN_FOR_MACRO(WTERMSIG, int); DEFINE_FUN_FOR_MACRO(WIFSTOPPED, bool); DEFINE_FUN_FOR_MACRO(WSTOPSIG, int); DEFINE_FUN_FOR_MACRO(WIFCONTINUED, bool); #undef DEFINE_FUN_FOR_MACRO static const mp_rom_map_elem_t posixmod_module_globals_table[] = { { MP_ROM_QSTR(MP_QSTR___name__), MP_ROM_QSTR(MP_QSTR_posix) }, #define F(name) { MP_ROM_QSTR(MP_QSTR_##name), \ MP_ROM_PTR(&posixmod_##name##_obj) } /* extern char **environ; */ F(_environ), /* */ F(fcntl), F(open), /* */ F(gai_strerror), F(getaddrinfo), F(getnameinfo), /* */ F(signal), F(kill), /* */ F(strerror), /* */ F(getpeername), F(getsockname), F(shutdown), /* */ F(lstat), F(stat), /* */ F(uname), /* */ F(waitpid), /* */ F(_exit), F(access), F(close), F(dup), F(dup2), F(execv), F(execve), F(execvp), F(execvpe), F(fork), F(getuid), F(isatty), F(pipe), F(read), F(readlink), F(write), /* function-like macros */ F(S_ISBLK), F(S_ISCHR), F(S_ISDIR), F(S_ISFIFO), F(S_ISREG), F(S_ISLNK), F(S_ISSOCK), /* function-like macros */ F(WIFEXITED), F(WEXITSTATUS), F(WIFSIGNALED), F(WTERMSIG), F(WIFSTOPPED), F(WSTOPSIG), F(WIFCONTINUED), #undef F #define C(name) { MP_ROM_QSTR(MP_QSTR_##name), MP_ROM_INT(name) } /* */ C(E2BIG), C(EACCES), C(EADDRINUSE), C(EADDRNOTAVAIL), C(EAFNOSUPPORT), C(EAGAIN), C(EALREADY), C(EBADF), C(EBADMSG), C(EBUSY), C(ECANCELED), C(ECHILD), C(ECONNABORTED), C(ECONNREFUSED), C(ECONNRESET), C(EDEADLK), C(EDESTADDRREQ), C(EDOM), C(EDQUOT), C(EEXIST), C(EFAULT), C(EFBIG), C(EHOSTUNREACH), C(EIDRM), C(EILSEQ), C(EINPROGRESS), C(EINTR), C(EINVAL), C(EIO), C(EISCONN), C(EISDIR), C(ELOOP), C(EMFILE), C(EMLINK), C(EMSGSIZE), C(EMULTIHOP), C(ENAMETOOLONG), C(ENETDOWN), C(ENETRESET), C(ENETUNREACH), C(ENFILE), C(ENOBUFS), C(ENODATA), C(ENODEV), C(ENOENT), C(ENOEXEC), C(ENOLCK), C(ENOLINK), C(ENOMEM), C(ENOMSG), C(ENOPROTOOPT), C(ENOSPC), C(ENOSR), C(ENOSTR), C(ENOSYS), C(ENOTCONN), C(ENOTDIR), C(ENOTEMPTY), C(ENOTRECOVERABLE), C(ENOTSOCK), C(ENOTSUP), C(ENOTTY), C(ENXIO), C(EOPNOTSUPP), C(EOVERFLOW), C(EOWNERDEAD), C(EPERM), C(EPIPE), C(EPROTO), C(EPROTONOSUPPORT), C(EPROTOTYPE), C(ERANGE), C(EROFS), C(ESPIPE), C(ESRCH), C(ESTALE), C(ETIME), C(ETIMEDOUT), C(ETXTBSY), C(EWOULDBLOCK), C(EXDEV), /* */ C(F_DUPFD), C(F_GETFD), C(F_SETFD), C(F_GETFL), C(F_SETFL), C(F_GETOWN), C(F_SETOWN), C(FD_CLOEXEC), C(O_CREAT), C(O_EXCL), C(O_NOCTTY), C(O_TRUNC), C(O_APPEND), C(O_DSYNC), C(O_NONBLOCK), C(O_RSYNC), C(O_SYNC), C(O_ACCMODE), C(O_RDONLY), C(O_RDWR), C(O_WRONLY), /* */ C(AI_PASSIVE), C(AI_CANONNAME), C(AI_NUMERICHOST), C(AI_NUMERICSERV), C(AI_V4MAPPED), C(AI_ALL), C(AI_ADDRCONFIG), C(NI_NOFQDN), C(NI_NUMERICHOST), C(NI_NAMEREQD), C(NI_NUMERICSERV), #ifdef NI_NUMERICSCOPE /* IEEE Std 1003.1-2001/Cor 1-2002 */ C(NI_NUMERICSCOPE), #endif C(NI_DGRAM), C(EAI_AGAIN), C(EAI_BADFLAGS), C(EAI_FAIL), C(EAI_FAMILY), C(EAI_MEMORY), C(EAI_NONAME), C(EAI_SERVICE), C(EAI_SOCKTYPE), C(EAI_SYSTEM), C(EAI_OVERFLOW), /* */ C(SIG_IGN), C(SIG_DFL), C(SIGABRT), C(SIGALRM), C(SIGBUS), C(SIGCHLD), C(SIGCONT), C(SIGFPE), C(SIGHUP), C(SIGILL), C(SIGINT), C(SIGKILL), C(SIGPIPE), C(SIGQUIT), C(SIGSEGV), C(SIGSTOP), C(SIGTERM), C(SIGTSTP), C(SIGTTIN), C(SIGTTOU), C(SIGUSR1), C(SIGUSR2), C(SIGPOLL), C(SIGPROF), C(SIGSYS), C(SIGTRAP), C(SIGURG), C(SIGVTALRM), C(SIGXCPU), C(SIGXFSZ), /* */ C(BUFSIZ), /* */ C(AF_INET), C(AF_INET6), C(AF_UNIX), C(AF_UNSPEC), C(SHUT_RD), C(SHUT_RDWR), C(SHUT_WR), C(SOCK_DGRAM), C(SOCK_RAW), C(SOCK_SEQPACKET), C(SOCK_STREAM), C(SOL_SOCKET), C(SO_ACCEPTCONN), #ifdef SO_BINDTODEVICE /* non-POSIX, Linux >= 2.0.30 */ C(SO_BINDTODEVICE), #endif C(SO_BROADCAST), C(SO_DEBUG), C(SO_DONTROUTE), C(SO_ERROR), C(SO_KEEPALIVE), C(SO_LINGER), C(SO_OOBINLINE), C(SO_RCVBUF), C(SO_RCVLOWAT), C(SO_RCVTIMEO), C(SO_REUSEADDR), #ifdef SO_REUSEPORT /* non-POSIX, Linux >= 3.9 */ C(SO_REUSEPORT), #endif C(SO_SNDBUF), C(SO_SNDLOWAT), C(SO_SNDTIMEO), C(SO_TYPE), C(SOMAXCONN), C(MSG_CTRUNC), C(MSG_DONTROUTE), C(MSG_EOR), C(MSG_OOB), C(MSG_PEEK), C(MSG_TRUNC), C(MSG_WAITALL), /* */ C(S_IFMT), C(S_IFBLK), C(S_IFCHR), C(S_IFIFO), C(S_IFREG), C(S_IFDIR), C(S_IFLNK), C(S_IFSOCK), C(S_IRWXU), C(S_IRUSR), C(S_IWUSR), C(S_IXUSR), C(S_IRWXG), C(S_IRGRP), C(S_IWGRP), C(S_IXGRP), C(S_IRWXO), C(S_IROTH), C(S_IWOTH), C(S_IXOTH), C(S_ISUID), C(S_ISGID), C(S_ISVTX), /* */ C(WNOHANG), C(WUNTRACED), C(WEXITED), C(WSTOPPED), C(WCONTINUED), C(WNOWAIT), /* */ C(IPPROTO_IP), C(IPPROTO_IPV6), C(IPPROTO_ICMP), C(IPPROTO_RAW), C(IPPROTO_TCP), C(IPPROTO_UDP), C(INADDR_ANY), C(INADDR_BROADCAST), C(INET_ADDRSTRLEN), C(INET6_ADDRSTRLEN), C(IPV6_JOIN_GROUP), C(IPV6_LEAVE_GROUP), C(IPV6_MULTICAST_HOPS), C(IPV6_MULTICAST_IF), C(IPV6_MULTICAST_LOOP), C(IPV6_UNICAST_HOPS), C(IPV6_V6ONLY), /* */ C(TCP_NODELAY), /* */ C(STDIN_FILENO), C(STDOUT_FILENO), C(STDERR_FILENO), C(F_OK), C(R_OK), C(W_OK), C(X_OK), #undef C }; static MP_DEFINE_CONST_DICT(posixmod_module_globals, posixmod_module_globals_table); const mp_obj_module_t posixmod_user_cmodule = { .base = { &mp_type_module }, .globals = (mp_obj_dict_t *) &posixmod_module_globals, }; MP_REGISTER_MODULE(MP_QSTR__posix, posixmod_user_cmodule);