blob: 2bdadf8176805d268e3077dc4f9e3de3bdba33d3 (
plain) (
tree)
|
|
/* See LICENSE file for copyright and license details. */
#include "common.h"
#ifndef TEST
int
libexec_get_documents(struct libexec_command *cmd, struct libexec_document **docsp, size_t *ndocsp, int flags)
{
typedef int fdpair[2];
size_t i, j, n;
void *new;
fdpair *pipes;
int error;
int fd_flags, fl_flags;
if (!cmd || !docsp || !ndocsp) {
errno = EINVAL;
return -1;
}
fd_flags = (flags & O_CLOEXEC);
fl_flags = (flags ^ fd_flags);
if (fd_flags)
fd_flags = FD_CLOEXEC;
n = 0;
for (i = 0; i < cmd->nplumings; i++)
if (cmd->plumings[i].type == LIBEXEC_PLUMING_DOCUMENT)
n += 1;
pipes = malloc(n * sizeof(*pipes));
if (!pipes)
return -1;
j = 0;
for (i = 0; i < cmd->nplumings; i++) {
if (cmd->plumings[i].type == LIBEXEC_PLUMING_DOCUMENT) {
if (pipe(pipes[j]))
goto fail;
j++;
if (fd_flags && fcntl(pipes[j - 1][1], F_SETFD, fd_flags))
goto fail;
if (fl_flags && fcntl(pipes[j - 1][1], F_SETFL, fl_flags))
goto fail;
}
}
new = realloc(*docsp, (*ndocsp + n) * sizeof(**docsp));
if (!new)
goto fail;
*docsp = new;
for (i = 0, j = 0; i < cmd->nplumings; i++) {
if (cmd->plumings[i].type != LIBEXEC_PLUMING_DOCUMENT)
continue;
(*docsp)[j].user = 0;
(*docsp)[j].fd = pipes[j][1];
(*docsp)[j].text = cmd->plumings[i].target.text;
(*docsp)[j].length = cmd->plumings[i].target.len;
(*docsp)[j].offset = 0;
cmd->plumings[i].target.fd = pipes[j][0];
cmd->plumings[i].type = LIBEXEC_PLUMING_PIPE;
j++;
}
free(pipes);
return 0;
fail:
error = errno;
while (j--) {
close(pipes[j][0]);
close(pipes[j][1]);
}
free(pipes);
errno = error;
return -1;
}
#else
LIBEXEC_CONST__ int main(void) {return 0;} /* TODO test */
#endif
|