int _socketpair(int af, int type, int protocol, int pair[2]) { int ret; if (!((ret = __sys_socketpair(af, type, protocol, pair)) < 0)) if (_thread_fd_table_init(pair[0]) != 0 || _thread_fd_table_init(pair[1]) != 0) { __sys_close(pair[0]); __sys_close(pair[1]); ret = -1; } return (ret); }
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 _dup(int fd) { int ret; /* Lock the file descriptor: */ if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) { /* Perform the 'dup' syscall: */ if ((ret = __sys_dup(fd)) < 0) { } /* Initialise the file descriptor table entry: */ else if (_thread_fd_table_init(ret) != 0) { /* Quietly close the file: */ __sys_close(ret); /* Reset the file descriptor: */ ret = -1; } else { /* * Save the file open flags so that they can be * checked later: */ _thread_fd_setflags(ret, _thread_fd_getflags(fd)); } /* Unlock the file descriptor: */ _FD_UNLOCK(fd, FD_RDWR); } /* Return the completion status: */ return (ret); }
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 getsockopt(int fd, int level, int optname, void *optval, socklen_t *optlen) { int ret; struct fd_table_entry *entry; ret = _thread_fd_table_init(fd, FD_INIT_UNKNOWN, NULL); if (ret == 0) { entry = _thread_fd_table[fd]; _thread_kern_sig_defer(); if (entry->state == FD_ENTRY_OPEN) { ret = _thread_sys_getsockopt(fd, level, optname, optval, optlen); } else { ret = -1; errno = EBADF; } _thread_kern_sig_undefer(); } 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); }