/* AMD64 specific Linux std parts. */ #include "linux.c" #include "../std.h" #include #include #include #include #include inline com_std_fd com_std_open(char const *path, uint32_t flags) { com_std_assert(flags != 0); uint32_t mode = flags & COM_STD_OPEN_READ && flags & COM_STD_OPEN_WRITE ? O_RDWR : flags & COM_STD_OPEN_READ ? O_RDONLY : O_WRONLY; long ret; __asm__ volatile("int $0x80" : "=a"(ret) : "a"(5), "b"(path), "c"(mode), "d"(0) : "memory", "cc"); if (ret <= 0) /* Mark NULL, removing error code */ ret = 0; return (void *)ret; } inline bool com_std_write(com_std_fd fd, void const *data, uint32_t bytes) { long ret; __asm__ volatile("int $0x80" : "=a"(ret) : "a"(4), "b"(fd), "c"(data), "d"(bytes) : "memory", "cc"); return ret == bytes; } inline int32_t com_std_read(com_std_fd fd, void *data, uint32_t upto) { long ret; __asm__ volatile("int $0x80" : "=a"(ret) : "a"(3), "b"(fd), "c"(data), "d"(upto) : "memory", "cc"); return ret; } inline bool com_std_has_data(com_std_fd fd) { struct pollfd pfd = { .fd = (intptr_t)fd, .events = POLLIN, }; long ret; __asm__ volatile("int $0x80" : "=a"(ret) : "a"(168), "b"(&pfd), "c"(1), "d"(0) : "memory", "cc"); if (ret > 0) { return pfd.revents & POLLIN; } else return false; } inline bool com_std_sfwd(com_std_fd fd, uint32_t bytes) { long ret; __asm__ volatile("int $0x80" : "=a"(ret) : "a"(19), "b"(fd), "c"(bytes), "d"(SEEK_CUR) : "memory", "cc"); return ret >= 0; /* TODO: Check whether offset is bytes offset exactly? */ } inline com_std_fd com_std_socket(bool isnetwork) { if (!isnetwork) { int32_t sockfd; __asm__ volatile("int $0x80" : "=a"(sockfd) : "a"(359), "b"(AF_UNIX), "c"(SOCK_STREAM), "d"(0) : "memory", "cc"); if (sockfd < 0) sockfd = 0; return (void *)(int64_t)sockfd; } else return NULL; } inline bool com_std_connect(com_std_fd fd, bool isnetwork, char const *address) { com_std_assert(address != NULL); if (!isnetwork) { struct sockaddr_un addr = {.sun_family = AF_UNIX}; __builtin_memcpy(&addr.sun_path, address, com_str_ext_len(address)); int32_t ret; __asm__ volatile("int $0x80" : "=a"(ret) : "a"(362), "b"(fd), "c"(&addr), "d"(sizeof addr) : "memory", "cc"); return ret == 0; } else return NULL; } inline void com_std_exit(uint32_t status) { __asm__ volatile("int $0x80" : : "a"(1), "b"(status) : "memory", "cc"); __builtin_unreachable(); } inline void com_std_close(com_std_fd fd) { __asm__ volatile("int $0x80" : : "a"(6), "b"(fd) : "memory", "cc"); }