ssize_t INTERPOSE(recvmsg)(int fd, struct msghdr *msg, int flags) { __real_recvmsg_init(); const bool bypass_filter = getenv("SIXJACK_BYPASS") != NULL || is_socket(fd) == false; struct sockaddr_storage sa_local, *sa_local_ = &sa_local; socklen_t sa_local_len; get_sock_info(fd, &sa_local_, &sa_local_len, NULL, NULL); int ret = 0; int ret_errno = 0; bool bypass_call = false; size_t nbyte = (size_t) 0U; struct iovec * const vecs = msg->msg_iov; size_t i_vecs = 0U; while (i_vecs < (size_t) msg->msg_iovlen) { assert(SIZE_MAX - nbyte >= vecs[i_vecs].iov_len); nbyte += vecs[i_vecs].iov_len; i_vecs++; } size_t new_nbyte = nbyte; FilterReplyResultBase rb = { .pre = true, .ret = &ret, .ret_errno = &ret_errno, .fd = fd }; if (bypass_filter == false && (rb.filter = filter_get()) && filter_apply(&rb, sa_local_, sa_local_len, msg, &new_nbyte, &flags) == FILTER_REPLY_BYPASS) { bypass_call = true; } if (bypass_call == false) { ssize_t ret_ = __real_recvmsg(fd, msg, flags); ret_errno = errno; ret = (int) ret_; assert((ssize_t) ret_ == ret); } if (bypass_filter == false) { new_nbyte = ret; rb.pre = false; filter_apply(&rb, sa_local_, sa_local_len, msg, &new_nbyte, &flags); } errno = ret_errno; return ret; }
bool UnixDomainSocketConnection::connect(const char* path, const char* db, const char* user, const char* pass) { #if !defined(MYSQLPP_PLATFORM_WINDOWS) if (is_socket(path, &error_message_)) { return Connection::connect(db, path, user, pass); } (void)common_complaint; #else error_message_ = common_complaint; #endif if (throw_exceptions()) { throw ConnectionFailed(error_message_.c_str()); } else { return false; } }
ssize_t INTERPOSE(read)(int fd, void *buf, size_t nbyte) { __real_read_init(); const bool bypass_filter = getenv("SIXJACK_BYPASS") != NULL || is_socket(fd) == false; struct sockaddr_storage sa_local, *sa_local_ = &sa_local; struct sockaddr_storage sa_remote, *sa_remote_ = &sa_remote; socklen_t sa_local_len, sa_remote_len; get_sock_info(fd, &sa_local_, &sa_local_len, &sa_remote_, &sa_remote_len); int ret = 0; int ret_errno = 0; bool bypass_call = false; size_t new_nbyte = nbyte; FilterReplyResultBase rb = { .pre = true, .ret = &ret, .ret_errno = &ret_errno, .fd = fd }; if (bypass_filter == false && (rb.filter = filter_get()) && filter_apply(&rb, sa_local_, sa_local_len, sa_remote_, sa_remote_len, NULL, &new_nbyte) == FILTER_REPLY_BYPASS) { bypass_call = true; } if (bypass_call == false) { ssize_t ret_ = __real_read(fd, buf, new_nbyte); ret_errno = errno; ret = (int) ret_; assert((ssize_t) ret_ == ret); } if (bypass_filter == false) { rb.pre = false; filter_apply(&rb, sa_local_, sa_local_len, sa_remote_, sa_remote_len, buf, &new_nbyte); } errno = ret_errno; return ret; }
ssize_t __assuan_write (assuan_context_t ctx, assuan_fd_t fd, const void *buffer, size_t size) { int res; int ec = 0; if (is_socket (fd)) { int tries = 3; again: ec = 0; res = send (HANDLE2SOCKET (fd), buffer, size, 0); if (res == -1) ec = WSAGetLastError (); if (ec == WSAEWOULDBLOCK && tries--) { /* EAGAIN: Use select to wait for resources and try again. We do this 3 times and then give up. The higher level layer then needs to take care of EAGAIN. No need to specify a timeout - the socket is not expected to be in blocking mode. */ fd_set fds; FD_ZERO (&fds); FD_SET (HANDLE2SOCKET (fd), &fds); select (0, NULL, &fds, NULL, NULL); goto again; } } else { DWORD nwrite; if (!WriteFile (fd, buffer, size, &nwrite, NULL)) { res = -1; ec = GetLastError (); } else res = (int)nwrite; } if (res == -1) { switch (ec) { case WSAENOTSOCK: gpg_err_set_errno (EBADF); break; case WSAEWOULDBLOCK: gpg_err_set_errno (EAGAIN); break; case ERROR_BROKEN_PIPE: case ERROR_NO_DATA: gpg_err_set_errno (EPIPE); break; default: gpg_err_set_errno (EIO); break; } } return res; }
int main(int argc, char **argv) { #define PORTSZ 32 char portname[PORTSZ]; max_fd = 0; /* No disk files on remote machine */ _fb_disk_enable = 0; memset((void *)clients, 0, sizeof(struct pkg_conn *) * MAX_CLIENTS); #ifdef SIGALRM (void)signal( SIGPIPE, SIG_IGN ); (void)signal( SIGALRM, sigalarm ); #endif /*alarm(1)*/ FD_ZERO(&select_list); fb_server_select_list = &select_list; fb_server_max_fd = &max_fd; #ifndef _WIN32 /* * Inetd Daemon. * Check to see if we were invoked by /etc/inetd. If so * we will have an open network socket on fd=0. Become * a Transient PKG server if this is so. */ netfd = 0; if ( is_socket(netfd) ) { init_syslog(); new_client( pkg_transerver( fb_server_pkg_switch, comm_error ) ); max_fd = 8; once_only = 1; main_loop(); return 0; } #endif /* for now, make them set a port_num, for usage message */ if ( !get_args( argc, argv ) || !port_set ) { (void)fputs(usage, stderr); return 1; } /* Single-Frame-Buffer Server */ if ( framebuffer != NULL ) { fb_server_retain_on_close = 1; /* don't ever close the frame buffer */ /* open a frame buffer */ if ( (fb_server_fbp = fb_open(framebuffer, width, height)) == FB_NULL ) bu_exit(1, NULL); max_fd = fb_set_fd(fb_server_fbp, &select_list); /* check/default port */ if ( port_set ) { if ( port < 1024 ) port += 5559; } snprintf(portname, PORTSZ, "%d", port); /* * Hang an unending listen for PKG connections */ if ( (netfd = pkg_permserver(portname, 0, 0, comm_error)) < 0 ) bu_exit(-1, NULL); FD_SET(netfd, &select_list); V_MAX(max_fd, netfd); main_loop(); return 0; } #ifndef _WIN32 /* * Stand-Alone Daemon */ /* check/default port */ if ( port_set ) { if ( port < 1024 ) port += 5559; sprintf(portname, "%d", port); } else { snprintf(portname, PORTSZ, "%s", "remotefb"); } init_syslog(); while ( (netfd = pkg_permserver(portname, 0, 0, comm_error)) < 0 ) { static int error_count=0; sleep(1); if (error_count++ < 60) { continue; } comm_error("Unable to start the stand-alone framebuffer daemon after 60 seconds, giving up."); return 1; } while (1) { int fbstat; struct pkg_conn *pcp; pcp = pkg_getclient( netfd, fb_server_pkg_switch, comm_error, 0 ); if ( pcp == PKC_ERROR ) break; /* continue is unlikely to work */ if ( fork() == 0 ) { /* 1st level child process */ (void)close(netfd); /* Child is not listener */ /* Create 2nd level child process, "double detach" */ if ( fork() == 0 ) { /* 2nd level child -- start work! */ new_client( pcp ); once_only = 1; main_loop(); return 0; } else { /* 1st level child -- vanish */ return 1; } } else { /* Parent: lingering server daemon */ pkg_close(pcp); /* Daemon is not the server */ /* Collect status from 1st level child */ (void)wait( &fbstat ); } } #endif /* _WIN32 */ return 2; }
/* set up the socket for client connections */ void open_sock() { int fd; struct connection c; /* if this is a socket passed in via stdin by systemd */ if (is_socket(STDIN_FILENO)) { fd = STDIN_FILENO; /* ??? Move CLOEXEC and NONBLOCK settings below up to here? */ } else { /* create our own socket */ fd = ud_create_socket(socketfile, socketmode); if (fd < 0) { acpid_log(LOG_ERR, "can't open socket %s: %s", socketfile, strerror(errno)); exit(EXIT_FAILURE); } /* if we need to change the socket's group, do so */ if (socketgroup) { struct group *gr; struct stat buf; gr = getgrnam(socketgroup); if (!gr) { acpid_log(LOG_ERR, "group %s does not exist", socketgroup); exit(EXIT_FAILURE); } if (fstat(fd, &buf) < 0) { acpid_log(LOG_ERR, "can't stat %s: %s", socketfile, strerror(errno)); exit(EXIT_FAILURE); } /* ??? I've tried using fchown(), however it doesn't work here. * It also doesn't work before bind(). The GNU docs seem to * indicate it isn't supposed to work with sockets. */ /* if (fchown(fd, buf.st_uid, gr->gr_gid) < 0) { */ if (chown(socketfile, buf.st_uid, gr->gr_gid) < 0) { acpid_log(LOG_ERR, "can't chown %s: %s", socketfile, strerror(errno)); exit(EXIT_FAILURE); } } } /* Don't leak fds when execing. * ud_create_socket() already does this, but there is no guarantee that * a socket sent in via STDIN will have this set. */ if (fcntl(fd, F_SETFD, FD_CLOEXEC) < 0) { close(fd); acpid_log(LOG_ERR, "fcntl() on socket %s for FD_CLOEXEC: %s", socketfile, strerror(errno)); return; } /* Avoid a potential hang. * ud_create_socket() already does this, but there is no guarantee that * a socket sent in via STDIN will have this set. */ if (fcntl(fd, F_SETFL, O_NONBLOCK) < 0) { close(fd); acpid_log(LOG_ERR, "fcntl() on socket %s for O_NONBLOCK: %s", socketfile, strerror(errno)); return; } /* add a connection to the list */ c.fd = fd; c.process = process_sock; c.pathname = NULL; c.kybd = 0; if (add_connection(&c) < 0) { close(fd); acpid_log(LOG_ERR, "can't add connection for socket %s", socketfile); return; } }
inline bool is_socket(const path& p, std::error_code& ec) noexcept { return is_socket(detail::status(p, &ec)); }
inline bool is_socket(const path& p) { return is_socket(detail::status(p)); }