Line data Source code
1 : /*
2 : *
3 : * Copyright 2015, Google Inc.
4 : * All rights reserved.
5 : *
6 : * Redistribution and use in source and binary forms, with or without
7 : * modification, are permitted provided that the following conditions are
8 : * met:
9 : *
10 : * * Redistributions of source code must retain the above copyright
11 : * notice, this list of conditions and the following disclaimer.
12 : * * Redistributions in binary form must reproduce the above
13 : * copyright notice, this list of conditions and the following disclaimer
14 : * in the documentation and/or other materials provided with the
15 : * distribution.
16 : * * Neither the name of Google Inc. nor the names of its
17 : * contributors may be used to endorse or promote products derived from
18 : * this software without specific prior written permission.
19 : *
20 : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21 : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
22 : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
23 : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
24 : * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 : * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 : * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27 : * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28 : * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29 : * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
30 : * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31 : *
32 : */
33 :
34 : #include <grpc/support/port_platform.h>
35 :
36 : #ifdef GPR_POSIX_SUBPROCESS
37 :
38 : #include <grpc/support/subprocess.h>
39 :
40 : #include <unistd.h>
41 : #include <assert.h>
42 : #include <errno.h>
43 : #include <stdio.h>
44 : #include <string.h>
45 : #include <signal.h>
46 : #include <stdlib.h>
47 : #include <sys/types.h>
48 : #include <sys/wait.h>
49 :
50 : #include <grpc/support/alloc.h>
51 : #include <grpc/support/log.h>
52 :
53 : struct gpr_subprocess {
54 : int pid;
55 : int joined;
56 : };
57 :
58 2 : const char *gpr_subprocess_binary_extension() { return ""; }
59 :
60 12 : gpr_subprocess *gpr_subprocess_create(int argc, const char **argv) {
61 : gpr_subprocess *r;
62 : int pid;
63 : char **exec_args;
64 :
65 12 : pid = fork();
66 12 : if (pid == -1) {
67 0 : return NULL;
68 12 : } else if (pid == 0) {
69 0 : exec_args = gpr_malloc(((size_t)argc + 1) * sizeof(char *));
70 0 : memcpy(exec_args, argv, (size_t)argc * sizeof(char *));
71 0 : exec_args[argc] = NULL;
72 0 : execv(exec_args[0], exec_args);
73 : /* if we reach here, an error has occurred */
74 0 : gpr_log(GPR_ERROR, "execv '%s' failed: %s", exec_args[0], strerror(errno));
75 0 : _exit(1);
76 : return NULL;
77 : } else {
78 12 : r = gpr_malloc(sizeof(gpr_subprocess));
79 12 : memset(r, 0, sizeof(*r));
80 12 : r->pid = pid;
81 12 : return r;
82 : }
83 : }
84 :
85 12 : void gpr_subprocess_destroy(gpr_subprocess *p) {
86 12 : if (!p->joined) {
87 12 : kill(p->pid, SIGKILL);
88 12 : gpr_subprocess_join(p);
89 : }
90 12 : gpr_free(p);
91 12 : }
92 :
93 14 : int gpr_subprocess_join(gpr_subprocess *p) {
94 : int status;
95 : retry:
96 14 : if (waitpid(p->pid, &status, 0) == -1) {
97 2 : if (errno == EINTR) {
98 0 : goto retry;
99 : }
100 2 : gpr_log(GPR_ERROR, "waitpid failed: %s", strerror(errno));
101 2 : return -1;
102 : }
103 12 : return status;
104 : }
105 :
106 1 : void gpr_subprocess_interrupt(gpr_subprocess *p) {
107 1 : if (!p->joined) {
108 1 : kill(p->pid, SIGINT);
109 : }
110 1 : }
111 :
112 : #endif /* GPR_POSIX_SUBPROCESS */
|