/* * Non-blocking read from an fd. */ int oskitunix_threaded_read(int fd, void* buf, size_t len) { int count; int enabled; enabled = osenv_intr_save_disable(); for (;;) { count = NATIVEOS(read)(fd, buf, len); if (count >= 0) break; /* a "real" error */ if (!((NATIVEOS(errno) == EAGAIN) || (NATIVEOS(errno) == EINTR))) { errno = NATIVEOS(errno); break; } /* an interruption */ if (oskitunix_threaded_fd_wait(fd, IOTYPE_READ)) { errno = EINTR; count = -1; break; } } if (enabled) osenv_intr_enable(); return count; }
/* * Added to improve console output performance. */ int console_putbytes(const char *str, int len) { int rc = 0; int enabled; enabled = osenv_intr_save_disable(); while (len) { rc = NATIVEOS(write)(1, str, len); if (rc < 0) { if (errno == EAGAIN) continue; break; } len -= rc; str += rc; } if (enabled) osenv_intr_enable(); if (rc < 0) return EOF; else return 0; }
/* * Non-blocking socket recvfrom */ int oskitunix_threaded_recvfrom(int fd, void* buf, size_t len, int flags, struct sockaddr* from, int* fromlen) { int count; int enabled; enabled = osenv_intr_save_disable(); for (;;) { count = NATIVEOS(recvfrom)(fd, buf, len, flags, from, fromlen); if (count >= 0) break; if (!((NATIVEOS(errno) == EAGAIN) || (NATIVEOS(errno) == EINTR))) { errno = NATIVEOS(errno); break; } if (oskitunix_threaded_fd_wait(fd, IOTYPE_READ)) { errno = EINTR; count = -1; break; } } if (enabled) osenv_intr_enable(); return count; }
/* * Non-blocking socket accept. */ int oskitunix_threaded_accept(int fd, struct sockaddr* addr, size_t* len) { int newfd; int enabled; enabled = osenv_intr_save_disable(); for (;;) { newfd = NATIVEOS(accept)(fd, addr, len); if (newfd >= 0) break; if (!((NATIVEOS(errno) == EAGAIN) || (NATIVEOS(errno) == EINTR))) { errno = NATIVEOS(errno); break; } if (oskitunix_threaded_fd_wait(fd, IOTYPE_READ)) { errno = EINTR; newfd = -1; break; } } if (enabled) osenv_intr_enable(); return newfd; }
/* * Trap handler. All we (currently) care about is page faults. Everything * else is passed through. */ int svm_page_fault_handler(struct trap_state *ts) { if (ts->trapno == T_PAGE_FAULT) { int rcode, enabled; enabled = osenv_intr_save_disable(); ts->cr2 = get_cr2(); rcode = svm_fault(ts->cr2, ts->err); if (enabled) osenv_intr_enable(); if (rcode != SVM_FAULT_OKAY) rcode = oskit_sendsig(rcode == SVM_FAULT_PAGEFLT ? SIGSEGV : SIGBUS, ts); return rcode; } /* * Not a page fault. Pass it through to the application as * a signal. If signal handling is not enabled, a trap dump * will be generated. */ return sendsig_trap_handler(ts); }
int osenv_timer_pit_read() { int enb; int value; enb = osenv_intr_save_disable(); value = pit_read(0); if (enb) osenv_intr_enable(); return value; }
/* * Non-blocking write to an fd. */ int oskitunix_threaded_write(int fd, const void* buf, size_t len) { int count = 1; const void* ptr; int enabled; ptr = buf; enabled = osenv_intr_save_disable(); while (len > 0 && count > 0) { count = NATIVEOS(write)(fd, ptr, len); if (count >= 0) { ptr += count; len -= count; count = ptr - buf; continue; } /* a regular error */ if (!((NATIVEOS(errno) == EAGAIN) || (NATIVEOS(errno) == EINTR))) { errno = NATIVEOS(errno); break; } /* an interruption */ if (oskitunix_threaded_fd_wait(fd, IOTYPE_WRITE)) { errno = EINTR; count = -1; break; } count = 1; } if (enabled) osenv_intr_enable(); return count; }
/* * Non-blocking socket connect. */ int oskitunix_threaded_connect(int fd, struct sockaddr* addr, size_t len) { int rc; int enabled; enabled = osenv_intr_save_disable(); for (;;) { rc = NATIVEOS(connect)(fd, addr, len); if (rc == 0) break; /* A "real" error */ if (!((NATIVEOS(errno) == EINPROGRESS) || (NATIVEOS(errno) == EALREADY) || (NATIVEOS(errno) == EINTR))) { errno = NATIVEOS(errno); break; } /* an interruption */ if (oskitunix_threaded_fd_wait(fd, IOTYPE_WRITE)) { errno = EINTR; rc = -1; break; } } /* annul EISCONN error */ if ((rc < 0) && (NATIVEOS(errno) == EISCONN)) rc = 0; if (enabled) osenv_intr_enable(); return rc; }
/* * Non-blocking socket sendto */ int oskitunix_threaded_sendto(int fd, const void* buf, size_t len, int flags, struct sockaddr* to, int tolen) { int total = 0, count; int enabled; enabled = osenv_intr_save_disable(); while (len > 0) { count = NATIVEOS(sendto)(fd, buf, len, flags, to, tolen); if (count >= 0) { buf += count; len -= count; total += count; continue; } if (!((NATIVEOS(errno) == EAGAIN) || (NATIVEOS(errno) == EINTR))) { errno = NATIVEOS(errno); break; } if (oskitunix_threaded_fd_wait(fd, IOTYPE_WRITE)) { errno = EINTR; total = -1; break; } count = 1; } if (enabled) osenv_intr_enable(); return total; }