summaryrefslogtreecommitdiff
path: root/tools/unix/process.c
blob: 6400cb92f83cc685ac14353987ed81aa78639893 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
// Copyright 2007 - 2021, Alan Antonuk and the rabbitmq-c contributors.
// SPDX-License-Identifier: mit

#include <errno.h>
#include <spawn.h>
#include <sys/wait.h>
#include <unistd.h>

#include "common.h"
#include "process.h"

extern char **environ;

void pipeline(const char *const *argv, struct pipeline *pl) {
  posix_spawn_file_actions_t file_acts;

  int pipefds[2];
  if (pipe(pipefds)) {
    die_errno(errno, "pipe");
  }

  die_errno(posix_spawn_file_actions_init(&file_acts),
            "posix_spawn_file_actions_init");
  die_errno(posix_spawn_file_actions_adddup2(&file_acts, pipefds[0], 0),
            "posix_spawn_file_actions_adddup2");
  die_errno(posix_spawn_file_actions_addclose(&file_acts, pipefds[0]),
            "posix_spawn_file_actions_addclose");
  die_errno(posix_spawn_file_actions_addclose(&file_acts, pipefds[1]),
            "posix_spawn_file_actions_addclose");

  die_errno(posix_spawnp(&pl->pid, argv[0], &file_acts, NULL,
                         (char *const *)argv, environ),
            "posix_spawnp: %s", argv[0]);

  die_errno(posix_spawn_file_actions_destroy(&file_acts),
            "posix_spawn_file_actions_destroy");

  if (close(pipefds[0])) {
    die_errno(errno, "close");
  }

  pl->infd = pipefds[1];
}

int finish_pipeline(struct pipeline *pl) {
  int status;

  if (close(pl->infd)) {
    die_errno(errno, "close");
  }
  if (waitpid(pl->pid, &status, 0) < 0) {
    die_errno(errno, "waitpid");
  }
  return WIFEXITED(status) && WEXITSTATUS(status) == 0;
}