int mail_unix_connect_socket(const char *path) { struct sockaddr_un sa; int s; if (sizeof(sa.sun_path) <= strlen(path)) { return -1; } if (!(memcpy(sa.sun_path, path, strlen(path)+1))) { return -1; } sa.sun_family = AF_UNIX; if (0 > (s = socket(AF_UNIX, SOCK_STREAM, 0))) return -1; if (prepare_fd(s)) goto close_socket; if (connect(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_un))) goto close_socket; return s; close_socket: close(s); return -1; }
int mail_tcp_connect_with_local_address_timeout(const char * server, uint16_t port, const char * local_address, uint16_t local_port, time_t timeout) { #ifndef HAVE_IPV6 struct hostent * remotehost; struct sockaddr_in sa; #else /* HAVE_IPV6 */ struct addrinfo hints, *res, *ai; struct addrinfo la_hints; char port_str[6]; #endif #ifdef WIN32 SOCKET s; long r; #else int s; int r; if ('/' == server[0]) return mail_unix_connect_socket(server); #endif #ifndef HAVE_IPV6 s = socket(PF_INET, SOCK_STREAM, 0); if (s == -1) goto err; if ((local_address != NULL) || (local_port != 0)) { struct sockaddr_in la; la.sin_family = AF_INET; la.sin_port = htons(local_port); if (local_address == NULL) { la.sin_addr.s_addr = htonl(INADDR_ANY); } r = inet_aton(local_address, &la.sin_addr); if (r == 0) goto close_socket; r = bind(s, (struct sockaddr *) &la, sizeof(struct sockaddr_in)); if (r == -1) goto close_socket; } remotehost = gethostbyname(server); if (remotehost == NULL) goto close_socket; sa.sin_family = AF_INET; sa.sin_port = htons(port); memcpy(&sa.sin_addr, remotehost->h_addr, remotehost->h_length); r = prepare_fd(s); if (r == -1) { goto close_socket; } r = connect(s, (struct sockaddr *) &sa, sizeof(struct sockaddr_in)); r = wait_connect(s, r, timeout); if (r == -1) { goto close_socket; } #else /* HAVE_IPV6 */ memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_protocol = IPPROTO_TCP; memset(&la_hints, 0, sizeof(la_hints)); la_hints.ai_family = AF_UNSPEC; la_hints.ai_socktype = SOCK_STREAM; la_hints.ai_flags = AI_PASSIVE; /* convert port from integer to string. */ snprintf(port_str, sizeof(port_str), "%d", port); res = NULL; if (getaddrinfo(server, port_str, &hints, &res) != 0) goto err; s = -1; for (ai = res; ai != NULL; ai = ai->ai_next) { s = socket(ai->ai_family, ai->ai_socktype, ai->ai_protocol); if (s == -1) continue; // Christopher Lyon Anderson - prevent SigPipe #ifdef SO_NOSIGPIPE int kOne = 1; int err = setsockopt(s, SOL_SOCKET, SO_NOSIGPIPE, &kOne, sizeof(kOne)); if (err != 0) continue; #endif if ((local_address != NULL) || (local_port != 0)) { char local_port_str[6]; char * p_local_port_str; struct addrinfo * la_res; if (local_port != 0) { snprintf(local_port_str, sizeof(local_port_str), "%d", local_port); p_local_port_str = local_port_str; } else { p_local_port_str = NULL; } la_res = NULL; r = getaddrinfo(local_address, p_local_port_str, &la_hints, &la_res); if (r != 0) goto close_socket; r = bind(s, (struct sockaddr *) la_res->ai_addr, la_res->ai_addrlen); if (la_res != NULL) freeaddrinfo(la_res); if (r == -1) goto close_socket; } r = prepare_fd(s); if (r == -1) { goto close_socket; } r = connect(s, ai->ai_addr, ai->ai_addrlen); r = wait_connect(s, r, timeout); if (r != -1) { r = verify_sock_errors(s); } if (r == -1) { if (ai->ai_next) { #ifdef WIN32 closesocket(s); #else close(s); #endif continue; } else { goto close_socket; } } /* if we're here, we're good */ break; } if (res != NULL) freeaddrinfo(res); if (ai == NULL) goto err; #endif return s; close_socket: #ifdef HAVE_IPV6 if (res != NULL) freeaddrinfo(res); #endif #ifdef WIN32 closesocket(s); #else close(s); #endif err: return -1; }
/* Open all events in the control state */ int open_pe_events(pe_control_t *ctl) { int i, ret = PE_OK; long pid = ctl->tid; for (i = 0; i < ctl->num_events; i++) { ctl->events[i].event_opened = 0; /* set up the attr structure. We don't set up all fields here */ /* as some have already been set up previously. */ /* group leader (event 0) is special */ if (i == 0) { ctl->events[i].attr.pinned = 1; ctl->events[i].attr.disabled = 1; ctl->events[i].group_leader_fd = -1; } else { ctl->events[i].attr.pinned = 0; ctl->events[i].attr.disabled = 0; ctl->events[i].group_leader_fd = ctl->events[0].event_fd; } /* try to open */ ctl->events[i].event_fd = sys_perf_event_open(&ctl->events[i].attr, pid, ctl->cpu, ctl->events[i].group_leader_fd, 0 /* flags */ ); if (ctl->events[i].event_fd == -1) { SUBDBG("sys_perf_event_open returned error on event #%d." " Error: %s\n", i, strerror(errno)); if (errno == EPERM) ret = PE_EPERM; else ret = PE_ECNFLCT; goto open_pe_cleanup; } SUBDBG("sys_perf_event_open: tid: %ld, cpu_num: %d," " group_leader/fd: %d, event_fd: %d," " read_format: 0x%"PRIu64"\n", pid, ctl->cpu, ctl->events[i].group_leader_fd, ctl->events[i].event_fd, ctl->events[i].attr.read_format); ctl->events[i].event_opened = 1; } /* Now that we've successfully opened all of the events, do whatever */ /* "tune-up" is needed to attach the mmap'd buffers, signal handlers, */ /* and so on. */ for (i = 0; i < ctl->num_events; i++) { /* If sampling is enabled, hook up signal handler */ if (ctl->events[i].attr.sample_period) { ret = prepare_fd(ctl, i); if (ret != PE_OK) { /* All of the fds are open, so we need to clean up all of them */ i = ctl->num_events; goto open_pe_cleanup; } } else { /* Make sure this is NULL so close_pe_events works right */ ctl->events[i].mmap_buf = NULL; } } return PE_OK; open_pe_cleanup: /* We encountered an error, close up the fds we successfully opened. */ /* We go backward in an attempt to close group leaders last, although */ /* That's probably not strictly necessary. */ while (i > 0) { i--; if (ctl->events[i].event_fd >= 0) { close(ctl->events[i].event_fd); ctl->events[i].event_opened = 0; } } return ret; }