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 connect(int fd, const struct sockaddr * name, socklen_t namelen) { struct pthread *curthread = _get_curthread(); struct sockaddr tmpname; socklen_t errnolen, tmpnamelen; int ret; /* This is a cancellation point: */ _thread_enter_cancellation_point(); if ((ret = _FD_LOCK(fd, FD_RDWR, NULL)) == 0) { if ((ret = _thread_sys_connect(fd, name, namelen)) < 0) { if (!(_thread_fd_table[fd]->status_flags->flags & O_NONBLOCK) && ((errno == EWOULDBLOCK) || (errno == EINPROGRESS) || (errno == EALREADY) || (errno == EAGAIN))) { curthread->data.fd.fd = fd; /* Reset the interrupted operation flag: */ curthread->interrupted = 0; curthread->closing_fd = 0; /* Set the timeout: */ _thread_kern_set_timeout(NULL); _thread_kern_sched_state(PS_FDW_WAIT, __FILE__, __LINE__); /* * Check if the operation was * interrupted by a signal or * a closing fd. */ if (curthread->interrupted) { errno = EINTR; ret = -1; } else if (curthread->closing_fd) { errno = EBADF; ret = -1; } else { tmpnamelen = sizeof(tmpname); /* 0 now lets see if it really worked */ if (((ret = _thread_sys_getpeername(fd, &tmpname, &tmpnamelen)) < 0) && (errno == ENOTCONN)) { /* * Get the error, this function * should not fail */ errnolen = sizeof(errno); _thread_sys_getsockopt(fd, SOL_SOCKET, SO_ERROR, &errno, &errnolen); } } } else { ret = -1; } } _FD_UNLOCK(fd, FD_RDWR); } /* No longer in a cancellation point: */ _thread_leave_cancellation_point(); return (ret); }