int pipe(int fds[2]) { int ret; if ((ret = _thread_sys_pipe(fds)) >= 0) { if (_thread_fd_table_init(fds[0], FD_INIT_NEW, NULL) != 0 || _thread_fd_table_init(fds[1], FD_INIT_NEW, NULL) != 0) { _thread_sys_close(fds[0]); _thread_sys_close(fds[1]); ret = -1; } } return (ret); }
int close(int fd) { int ret; /* This is a cancelation point: */ _thread_enter_cancellation_point(); if ((fd < 0) || (fd >= _thread_max_fdtsize) || (fd == _thread_kern_pipe[0]) || (fd == _thread_kern_pipe[1])) { errno = EBADF; ret = -1; } else if ((ret = _FD_LOCK(fd, FD_RDWR_CLOSE, NULL)) != -1) { /* * We need to hold the entry spinlock till after * _thread_sys_close() to stop races caused by the * fd state transition. */ _SPINLOCK(&_thread_fd_table[fd]->lock); _thread_fd_entry_close(fd); /* Close the file descriptor: */ ret = _thread_sys_close(fd); _SPINUNLOCK(&_thread_fd_table[fd]->lock); _FD_UNLOCK(fd, FD_RDWR_CLOSE); } /* No longer in a cancellation point: */ _thread_leave_cancellation_point(); return (ret); }
int close(int fd) { pthread_t self = pthread_self(); int rv; _enter_cancel(self); rv = _thread_sys_close(fd); _leave_cancel(self); return (rv); }
void _exit(int status) { int flags; int i; struct itimerval itimer; /* Disable the interval timer: */ itimer.it_interval.tv_sec = 0; itimer.it_interval.tv_usec = 0; itimer.it_value.tv_sec = 0; itimer.it_value.tv_usec = 0; setitimer(_ITIMER_SCHED_TIMER, &itimer, NULL); /* Close the pthread kernel pipe: */ _thread_sys_close(_thread_kern_pipe[0]); _thread_sys_close(_thread_kern_pipe[1]); /* * Enter a loop to set all file descriptors to blocking * if they were not created as non-blocking: */ for (i = 0; i < _thread_max_fdtsize; i++) { /* Check if this file descriptor is in use: */ if (_thread_fd_table[i] != NULL && _thread_fd_table[i]->status_flags != NULL && !(_thread_fd_table[i]->status_flags->flags & O_NONBLOCK)) { /* Get the current flags: */ flags = _thread_sys_fcntl(i, F_GETFL, NULL); /* Clear the nonblocking file descriptor flag: */ _thread_sys_fcntl(i, F_SETFL, flags & ~O_NONBLOCK); } } /* Call the _exit syscall: */ _thread_sys__exit(status); }
int socket(int af, int type, int protocol) { int fd; /* Create a socket: */ if ((fd = _thread_sys_socket(af, type, protocol)) < 0) { /* Error creating socket. */ /* Initialise the entry in the file descriptor table: */ } else if (_thread_fd_table_init(fd, FD_INIT_NEW, NULL) != 0) { _thread_sys_close(fd); fd = -1; } return (fd); }
int kqueue(void) { int fd; /* Create a kqueue: */ if ((fd = _thread_sys_kqueue()) < 0) { /* Error creating socket. */ /* Initialise the entry in the file descriptor table: */ } else if (_thread_fd_table_init(fd, FD_INIT_NEW, NULL) != 0) { _thread_sys_close(fd); fd = -1; } return (fd); }
int dup(int fd) { int ret; ret = _FD_LOCK(fd, FD_RDWR, NULL); if (ret == 0) { ret = _thread_sys_dup(fd); if (ret != -1) { if (_thread_fd_table_init(ret, FD_INIT_DUP, _thread_fd_table[fd]->status_flags) == -1) { _thread_sys_close(ret); ret = -1; } } _FD_UNLOCK(fd, FD_RDWR); } return (ret); }
int accept(int fd, struct sockaddr * name, socklen_t *namelen) { struct pthread *curthread = _get_curthread(); int ret; int newfd; enum fd_entry_mode init_mode; /* This is a cancellation point: */ _thread_enter_cancellation_point(); /* Lock the file descriptor: */ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) { /* Enter a loop to wait for a connection request: */ while ((ret = _thread_sys_accept(fd, name, namelen)) < 0) { /* Check if the socket is to block: */ if ((_thread_fd_table[fd]->status_flags->flags & O_NONBLOCK) == 0 && (errno == EWOULDBLOCK || errno == EAGAIN)) { /* Save the socket file descriptor: */ curthread->data.fd.fd = fd; curthread->data.fd.fname = __FILE__; curthread->data.fd.branch = __LINE__; /* Set the timeout: */ _thread_kern_set_timeout(NULL); curthread->interrupted = 0; curthread->closing_fd = 0; /* Schedule the next thread: */ _thread_kern_sched_state(PS_FDR_WAIT, __FILE__, __LINE__); /* Check if the wait was interrupted: */ if (curthread->interrupted) { /* Return an error status: */ errno = EINTR; ret = -1; break; } else if (curthread->closing_fd) { /* Return an error status: */ errno = EBADF; ret = -1; break; } } else { /* * Another error has occurred, so exit the * loop here: */ break; } } /* * If no errors initialize the file descriptor table * for the new socket. If the client's view of the * status_flags for fd is blocking, then force newfd * to be viewed as blocking too. */ if (ret != -1) { newfd = ret; if ((_thread_fd_table[fd]->status_flags->flags & O_NONBLOCK) == 0) init_mode = FD_INIT_BLOCKING; else init_mode = FD_INIT_NEW; if((ret = _thread_fd_table_init(newfd, init_mode, NULL)) != -1) ret = newfd; else { /* quitely close the fd */ _thread_sys_close(ret); } } /* Unlock the file descriptor: */ _FD_UNLOCK(fd, FD_RDWR); } /* No longer in a cancellation point: */ _thread_leave_cancellation_point(); /* Return the socket file descriptor or -1 on error: */ return (ret); }