Exemple #1
0
bool socket_close(int fd)
{
	char unused[64];
	int sys_res;

	sys_res = shutdown(fd, SHUT_WR);
	if (sys_res < 0) {
		close_noerr(fd);
		return false;
	}

	for (;;) {
		do {
			sys_res = read(fd, unused, sizeof(unused));
		} while (sys_res < 0 && errno == EINTR);
		if (sys_res < 0) {
			close_noerr(fd);
			return false;
		}
		if (sys_res == 0)
			break;
	}

	if (close(fd) < 0)
		return false;
	else
		return true;
}
Exemple #2
0
static int start_connect(const struct addrinfo *addr, bool *immediate)
{
	int fd;

	*immediate = false;

	fd = socket(addr->ai_family, addr->ai_socktype, addr->ai_protocol);
	if (fd == -1)
		return fd;

	if (!set_nonblock(fd, true))
		goto close;

	if (connect(fd, addr->ai_addr, addr->ai_addrlen) == 0) {
		/* Immediate connect. */
		*immediate = true;
		return fd;
	}

	if (errno == EINPROGRESS)
		return fd;

close:
	close_noerr(fd);
	return -1;
}
Exemple #3
0
void net_connect_abort(struct pollfd pfds[2])
{
	unsigned int i;

	for (i = 0; i < 2; i++) {
		if (pfds[i].fd != -1)
			close_noerr(pfds[i].fd);
		pfds[i].fd = -1;
	}
}
Exemple #4
0
static bool create_child(struct ptr_valid_batch *batch)
{
	int outpipe[2], inpipe[2];

	if (pipe(outpipe) != 0)
		return false;
	if (pipe(inpipe) != 0)
		goto close_outpipe;

	fflush(stdout);
	batch->child_pid = fork();
	if (batch->child_pid == 0) {
		close(outpipe[1]);
		close(inpipe[0]);
		run_child(outpipe[0], inpipe[1]);
	}

	if (batch->child_pid == -1)
		goto cleanup_pid;

	close(outpipe[0]);
	close(inpipe[1]);

	batch->to_child = outpipe[1];
	batch->from_child = inpipe[0];
	return true;

cleanup_pid:
	batch->child_pid = 0;
	close_noerr(inpipe[0]);
	close_noerr(inpipe[1]);
close_outpipe:
	close_noerr(outpipe[0]);
	close_noerr(outpipe[1]);
	return false;
}
Exemple #5
0
int net_connect_async(const struct addrinfo *addrinfo, struct pollfd pfds[2])
{
	const struct addrinfo *addr[2] = { NULL, NULL };
	unsigned int i;

	pfds[0].fd = pfds[1].fd = -1;
	pfds[0].events = pfds[1].events = POLLOUT;

	/* Give IPv6 a slight advantage, by trying it first. */
	for (; addrinfo; addrinfo = addrinfo->ai_next) {
		switch (addrinfo->ai_family) {
		case AF_INET:
			addr[1] = addrinfo;
			break;
		case AF_INET6:
			addr[0] = addrinfo;
			break;
		default:
			continue;
		}
	}

	/* In case we found nothing. */
	errno = ENOENT;
	for (i = 0; i < 2; i++) {
		bool immediate;

		if (!addr[i])
			continue;

		pfds[i].fd = start_connect(addr[i], &immediate);
		if (immediate) {
			if (pfds[!i].fd != -1)
				close(pfds[!i].fd);
			if (!set_nonblock(pfds[i].fd, false)) {
				close_noerr(pfds[i].fd);
				return -1;
			}
			return pfds[i].fd;
		}
	}

	if (pfds[0].fd != -1 || pfds[1].fd != -1)
		errno = EINPROGRESS;
	return -1;
}
Exemple #6
0
static int make_listen_fd(const struct addrinfo *addrinfo)
{
	int fd, on = 1;

	fd = socket(addrinfo->ai_family, addrinfo->ai_socktype,
		    addrinfo->ai_protocol);
	if (fd < 0)
		return -1;

	setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));
	if (bind(fd, addrinfo->ai_addr, addrinfo->ai_addrlen) != 0)
		goto fail;

	if (should_listen(addrinfo) && listen(fd, 5) != 0)
		goto fail;
	return fd;

