diff options
Diffstat (limited to '')
-rw-r--r-- | libexec_get_documents.c | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/libexec_get_documents.c b/libexec_get_documents.c new file mode 100644 index 0000000..2bdadf8 --- /dev/null +++ b/libexec_get_documents.c @@ -0,0 +1,83 @@ +/* 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 |