OpenVAS Libraries  9.0.3
popen.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) Michel Arboi 2002
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public
15  * License along with this library; if not, write to the Free
16  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17  *
18  */
19 
20 #include <stdlib.h>
21 #include <stdio.h>
22 #include <sys/types.h>
23 #include <sys/socket.h>
24 #include <sys/resource.h>
25 #include <sys/wait.h>
26 #include <unistd.h>
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <signal.h>
30 
31 #ifndef RLIM_INFINITY
32 #define RLIM_INFINITY (1024*1024*1024)
33 #endif
34 
35 FILE *
36 openvas_popen4 (const char *cmd, char *const args[], pid_t * ppid, int inice)
37 {
38  int fd, pipes[2];
39  pid_t son;
40  FILE *fp;
41 
42 #if DEBUG
43  int i;
44  log_legacy_write ("openvas_popen4: running %s -", cmd);
45  for (i = 0; args[i] != NULL; i++)
46  log_legacy_write (" %s", args[i]);
47  fputc ('\n', stderr);
48 #endif
49 
50  /* pipe() does not always work well on some OS */
51  if (socketpair (AF_UNIX, SOCK_STREAM, 0, pipes) < 0)
52  {
53  perror ("socketpair");
54  return NULL;
55  /* filedes[0] is for reading, filedes[1] is for writing. */
56  }
57  if ((son = fork ()) < 0)
58  {
59  perror ("fork");
60  close (pipes[0]);
61  close (pipes[1]);
62  return NULL;
63  }
64  if (son == 0)
65  {
66  struct rlimit rl;
67  int i;
68 
69  /* Child process */
70 
71  if (inice)
72  {
73  errno = 0;
74  /* Some systems returned the new nice value => it may be < 0 */
75  if (nice (inice) < 0 && errno)
76  perror ("nice");
77  }
78  /* Memory usage: unlimited */
79  rl.rlim_cur = rl.rlim_max = RLIM_INFINITY;
80  if (setrlimit (RLIMIT_DATA, &rl) < 0)
81  perror ("RLIMIT_DATA");
82  if (setrlimit (RLIMIT_RSS, &rl) < 0)
83  perror ("RLIMIT_RSS");
84  if (setrlimit (RLIMIT_STACK, &rl) < 0)
85  perror ("RLIMIT_STACK");
86  /* We could probably limit the CPU time, but to which value? */
87 
88  if ((fd = open ("/dev/null", O_RDONLY)) < 0)
89  {
90  perror ("/dev/null");
91  exit (1);
92  }
93  close (STDIN_FILENO);
94  if (dup2 (fd, STDIN_FILENO) < 0)
95  {
96  perror ("dup2");
97  exit (1);
98  }
99  close (fd);
100 
101  close (STDOUT_FILENO);
102  close (STDERR_FILENO);
103  if (dup2 (pipes[1], STDOUT_FILENO) < 0 || dup2 (pipes[1], STDERR_FILENO) < 0)
104  {
105  /* Cannot print error as STDERR is closed! */
106  exit (1);
107  }
108 
109  /*
110  * Close all the fd's
111  */
112  for (i = 3; i < 256; i++)
113  {
114  close (i);
115  }
116  signal (SIGTERM, _exit);
117  signal (SIGPIPE, _exit);
118  execvp (cmd, args);
119  perror ("execvp");
120  _exit (1);
121  }
122  close (pipes[1]);
123  if ((fp = fdopen (pipes[0], "r")) == NULL)
124  {
125  perror ("fdopen");
126  close (pipes[0]);
127  return NULL;
128  }
129 
130  if (ppid != NULL)
131  *ppid = son;
132  return fp;
133 }
134 
135 int
136 openvas_pclose (FILE * fp, pid_t pid)
137 {
138  if (pid > 0)
139  if (waitpid (pid, NULL, WNOHANG) == 0)
140  if (kill (pid, SIGTERM) >= 0)
141  if (waitpid (pid, NULL, WNOHANG) == 0)
142  {
143  usleep (400);
144  (void) kill (pid, SIGKILL);
145  (void) waitpid (pid, NULL, WNOHANG);
146  }
147  return fclose (fp);
148 }
FILE * openvas_popen4(const char *cmd, char *const args[], pid_t *ppid, int inice)
Definition: popen.c:36
#define RLIM_INFINITY
Definition: popen.c:32
void log_legacy_write(const char *format,...)
Legacy function to write a log message.
int openvas_pclose(FILE *fp, pid_t pid)
Definition: popen.c:136