_st_netfd_t *st_accept(_st_netfd_t *fd, struct sockaddr *addr, int *addrlen, st_utime_t timeout) { int osfd, err; _st_netfd_t *newfd; while ((osfd = accept(fd->osfd, addr, (socklen_t *)addrlen)) < 0) { if (errno == EINTR) continue; if (!_IO_NOT_READY_ERROR) return NULL; /* Wait until the socket becomes readable */ if (st_netfd_poll(fd, POLLIN, timeout) < 0) return NULL; } /* On some platforms the new socket created by accept() inherits */ /* the nonblocking attribute of the listening socket */ #if defined (MD_ACCEPT_NB_INHERITED) newfd = _st_netfd_new(osfd, 0, 1); #elif defined (MD_ACCEPT_NB_NOT_INHERITED) newfd = _st_netfd_new(osfd, 1, 1); #else #error Unknown OS #endif if (!newfd) { err = errno; close(osfd); errno = err; } return newfd; }
_st_netfd_t *st_accept(_st_netfd_t *fd, struct sockaddr *addr, int *addrlen, st_utime_t timeout) { int osfd, err; _st_netfd_t *newfd; _st_netfd_t **p = (_st_netfd_t **) fd->aux_data; ssize_t n; char c; for ( ; ; ) { if (p == NULL) { osfd = accept(fd->osfd, addr, (socklen_t *)addrlen); } else { /* Get the lock */ n = st_read(p[0], &c, 1, timeout); if (n < 0) { return NULL; } ST_ASSERT(n == 1); /* Got the lock */ osfd = accept(fd->osfd, addr, (socklen_t *)addrlen); /* Unlock */ err = errno; n = st_write(p[1], &c, 1, timeout); ST_ASSERT(n == 1); errno = err; } if (osfd >= 0) { break; } if (errno == EINTR) { continue; } if (!_IO_NOT_READY_ERROR) { return NULL; } /* Wait until the socket becomes readable */ if (st_netfd_poll(fd, POLLIN, timeout) < 0) { return NULL; } } /* On some platforms the new socket created by accept() inherits */ /* the nonblocking attribute of the listening socket */ #if defined (MD_ACCEPT_NB_INHERITED) newfd = _st_netfd_new(osfd, 0, 1); #elif defined (MD_ACCEPT_NB_NOT_INHERITED) newfd = _st_netfd_new(osfd, 1, 1); #else #error Unknown OS #endif if (!newfd) { err = errno; close(osfd); errno = err; } return newfd; }
/* * To open FIFOs or other special files. */ _st_netfd_t *st_open(const char *path, int oflags, mode_t mode) { int osfd, err; _st_netfd_t *newfd; while ((osfd = open(path, oflags | O_NONBLOCK, mode)) < 0) { if (errno != EINTR) return NULL; } newfd = _st_netfd_new(osfd, 0, 0); if (!newfd) { err = errno; close(osfd); errno = err; } return newfd; }
// 将 socket 文件描述符转为 _st_netfd_t _st_netfd_t *st_netfd_open_socket(int osfd) { return _st_netfd_new(osfd, 1, 1); }
// 将普通文件描述符转为 _st_netfd_t _st_netfd_t *st_netfd_open(int osfd) { return _st_netfd_new(osfd, 1, 0); }