fail:
	close_noerr(fd);
	return -1;
}
/* arg* may be null */
static char *ask_process(const tal_t *ctx,
			 const char *name,
			 const char *arg1,
			 const char *arg2,
			 const char *arg3,
			 const char *arg4,
			 const char *arg5)
{
	char *output;
	int fds[2], status;

	if (pipe(fds) != 0)
		return NULL;

	switch (fork()) {
	case -1:
		return NULL;
	case 0:
		close(fds[0]);
		dup2(fds[1], STDOUT_FILENO);
		execlp(name, name, arg1, arg2, arg3, arg4, arg5, NULL);
		exit(errno);
	}

	close(fds[1]);
	output = grab_fd(ctx, fds[0]);
	close_noerr(fds[0]);

	wait(&status);
	if (!WIFEXITED(status)) {
		output = tal_free(output);
		errno = EINTR;
	} else if (WEXITSTATUS(status)) {
		output = tal_free(output);
		errno = WEXITSTATUS(status);
	}

	return output;
}
Exemple #8
0
static char *grab(const char *filename)
{
	int ret, fd;
	size_t max = 16384, s = 0;
	char *buffer;

	fd = open(filename, O_RDONLY);
	if (fd < 0)
		return NULL;

	buffer = malloc(max+1);
	if (!buffer)
		goto close;

	while ((ret = read(fd, buffer + s, max - s)) > 0) {
		s += ret;
		if (s == max) {
			buffer = realloc(buffer, max*2+1);
			if (!buffer)
				goto close;
			max *= 2;
		}
	}
	if (ret < 0)
		goto free;

	close(fd);
	buffer[s] = '\0';
	return buffer;

free:
	free(buffer);
close:
	close_noerr(fd);
	return NULL;
}
Exemple #9
0
char *run_with_timeout(const void *ctx, const char *cmd,
		       bool *ok, unsigned *timeout_ms)
{
	pid_t pid;
	int p[2];
	char *ret;
	int status, ms;
	struct timeval start, end;

	*ok = false;
	if (pipe(p) != 0)
		return talloc_asprintf(ctx, "Failed to create pipe: %s",
				       strerror(errno));

	if (tools_verbose)
		printf("Running: %s\n", cmd);

	gettimeofday(&start, NULL);
	pid = fork();
	if (pid == -1) {
		close_noerr(p[0]);
		close_noerr(p[1]);
		return talloc_asprintf(ctx, "Failed to fork: %s",
				       strerror(errno));
		return NULL;
	}

	if (pid == 0) {
		struct itimerval itim;

		if (dup2(p[1], STDOUT_FILENO) != STDOUT_FILENO
		    || dup2(p[1], STDERR_FILENO) != STDERR_FILENO
		    || close(p[0]) != 0
		    || close(STDIN_FILENO) != 0
		    || open("/dev/null", O_RDONLY) != STDIN_FILENO)
			exit(128);

		signal(SIGALRM, killme);
		itim.it_interval.tv_sec = itim.it_interval.tv_usec = 0;
		itim.it_value.tv_sec = *timeout_ms / 1000;
		itim.it_value.tv_usec = (*timeout_ms % 1000) * 1000;
		setitimer(ITIMER_REAL, &itim, NULL);

		status = system(cmd);
		if (WIFEXITED(status))
			exit(WEXITSTATUS(status));
		/* Here's a hint... */
		exit(128 + WTERMSIG(status));
	}

	close(p[1]);
	ret = grab_fd(ctx, p[0], NULL);
	/* This shouldn't fail... */
	if (waitpid(pid, &status, 0) != pid)
		err(1, "Failed to wait for child");

	gettimeofday(&end, NULL);
	if (end.tv_usec < start.tv_usec) {
		end.tv_usec += 1000000;
		end.tv_sec--;
	}
	ms = (end.tv_sec - start.tv_sec) * 1000
		+ (end.tv_usec - start.tv_usec) / 1000;
	if (ms > *timeout_ms)
		*timeout_ms = 0;
	else
		*timeout_ms -= ms;
	close(p[0]);
	if (tools_verbose) {
		printf("%s", ret);
		printf("Finished: %u ms, %s %u\n", ms,
		       WIFEXITED(status) ? "exit status" : "killed by signal",
		       WIFEXITED(status) ? WEXITSTATUS(status)
		       : WTERMSIG(status));
	}
	*ok = (WIFEXITED(status) && WEXITSTATUS(status) == 0);
	return ret;
}
Exemple #10
0
pid_t pipecmdarr(int *fd_fromchild, int *fd_tochild, int *fd_errfromchild,
		 char *const *arr)
{
	int tochild[2], fromchild[2], errfromchild[2], execfail[2];
	pid_t childpid;
	int err;

	if (fd_tochild) {
		if (pipe(tochild) != 0)
			goto fail;
	} else {
		tochild[0] = open("/dev/null", O_RDONLY);
		if (tochild[0] < 0)
			goto fail;
	}
	if (fd_fromchild) {
		if (pipe(fromchild) != 0)
			goto close_tochild_fail;
	} else {
		fromchild[1] = open("/dev/null", O_WRONLY);
		if (fromchild[1] < 0)
			goto close_tochild_fail;
	}
	if (fd_errfromchild) {
		if (fd_errfromchild == fd_fromchild) {
			errfromchild[0] = fromchild[0];
			errfromchild[1] = fromchild[1];
		} else {
			if (pipe(errfromchild) != 0)
				goto close_fromchild_fail;
		}
	} else {
		errfromchild[1] = open("/dev/null", O_WRONLY);
		if (errfromchild[1] < 0)
			goto close_fromchild_fail;
	}
		
	if (pipe(execfail) != 0)
		goto close_errfromchild_fail;

	if (fcntl(execfail[1], F_SETFD, fcntl(execfail[1], F_GETFD)
		  | FD_CLOEXEC) < 0)
		goto close_execfail_fail;

	childpid = fork();
	if (childpid < 0)
		goto close_execfail_fail;

	if (childpid == 0) {
		if (fd_tochild)
			close(tochild[1]);
		if (fd_fromchild)
			close(fromchild[0]);
		if (fd_errfromchild && fd_errfromchild != fd_fromchild)
			close(errfromchild[0]);

		close(execfail[0]);

		// Child runs command.
		if (tochild[0] != STDIN_FILENO) {
			if (dup2(tochild[0], STDIN_FILENO) == -1)
				goto child_errno_fail;
			close(tochild[0]);
		}
		if (fromchild[1] != STDOUT_FILENO) {
			if (dup2(fromchild[1], STDOUT_FILENO) == -1)
				goto child_errno_fail;
			close(fromchild[1]);
		}
		if (fd_errfromchild && fd_errfromchild == fd_fromchild) {
			if (dup2(STDOUT_FILENO, STDERR_FILENO) == -1)
				goto child_errno_fail;
		} else if (errfromchild[1] != STDERR_FILENO) {
			if (dup2(errfromchild[1], STDERR_FILENO) == -1)
				goto child_errno_fail;
			close(errfromchild[1]);
		}
		execvp(arr[0], arr);

	child_errno_fail:
		err = errno;
		write(execfail[1], &err, sizeof(err));
		exit(127);
	}

	close(tochild[0]);
	close(fromchild[1]);
	close(errfromchild[1]);
	close(execfail[1]);
	/* Child will close this without writing on successful exec. */
	if (read(execfail[0], &err, sizeof(err)) == sizeof(err)) {
		close(execfail[0]);
		waitpid(childpid, NULL, 0);
		errno = err;
		return -1;
	}
	close(execfail[0]);
	if (fd_tochild)
		*fd_tochild = tochild[1];
	if (fd_fromchild)
		*fd_fromchild = fromchild[0];
	if (fd_errfromchild)
		*fd_errfromchild = errfromchild[0];
	return childpid;

close_execfail_fail:
	close_noerr(execfail[0]);
	close_noerr(execfail[1]);
close_errfromchild_fail:
	if (fd_errfromchild)
		close_noerr(errfromchild[0]);
	close_noerr(errfromchild[1]);
close_fromchild_fail:
	if (fd_fromchild)
		close_noerr(fromchild[0]);
	close_noerr(fromchild[1]);
close_tochild_fail:
	close_noerr(tochild[0]);
	if (fd_tochild)
		close_noerr(tochild[1]);
fail:
	return -1;
}