int mqueue_delete(mqueue_t * self) { assert(self != NULL); char path[pathconf(MQUEUE_ROOT, _PC_PATH_MAX)]; if (self->in != (mqd_t) - 1) { sprintf(path, "%s/%d->%s", MQUEUE_ROOT, gettid(), self->service); unlink(path); if (mq_close(self->in) == (mqd_t) - 1) { ERRNO(errno); return -1; } self->in = (mqd_t) - 1; } if (self->out != (mqd_t) - 1) { sprintf(path, "%s/%d<-%s", MQUEUE_ROOT, gettid(), self->service); unlink(path); if (mq_close(self->in) == (mqd_t) - 1) { ERRNO(errno); return -1; } self->out = (mqd_t) - 1; } if (self->service) { free((void *)self->service); self->service = NULL; } return 0; }
int create_regular_file(const char *path, size_t size, char pad) { assert(path != NULL); int fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, S_IRUSR|S_IWUSR); if (fd == -1) { ERRNO(errno); return -1; } if (ftruncate(fd, size) < 0) { ERRNO(errno); close(fd); return -1; } uint32_t page_size = sysconf(_SC_PAGESIZE); char buf[page_size]; memset(buf, pad, page_size); while (0 < size) { ssize_t rc = write(fd, buf, min(sizeof(buf), size)); if (rc <= 0) { ERRNO(errno); close(fd); return -1; } size -= rc; } close(fd); return 0; }
int mqueue_open(mqueue_t * self, char *path) { assert(self != NULL); if (path != NULL) { char *endp = NULL; (void)strtol(path + 1, &endp, 10); if (strncmp(endp, "->", 2) == 0) { self->in = mq_open((char *)path, O_RDONLY, S_IRWXU, NULL); if (self->in == (mqd_t) - 1) { ERRNO(errno); return -1; } } else if (strncmp(endp, "<-", 2) == 0) { self->out = mq_open((char *)path, O_WRONLY, S_IRWXU, NULL); if (self->out == (mqd_t) - 1) { ERRNO(errno); return -1; } } else { UNEXPECTED("'%s' invalid service", path); return -1; } } return 0; }
int _DkMutexLock (struct mutex_handle * mut) { int i, c = 0; int ret; struct atomic_int * m = &mut->value; /* Spin and try to take lock */ for (i = 0; i < MUTEX_SPINLOCK_TIMES; i++) { c = atomic_dec_and_test(m); if (c) goto success; cpu_relax(); } /* The lock is now contended */ while (!c) { int val = atomic_read(m); if (val == 1) goto again; ret = INLINE_SYSCALL(futex, 6, m, FUTEX_WAIT, val, NULL, NULL, 0); if (IS_ERR(ret) && ERRNO(ret) != EWOULDBLOCK && ERRNO(ret) != EINTR) { ret = unix_to_pal_error(ERRNO(ret)); goto out; } #ifdef DEBUG_MUTEX if (IS_ERR(ret)) printf("mutex held by thread %d\n", mut->owner); #endif again: /* Upon wakeup, we still need to check whether mutex is unlocked or * someone else took it. * If c==0 upon return from xchg (i.e., the older value of m==0), we * will exit the loop. Else, we sleep again (through a futex call). */ c = atomic_dec_and_test(m); } success: #ifdef DEBUG_MUTEX mut->owner = INLINE_SYSCALL(gettid, 0); #endif ret = 0; out: return ret; }
void Parser::parse(const char* src) { const char* ptr = src; mNodeStart = ptr; ERRNO(mbtowc(NULL, NULL, 0)); // reset shift state. while(*ptr) { // skip invalid utf-8 sequences. wchar_t w; int res = utf8towc(&w, ptr, 4); if(res <= 0) { if(res < 0) { printf("Invalid UTF-8 0x%x @ pos %" PRIuPTR "\n", (unsigned char)*ptr, ptr - src); } FLUSH; ptr++; mNodeStart = ptr; continue; } else if(res > 1) { // valid utf-8 beyond ascii ptr += res; continue; } if(STREQ(ptr, "http://")) { // unescaped link FLUSH; ptr = parseUnescapedUrl(ptr); mNodeStart = ptr; continue; } char c = *ptr; ptr++; if(c == '[') { // start tag while(*ptr == '[') { ptr++; } const char* endPtr = strchr(ptr, ']'); if(!endPtr) { break; } const char* newEndPtr = fixTag(ptr, endPtr); bool diff = newEndPtr != endPtr; endPtr = newEndPtr; flush(ptr-1); if(!diff) { mNodeStart = ptr; parseTag(ptr, endPtr - ptr); } ptr = endPtr; if(!diff) { ptr++; } mNodeStart = ptr; } else if(c == '\\' && *ptr == 'n') { flush(ptr-1); ptr++; mNodeStart = ptr; addLinebreakNode(); } } FLUSH; }
static int process_option(args_t * args, const char *opt) { assert(args != NULL); assert(opt != NULL); if (args->opt_sz <= args->opt_nr) { size_t size = sizeof(*args->opt); args->opt_sz += 5; args->opt = (const char **)realloc(args->opt, size * args->opt_sz); if (args->opt == NULL) { ERRNO(errno); return -1; } memset(args->opt + args->opt_nr, 0, size * (args->opt_sz - args->opt_nr)); } args->opt[args->opt_nr] = strdup(opt); args->opt_nr++; return 0; }
int main (int argc, char * argv[]) { ERRNO(EINVAL); FOO_UNEXPECTED("cannot frob the ka-knob"); goto error; if (false) { err_t * err = NULL; error: while ((err = err_get()) != NULL) { switch (err_type(err)) { case ERR_VERSION: fprintf(stderr, "%s: %s : %s(%d) : v%d.%02d.%04d %.*s\n", basename((char *)argv[0]), err_type_name(err), basename(err_file(err)), err_line(err), VER_TO_MAJOR(err_code(err)), VER_TO_MINOR(err_code(err)), VER_TO_PATCH(err_code(err)), err_size(err), (char *)err_data(err)); break; default: fprintf(stderr, "%s: %s : %s(%d) : (code=%d) %.*s\n", basename((char *)argv[0]), err_type_name(err), basename(err_file(err)), err_line(err), err_code(err), err_size(err), (char *)err_data(err)); } } } return 0; }
int parse_number(const char *str, uint32_t *num) { assert(num != NULL); if (str == NULL) { *num = 0; return 0; } char *end = NULL; errno = 0; *num = strtoul(str, &end, 0); if (errno != 0) { ERRNO(errno); return -1; } if (*end != '\0') { UNEXPECTED("invalid number specified '%s'", end); return -1; } return 0; }
/* internally to wait for one object. Also used as a shortcut to wait on events and semaphores */ static int _DkObjectWaitOne (PAL_HANDLE handle, PAL_NUM timeout) { /* only for all these handle which has a file descriptor, or a eventfd. events and semaphores will skip this part */ if (HANDLE_HDR(handle)->flags & HAS_FDS) { struct pollfd fds[MAX_FDS]; int off[MAX_FDS]; int nfds = 0; for (int i = 0 ; i < MAX_FDS ; i++) { int events = 0; if ((HANDLE_HDR(handle)->flags & RFD(i)) && !(HANDLE_HDR(handle)->flags & ERROR(i))) events |= POLLIN; if ((HANDLE_HDR(handle)->flags & WFD(i)) && !(HANDLE_HDR(handle)->flags & WRITEABLE(i)) && !(HANDLE_HDR(handle)->flags & ERROR(i))) events |= POLLOUT; if (events) { fds[nfds].fd = handle->generic.fds[i]; fds[nfds].events = events|POLLHUP|POLLERR; fds[nfds].revents = 0; off[nfds] = i; nfds++; } } if (!nfds) return -PAL_ERROR_TRYAGAIN; int64_t waittime = timeout; int ret = ocall_poll(fds, nfds, timeout != NO_TIMEOUT ? &waittime : NULL); if (IS_ERR(ret)) return unix_to_pal_error(ERRNO(ret)); if (!ret) return -PAL_ERROR_TRYAGAIN; for (int i = 0 ; i < nfds ; i++) { if (!fds[i].revents) continue; if (fds[i].revents & POLLOUT) HANDLE_HDR(handle)->flags |= WRITEABLE(off[i]); if (fds[i].revents & (POLLHUP|POLLERR)) HANDLE_HDR(handle)->flags |= ERROR(off[i]); } return 0; } const struct handle_ops * ops = HANDLE_OPS(handle); if (!ops || !ops->wait) return -PAL_ERROR_NOTSUPPORT; return ops->wait(handle, timeout); }
static int __hdr_write(ffs_hdr_t * hdr, FILE * file, off_t offset) { assert(hdr != NULL); assert(hdr->magic == FFS_MAGIC); hdr->checksum = memcpy_checksum(NULL, (void *)hdr, offsetof(ffs_hdr_t, checksum)); hdr->checksum = htobe32(hdr->checksum); if (fseeko(file, offset, SEEK_SET) != 0) { ERRNO(errno); return -1; } size_t size = sizeof(*hdr); if (0 < hdr->entry_count) { size += hdr->entry_count * hdr->entry_size; for (size_t i=0; i<hdr->entry_count; i++) { ffs_entry_t *e = hdr->entries + i; __entry_htobe32(e); e->checksum = memcpy_checksum(NULL, (void *)e, offsetof(ffs_entry_t, checksum)); e->checksum = htobe32(e->checksum); } } __hdr_htobe32(hdr); size_t rc = fwrite(hdr, 1, size, file); if (rc <= 0 && ferror(file)) { ERRNO(errno); return -1; } __hdr_be32toh(hdr); if (0 < hdr->entry_count) for (size_t i=0; i<hdr->entry_count; i++) __entry_be32toh(hdr->entries + i); return 0; }
static regex_t * regex_create(const char * str) { assert(str != NULL); regex_t * self = (regex_t *)malloc(sizeof(*self)); if (self == NULL) { ERRNO(errno); return self; } if (regcomp(self, str, REG_ICASE | REG_NOSUB) != 0) { free(self); ERRNO(errno); return NULL; } return self; }
int init_server() { int socket_fd = socket(AF_INET, SOCK_STREAM, 0); if (socket_fd < 0) { ERRNO("socket() failed"); return -1; } int tr = 1; if (setsockopt(socket_fd, SOL_SOCKET, SO_REUSEADDR, &tr, sizeof(tr)) < 0) { ERRNO("setsockopt() failed"); return -1; } struct sockaddr_in server_addr; server_addr.sin_family = AF_INET; if (listen_localhost) { server_addr.sin_addr.s_addr = inet_addr("127.0.0.1"); } else { server_addr.sin_addr.s_addr = INADDR_ANY; } server_addr.sin_port = htons(tcp_port); if (bind(socket_fd, (struct sockaddr *) &server_addr, sizeof(server_addr)) < 0) { ERRNO("bind() failed"); close(socket_fd); return -1; } if (listen(socket_fd, 5) < 0) { ERRNO("listen() failed"); close(socket_fd); return -1; } if (fcntl(socket_fd, F_SETFL, O_NONBLOCK) < 0) { ERRNO("fcntl() failed"); close(socket_fd); return -1; } return socket_fd; }
int mqueue_receive(mqueue_t * self, void *ptr, size_t len) { assert(self != NULL); int rc = mq_receive(self->in, (char *)ptr, len, 0); if (rc == -1) { ERRNO(errno); return -1; } return rc; }
static int __entries_read(ffs_hdr_t * hdr, FILE * file, off_t offset) { assert(hdr != NULL); assert(hdr->magic == FFS_MAGIC); if (0 < hdr->entry_count) { if (fseeko(file, offset, SEEK_SET) != 0) { ERRNO(errno); return -1; } size_t size = hdr->entry_count * hdr->entry_size; size_t rc = fread(hdr->entries, 1, size, file); if (rc <= 0 && ferror(file)) { ERRNO(errno); return -1; } for (size_t i=0; i<hdr->entry_count; i++) { ffs_entry_t *e = hdr->entries + i; uint32_t ck = memcpy_checksum(NULL, (void *)e, offsetof(ffs_entry_t, checksum)); __entry_be32toh(e); if (e->checksum != ck) { ERROR(ERR_UNEXPECTED, FFS_CHECK_ENTRY_CHECKSUM, "'%s' entry checksum mismatch '%x' != " "'%x'", e->name, e->checksum, ck); return -1; } } } return 0; }
entry_list_t * entry_list_create(ffs_t * ffs) { entry_list_t * self = (entry_list_t *)malloc(sizeof(*self)); if (self == NULL) { ERRNO(errno); return NULL; } list_init(&self->list); self->ffs = ffs; return self; }
int mqueue_create(mqueue_t * self, pid_t tid) { assert(self != NULL); char path[pathconf(MQUEUE_ROOT, _PC_PATH_MAX)]; sprintf(path, "%s/%d->%s", MQUEUE_ROOT, tid, self->service); self->out = open(path, O_WRONLY | O_CREAT, S_IWUSR); if (self->out == (mqd_t) - 1) { ERRNO(errno); return -1; } sprintf(path, "%s/%d<-%s", MQUEUE_ROOT, tid, self->service); self->in = open(path, O_RDONLY | O_CREAT, S_IRUSR); if (self->in == (mqd_t) - 1) { ERRNO(errno); return -1; } return 0; }
static int __hdr_read(ffs_hdr_t * hdr, FILE * file, off_t offset) { assert(hdr != NULL); if (fseeko(file, offset, SEEK_SET) != 0) { ERRNO(errno); return -1; } size_t rc = fread(hdr, 1, sizeof(*hdr), file); if (rc <= 0 && ferror(file)) { ERRNO(errno); return -1; } uint32_t ck = memcpy_checksum(NULL, (void *)hdr, offsetof(ffs_hdr_t, checksum)); __hdr_be32toh(hdr); if (hdr->magic != FFS_MAGIC) { ERROR(ERR_UNEXPECTED, FFS_CHECK_HEADER_MAGIC, "magic number mismatch '%x' != '%x'", hdr->magic, FFS_MAGIC); return -1; } if (hdr->checksum != ck) { ERROR(ERR_UNEXPECTED, FFS_CHECK_HEADER_CHECKSUM, "header checksum mismatch '%x' != '%x'", hdr->checksum, ck); return -1; } return 0; }
int main(int argc, char** argv) { if(argc != 2) { printf("usage: .exe <my port>\n"); return -1; } //CLog::SetLogLevel(LL_DETAIL); CLog::SetLogFile(stdout); // initialize all, acceptor, worker, and client simulator CInetAddr addr("", atoi(argv[1]), IP_V4); if(g_echoServer.Initialize(addr) != 0) { CLog::Log(LL_ERROR, __FILE__, __LINE__, ERRNO(), "initialize echo server failed."); exit(-1); } printf("server running on port[%s]\n", argv[1]); // create work threads for(int i = 0; i < WORKER_NUM; i++) { IReactor_Imp *pImp; if(i < WORKER_NUM/2) { pImp = NewReactorImp(REACTOR_EPOLL); } else { #ifdef WIN32 pImp = NewReactorImp(REACTOR_SELECT); #else pImp = NewReactorImp(REACTOR_EPOLL); #endif } if(g_worker[i].Initialize(pImp) != 0) exit(-1); CThreadManager::Spawn(NULL, (THREAD_CALLBACK)workerThread, (void*)&g_worker[i]); } // accept connections g_echoServer.RunForever(); return 0; }
int parse_path(const char * path, char ** type, char ** target, char ** name) { assert(path != NULL); *type = *target = *name = NULL; char * delim1 = strchr(path, ':'); char * delim2 = strrchr(path, ':'); if (delim1 == NULL && delim2 == NULL) { // <target> if (asprintf(target, "%s", path) < 0) { ERRNO(errno); return -1; } } else if (delim1 == delim2) { // <target>:<name> if (asprintf(target, "%.*s", (uint32_t)(delim1 - path), path) < 0) { ERRNO(errno); return -1; } delim1++; if (asprintf(name, "%s", delim1) < 0) { ERRNO(errno); return -1; } if (valid_type(*target) == true) { *type = *target; *target = *name; *name = NULL; } } else if (delim1 != delim2) { // <type>:<target>:<name> if (asprintf(type, "%.*s", (uint32_t)(delim1 - path), path) < 0) { ERRNO(errno); return -1; } delim1++; if (asprintf(target, "%.*s", (uint32_t)(delim2 - delim1), delim1) < 0) { ERRNO(errno); return -1; } delim2++; if (asprintf(name, "%s", delim2) < 0) { ERRNO(errno); return -1; } } return 0; }
client_t *wait_for_client(int socket_fd) { struct sockaddr_in client_addr; unsigned int client_len = sizeof(client_addr); /* wait for a connection */ int stream_fd = accept(socket_fd, (struct sockaddr *) &client_addr, &client_len); if (stream_fd < 0) { if (errno != EAGAIN && errno != EWOULDBLOCK) { ERRNO("accept() failed"); } return NULL; } /* set socket timeout */ struct timeval tv; tv.tv_sec = client_timeout; tv.tv_usec = 0; setsockopt(stream_fd, SOL_SOCKET, SO_RCVTIMEO, (char *) &tv, sizeof(struct timeval)); setsockopt(stream_fd, SOL_SOCKET, SO_SNDTIMEO, (char *) &tv, sizeof(struct timeval)); /* create client structure */ client_t *client = malloc(sizeof(client_t)); if (!client) { ERROR("malloc() failed"); return NULL; } memset(client, 0, sizeof(client_t)); client->stream_fd = stream_fd; inet_ntop(AF_INET, &client_addr.sin_addr.s_addr, client->addr, INET_ADDRSTRLEN); client->port = ntohs(client_addr.sin_port); INFO("new client connection from %s:%d", client->addr, client->port); return client; }
int parse_offset(const char *str, off_t *offset) { assert(offset != NULL); if (str == NULL) { *offset = 0; return 0; } char *end = NULL; errno = 0; *offset = strtoull(str, &end, 0); if (errno != 0) { ERRNO(errno); return -1; } if (*end != '\0') { if (!strcmp(end, "KiB") || !strcasecmp(end, "KB") || !strcasecmp(end, "K")) *offset <<= 10; else if (!strcmp(end, "MiB") || !strcasecmp(end, "MB") || !strcasecmp(end, "M")) *offset <<= 20; else if (!strcmp(end, "GiB") || !strcasecmp(end, "GB") || !strcasecmp(end, "G")) *offset <<= 30; else { UNEXPECTED("invalid offset specified '%s'", end); return -1; } } return 0; }
entry_list_t * entry_list_create_by_regex(ffs_t * ffs, const char * name) { assert(ffs != NULL); if (name == NULL) name = ".*"; RAII(regex_t*, rx, regex_create(name), regex_free); if (rx == NULL) return NULL; entry_list_t * self = entry_list_create(ffs); if (self == NULL) return NULL; int entry_list(ffs_entry_t * entry) { assert(entry != NULL); char full_name[page_size]; if (__ffs_entry_name(ffs, entry, full_name, sizeof full_name) < 0) return -1; if (regexec(rx, full_name, 0, NULL, 0) == REG_NOMATCH) return 0; entry_node_t * entry_node; entry_node = (entry_node_t *)malloc(sizeof(*entry_node)); if (entry_node == NULL) { ERRNO(errno); return -1; } memcpy(&entry_node->entry, entry, sizeof(*entry)); list_add_tail(&self->list, &entry_node->node); return 0; }
FILE *fopen_generic(const char *path, const char *mode, int debug) { assert(path != NULL); assert(mode != NULL); FILE *file = NULL; uint32_t port = 0; if (strncasecmp(path, "aa:", 3) == 0) { if (parse_number(path + 3, &port) == 0) assert(0); //file = fopen_aaflash(port, mode, debug); } else if (strncasecmp(path, "rw:", 3) == 0) { assert(0); //file = fopen_rwflash(path + 3, mode, debug); } else { file = fopen(path, mode); } if (file == NULL) ERRNO(errno); return file; }
int parse_size(const char *str, uint32_t *size) { assert(size != NULL); if (str == NULL) { *size = 0; return 0; } char *end = NULL; errno = 0; *size = strtoul(str, &end, 0); if (errno != 0) { ERRNO(errno); return -1; } if (*end != '\0') { if (!strcmp(end, "KiB") || !strcasecmp(end, "K") || !strcasecmp(end, "KB")) *size <<= 10; else if (!strcmp(end, "MiB") || !strcasecmp(end, "M") || !strcasecmp(end, "MB")) *size <<= 20; else if (!strcmp(end, "GiB") || !strcasecmp(end, "G") || !strcasecmp(end, "GB")) *size <<= 30; else { UNEXPECTED("invalid size specified '%s'", end); return -1; } } return 0; }
static int command_hexdump(args_t * args) { assert(args != NULL); struct stat st; if (stat(args->path, &st) != 0) { ERRNO(errno); return -1; } if (!S_ISREG(st.st_mode)) { ERRNO(errno); return -1; } FILE *i = fopen(args->path, "r"); if (i == NULL) { ERRNO(errno); return -1; } FILE *o = stdout; if (args->file != NULL) { o = fopen(args->file, "w"); if (o == NULL) { ERRNO(errno); return -1; } } #define INPUT_SIZE 4086 char input[INPUT_SIZE]; // multiple of 9-bytes #undef INPUT_SIZE if (setvbuf(i, NULL, _IOFBF, __round_pow2(sizeof input)) != 0) { ERRNO(errno); return -1; } size_t count = 0; while (count < st.st_size) { clearerr(i); size_t rc = fread(input, 1, sizeof input, i); if (rc == 0) { int err = ferror(i); if (err) { ERRNO(errno); return -1; } else break; } if (args->p8 == f_P8) p8_ecc_dump(o, count, input, rc); else sfc_ecc_dump(o, count, input, rc); count += rc; } if (fclose(i) == EOF) { ERRNO(errno); return -1; } if (o != stdout) { if (fclose(o) == EOF) { ERRNO(errno); return -1; } } return 0; }
int exec(const char* logfilename, const char* cmdline) { #ifdef _WIN32 STARTUPINFO si; PROCESS_INFORMATION pi; //HandleCloser hEvent; SECURITY_ATTRIBUTES sa; sa.lpSecurityDescriptor = NULL; sa.nLength = sizeof(sa); sa.bInheritHandle = true; W32TEST(CreatePipe(hReadPipe.p(), hWritePipe.p(), &sa, 0)); W32TEST(CreatePipe(hStdinPipeRead.p(), hStdinPipeWrite.p(), &sa, 0)); hLogfile = CreateFile(logfilename, GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); W32TEST(hLogfile != INVALID_HANDLE_VALUE); //todo: create console ZERO_OBJECT(si); si.cb = sizeof(si); si.dwFlags = STARTF_USESTDHANDLES; si.hStdOutput = hWritePipe; si.hStdError = hWritePipe; si.hStdInput = hStdinPipeRead; std::string commandLine = cmdline; //will modify string. is ok since commandLine is a copy. W32TEST(CreateProcess(NULL, (char*)commandLine.c_str(), NULL, NULL, true, CREATE_NO_WINDOW, NULL, NULL, &si, &pi)); HandleCloser hcProcess = pi.hProcess; HandleCloser hcThread = pi.hThread; DWORD exitCode; hWritePipe.close(); hStdinPipeRead.close(); HandleCloser hOutThread = CreateThread(NULL, 0, OutThreadFunc, NULL, 0, NULL); HandleCloser hInThread = CreateThread(NULL, 0, InThreadFunc, NULL, 0, NULL); if(WaitForSingleObject(pi.hProcess, INFINITE) == WAIT_FAILED) { DO_GLE; } W32TEST(GetExitCodeProcess(pi.hProcess, &exitCode)); return exitCode; #else #define FAIL_ERRNO LOG("Errno %i @ %s:%i\n", errno, __FILE__, __LINE__); return -2 #define ERRNO(a) if((a) < 0) { FAIL_ERRNO; } LOG("execDoublePipe(%s, %i)\n", cmdline, in.size()); int pin[2], pout[2]; ERRNO(pipe(pin)); ERRNO(pipe(pout)); pid_t pid = fork(); if(pid == 0) { //child if(dup2(pin[0], STDIN_FILENO) < 0) _exit(errno); close(pin[1]); if(dup2(pout[1], STDOUT_FILENO) < 0) _exit(errno); close(pout[0]); execvp(cmdline, NULL); //if this function returns, it has failed. _exit(errno); } else { //parent if(pid < 0) { //fork failed FAIL_ERRNO; } } ERRNO(close(pin[0])); FILE* fout = fdopen(pin[1], "w"); if(!fout) { FAIL_ERRNO; } ERRNO(close(pout[1])); fprintf(fout, "%s", in.c_str()); ERRNO(fclose(fout)); out.clear(); while(1) { char buffer[BUFSIZE]; ssize_t res; ERRNO(res = read(pout[0], buffer, BUFSIZE)); if(res == 0) //EOF break; out.append(buffer, res); } ERRNO(close(pout[0])); int status; ERRNO(waitpid(pid, &status, 0)); errno = status; ERRNO(errno); return status; #endif }
int _DkMutexLockTimeout (struct mutex_handle * mut, int timeout) { int i, c = 0; if (timeout == -1) return -_DkMutexLock(mut); struct atomic_int * m = &mut->value; /* Spin and try to take lock */ for (i = 0 ; i < MUTEX_SPINLOCK_TIMES ; i++) { c = atomic_dec_and_test(m); if (c) goto success; CPU_RELAX(); } /* The lock is now contended */ int ret; if (timeout == 0) { ret = c ? 0 : -PAL_ERROR_TRYAGAIN; goto out; } while (!c) { int val = atomic_read(m); if (val == 1) goto again; struct timespec waittime; long sec = timeout / 1000000; long microsec = timeout - (sec * 1000000); waittime.tv_sec = sec; waittime.tv_nsec = microsec * 1000; ret = INLINE_SYSCALL(_umtx_op, 5, m, UMTX_OP_WAIT_UINT, val, NULL, &waittime); if (IS_ERR(ret) && ERRNO(ret) != EWOULDBLOCK) { ret = unix_to_pal_error(ERRNO(ret)); goto out; } #ifdef DEBUG_MUTEX if (IS_ERR(ret)) printf("mutex held by thread %d\n", mut->owner); #endif again: /* Upon wakeup, we still need to check whether mutex is unlocked or * someone else took it. * If c==0 upon return from xchg (i.e., the older value of m==0), we * will exit the loop. Else, we sleep again (through a futex call). */ c = atomic_dec_and_test(m); } success: #ifdef DEBUG_MUTEX mut->owner = INLINE_SYSCALL(gettid, 0); #endif ret = 0; out: return ret; }
int _DkVirtualMemoryProtect (void * addr, int size, int prot) { int ret = INLINE_SYSCALL(mprotect, 3, addr, size, HOST_PROT(prot)); return IS_ERR(ret) ? unix_to_pal_error(ERRNO(ret)) : 0; }
int _DkMutexLockTimeout (struct mutex_handle * m, PAL_NUM timeout) { int i, ret = 0; #ifdef DEBUG_MUTEX int tid = INLINE_SYSCALL(gettid, 0); #endif /* If this is a trylock-style call, break more quickly. */ int iterations = (timeout == 0) ? 1 : MUTEX_SPINLOCK_TIMES; /* Spin and try to take lock. Ignore any contribution this makes toward * the timeout.*/ for (i = 0; i < iterations; i++) { if (MUTEX_UNLOCKED == cmpxchg(&m->locked, MUTEX_UNLOCKED, MUTEX_LOCKED)) goto success; CPU_RELAX(); } if (timeout == 0) { ret = -PAL_ERROR_TRYAGAIN; goto out; } // Bump up the waiters count; we are probably going to block atomic_inc(&m->nwaiters); while (MUTEX_LOCKED == cmpxchg(&m->locked, MUTEX_UNLOCKED, MUTEX_LOCKED)) { struct timespec waittime, *waittimep = NULL; if (timeout != NO_TIMEOUT) { long sec = timeout / 1000000; long microsec = timeout - (sec * 1000000); waittime.tv_sec = sec; waittime.tv_nsec = microsec * 1000; waittimep = &waittime; } ret = INLINE_SYSCALL(futex, 6, m, FUTEX_WAIT, MUTEX_LOCKED, waittimep, NULL, 0); if (IS_ERR(ret)) { if (ERRNO(ret) == EWOULDBLOCK) { if (timeout != NO_TIMEOUT) { ret = -PAL_ERROR_TRYAGAIN; atomic_dec(&m->nwaiters); goto out; } } else { #ifdef DEBUG_MUTEX printf("futex failed (err = %d)\n", ERRNO(ret)); #endif ret = unix_to_pal_error(ERRNO(ret)); atomic_dec(&m->nwaiters); goto out; } } } atomic_dec(&m->nwaiters); success: #ifdef DEBUG_MUTEX m->owner = tid; #endif ret = 0; out: #ifdef DEBUG_MUTEX if (ret < 0) printf("mutex failed (%s, tid = %d)\n", PAL_STRERROR(ret), tid); #endif return ret; }
int _DkVirtualMemoryFree (void * addr, int size) { int ret = INLINE_SYSCALL(munmap, 2, addr, size); return IS_ERR(ret) ? unix_to_pal_error(ERRNO(ret)) : 0; }