void check_client_fd(aClient *cptr) { if (DoingAuth(cptr)) { unsigned int fdflags = get_fd_flags(cptr->authfd); if(!(fdflags & FDF_WANTREAD)) set_fd_flags(cptr->authfd, FDF_WANTREAD); if((cptr->flags & FLAGS_WRAUTH) && !(fdflags & FDF_WANTWRITE)) set_fd_flags(cptr->authfd, FDF_WANTWRITE); else if(!(cptr->flags & FLAGS_WRAUTH) && (fdflags & FDF_WANTWRITE)) unset_fd_flags(cptr->authfd, FDF_WANTWRITE); return; } if (DoingDNS(cptr)) return; set_fd_flags(cptr->fd, FDF_WANTREAD); }
xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info) { xcb_connection_t* c; #ifndef _WIN32 #ifndef USE_POLL if(fd >= FD_SETSIZE) /* would overflow in FD_SET */ { close(fd); return _xcb_conn_ret_error(XCB_CONN_ERROR); } #endif #endif /* !_WIN32*/ c = calloc(1, sizeof(xcb_connection_t)); if(!c) { close(fd); return _xcb_conn_ret_error(XCB_CONN_CLOSED_MEM_INSUFFICIENT) ; } c->fd = fd; if(!( set_fd_flags(fd) && pthread_mutex_init(&c->iolock, 0) == 0 && _xcb_in_init(&c->in) && _xcb_out_init(&c->out) && write_setup(c, auth_info) && read_setup(c) && _xcb_ext_init(c) && _xcb_xid_init(c) )) { xcb_disconnect(c); return _xcb_conn_ret_error(XCB_CONN_ERROR); } return c; }
xcb_connection_t *xcb_connect_to_fd(int fd, xcb_auth_info_t *auth_info) { xcb_connection_t* c; #ifndef USE_POLL if(fd >= FD_SETSIZE) /* would overflow in FD_SET */ { close(fd); return (xcb_connection_t *) &error_connection; } #endif c = calloc(1, sizeof(xcb_connection_t)); if(!c) { close(fd); return (xcb_connection_t *) &error_connection; } c->fd = fd; if(!( set_fd_flags(fd) && pthread_mutex_init(&c->iolock, 0) == 0 && _xcb_in_init(&c->in) && _xcb_out_init(&c->out) && write_setup(c, auth_info) && read_setup(c) && _xcb_ext_init(c) && _xcb_xid_init(c) )) { xcb_disconnect(c); return (xcb_connection_t *) &error_connection; } return c; }
static GEvent * nmp_rtsp_dev_mng_create_listen_ev(NmpDevMng *dev_mng) { GEvent *e_listen; gint ret, tag_onoff, sockfd = -1; struct addrinfo hints; struct addrinfo *result, *rp; #ifdef USE_SOLINGER struct linger linger; #endif g_return_val_if_fail(dev_mng != NULL, NULL); memset (&hints, 0, sizeof (struct addrinfo)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_PASSIVE | AI_CANONNAME; hints.ai_protocol = 0; hints.ai_canonname = NULL; hints.ai_addr = NULL; hints.ai_next = NULL; ret = getaddrinfo( dev_mng->address, dev_mng->service, &hints, &result ); if (ret != 0) goto close_error; for (rp = result; rp; rp = rp->ai_next) { sockfd = socket( rp->ai_family, rp->ai_socktype, rp->ai_protocol ); if (sockfd < 0) continue; tag_onoff = 1; setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (void *)&tag_onoff, sizeof(tag_onoff)); if (!bind(sockfd, rp->ai_addr, rp->ai_addrlen)) break; close(sockfd); sockfd = -1; } freeaddrinfo(result); if (sockfd == -1) goto close_error; #ifdef USE_SOLINGER linger.l_onoff = 1; linger.l_linger = 5; if (setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (void *)&linger, sizeof (linger)) < 0) goto close_error; #endif set_fd_flags(sockfd, O_NONBLOCK); if (listen(sockfd, MAX_LISTEN_BACKLOG) < 0) goto close_error; e_listen = g_event_new(sizeof(GEvent), sockfd, EV_READ); return e_listen; close_error: if (sockfd >= 0) close (sockfd); return NULL; }
/* * deliver_it * * Attempt to send a sequence of bytes to the connection. * Returns * < 0 Some fatal error occurred, (but not EWOULDBLOCK). * his return is a request to close the socket and clean up the link. * >= 0 No real error occurred, returns the number of bytes actually * transferred. EWOULDBLOCK and other similar conditions should be mapped * to zero return. * Upper level routine will have to decide what to do with * those unwritten bytes... * *NOTE* alarm calls have been preserved, so this should work equally * well whether blocking or non-blocking mode is used... */ int deliver_it (aClient * client_p, char *str, int len) { int retval; aClient *acpt = client_p->acpt; #ifdef DEBUGMODE writecalls++; #endif #ifdef USE_SSL if (IsSSL (client_p) && client_p->ssl) retval = safe_SSL_write (client_p, str, len); else #endif retval = send (client_p->fd, str, len, 0); /* * Convert WOULDBLOCK to a return of "0 bytes moved". This * should occur only if socket was non-blocking. Note, that all is * Ok, if the 'write' just returns '0' instead of an error and * errno=EWOULDBLOCK. */ if (retval < 0 && #ifdef _WIN32 (WSAGetLastError () == WSAEWOULDBLOCK || WSAGetLastError () == WSAENOBUFS) #else (errno == EWOULDBLOCK || errno == EAGAIN || errno == ENOBUFS) #endif ) { retval = 0; client_p->flags |= FLAGS_BLOCKED; set_fd_flags (client_p->fd, FDF_WANTWRITE); return (retval); /* Just get out now... */ } else if (retval > 0) { if (client_p->flags & FLAGS_BLOCKED) { client_p->flags &= ~FLAGS_BLOCKED; unset_fd_flags (client_p->fd, FDF_WANTWRITE); } } #ifdef DEBUGMODE if (retval < 0) { writeb[0]++; Debug ((DEBUG_ERROR, "write error (%s) to %s", strerror (errno), client_p->name)); } else if (retval == 0) writeb[1]++; else if (retval < 16) writeb[2]++; else if (retval < 32) writeb[3]++; else if (retval < 64) writeb[4]++; else if (retval < 128) writeb[5]++; else if (retval < 256) writeb[6]++; else if (retval < 512) writeb[7]++; else if (retval < 1024) writeb[8]++; else writeb[9]++; #endif if (retval > 0) { client_p->sendB += retval; me.sendB += retval; if (client_p->sendB > 1023) { client_p->sendK += (client_p->sendB >> 10); client_p->sendB &= 0x03ff; /* 2^10 = 1024, 3ff = 1023 */ }
void accept_sock_conn(verto_ctx *vctx, verto_ev *ev) { struct gp_conn *conn = NULL; int listen_fd; int fd = -1; int ret; conn = calloc(1, sizeof(struct gp_conn)); if (!conn) { ret = ENOMEM; goto done; } conn->sock_ctx = verto_get_private(ev); conn->us.sd = -1; listen_fd = verto_get_fd(ev); fd = accept(listen_fd, (struct sockaddr *)&conn->us.sock_addr, &conn->us.sock_addr_len); if (fd == -1) { ret = errno; if (ret == EINTR) { /* let the event loop retry later */ return; } goto done; } conn->us.sd = fd; ret = set_status_flags(fd, O_NONBLOCK); if (ret) { GPDEBUG("Failed to set O_NONBLOCK on %d!\n", fd); goto done; } ret = set_fd_flags(fd, FD_CLOEXEC); if (ret) { GPDEBUG("Failed to set FD_CLOEXEC on %d!\n", fd); goto done; } ret = get_peercred(fd, conn); if (ret) { goto done; } GPDEBUG("Client connected (fd = %d)", fd); if (conn->creds.type & CRED_TYPE_UNIX) { GPDEBUG(" (pid = %d) (uid = %d) (gid = %d)", conn->creds.ucred.pid, conn->creds.ucred.uid, conn->creds.ucred.gid); } if (conn->creds.type & CRED_TYPE_SELINUX) { GPDEBUG(" (context = %s)", SELINUX_context_str(conn->selinux_ctx)); } GPDEBUG("\n"); gp_setup_reader(vctx, conn); ret = 0; done: if (ret) { GPERROR("Error connecting client: (%d:%s)", ret, gp_strerror(ret)); gp_conn_free(conn); } }
struct gp_sock_ctx *init_unix_socket(struct gssproxy_ctx *gpctx, const char *file_name) { struct sockaddr_un addr = {0}; struct gp_sock_ctx *sock_ctx; mode_t old_mode; int ret = 0; int fd = -1; sock_ctx = calloc(1, sizeof(struct gp_sock_ctx)); if (!sock_ctx) { return NULL; } /* can't bind if an old socket is around */ unlink(file_name); /* socket should be r/w by anyone */ old_mode = umask(0111); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, file_name, sizeof(addr.sun_path)-1); addr.sun_path[sizeof(addr.sun_path)-1] = '\0'; fd = socket(AF_UNIX, SOCK_STREAM, 0); if (fd == -1) { ret = errno; GPDEBUG("Failed to init socket! (%d: %s)\n", ret, gp_strerror(ret)); goto done; } ret = bind(fd, (struct sockaddr *)&addr, sizeof(addr)); if (ret == -1) { ret = errno; GPDEBUG("Failed to bind socket %s! (%d: %s)\n", addr.sun_path, ret, gp_strerror(ret)); goto done; } ret = listen(fd, 10); if (ret == -1) { ret = errno; GPDEBUG("Failed to listen! (%d: %s)\n", ret, gp_strerror(ret)); goto done; } ret = set_status_flags(fd, O_NONBLOCK); if (ret != 0) { GPDEBUG("Failed to set O_NONBLOCK on %d!\n", fd); goto done; } ret = set_fd_flags(fd, FD_CLOEXEC); if (ret != 0) { GPDEBUG("Failed to set FD_CLOEXEC on %d!\n", fd); goto done; } done: if (ret) { GPERROR("Failed to create Unix Socket! (%d:%s)", ret, gp_strerror(ret)); if (fd != -1) { close(fd); fd = -1; } safefree(sock_ctx); } else { sock_ctx->gpctx = gpctx; sock_ctx->socket = file_name; sock_ctx->fd = fd; } umask(old_mode); return sock_ctx; }