/* 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