bb0840029e546bb24fe786d99c32121b69d0d2c0
[oweals/gnunet.git] / src / include / gnunet_os_lib.h
1 /*
2      This file is part of GNUnet.
3      Copyright (C) 2001, 2002, 2003, 2004, 2005, 2006, 2011 Christian Grothoff (and other contributing authors)
4
5      GNUnet is free software; you can redistribute it and/or modify
6      it under the terms of the GNU General Public License as published
7      by the Free Software Foundation; either version 3, or (at your
8      option) any later version.
9
10      GNUnet is distributed in the hope that it will be useful, but
11      WITHOUT ANY WARRANTY; without even the implied warranty of
12      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13      General Public License for more details.
14
15      You should have received a copy of the GNU General Public License
16      along with GNUnet; see the file COPYING.  If not, write to the
17      Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18      Boston, MA 02110-1301, USA.
19 */
20
21 /**
22  * @file
23  * Low level process routines
24  *
25  * @author Christian Grothoff
26  * @author Krista Bennett
27  * @author Gerd Knorr <kraxel@bytesex.org>
28  * @author Ioana Patrascu
29  * @author Tzvetan Horozov
30  * @author Milan
31  *
32  * This code manages child processes.  We can communicate with child
33  * processes using signals.  Because signals are not supported on W32
34  * and Java (at least not nicely), we can alternatively use a pipe
35  * to send signals to the child processes (if the child process is
36  * a full-blown GNUnet process that supports reading signals from
37  * a pipe, of course).  Naturally, this also only works for 'normal'
38  * termination via signals, and not as a replacement for SIGKILL.
39  * Thus using pipes to communicate signals should only be enabled if
40  * the child is a Java process OR if we are on Windoze.
41  */
42
43 #ifndef GNUNET_OS_LIB_H
44 #define GNUNET_OS_LIB_H
45
46 #ifdef __cplusplus
47 extern "C"
48 {
49 #if 0                           /* keep Emacsens' auto-indent happy */
50 }
51 #endif
52 #endif
53
54 #include "gnunet_common.h"
55 #include "gnunet_configuration_lib.h"
56 #include "gnunet_scheduler_lib.h"
57
58
59 /**
60  * Flags that determine which of the standard streams
61  * should be inherited by the child process.
62  */
63 enum GNUNET_OS_InheritStdioFlags
64 {
65
66   /**
67    * No standard streams should be inherited.
68    */
69   GNUNET_OS_INHERIT_STD_NONE = 0,
70
71   /**
72    * When this flag is set, the child process will
73    * inherit stdin of the parent.
74    */
75   GNUNET_OS_INHERIT_STD_IN = 1,
76
77   /**
78    * When this flag is set, the child process will
79    * inherit stdout of the parent.
80    */
81   GNUNET_OS_INHERIT_STD_OUT = 2,
82
83   /**
84    * When this flag is set, the child process will
85    * inherit stderr of the parent.
86    */
87   GNUNET_OS_INHERIT_STD_ERR = 4,
88
89   /**
90    * When these flags are set, the child process will
91    * inherit stdout and stderr of the parent.
92    */
93   GNUNET_OS_INHERIT_STD_OUT_AND_ERR = 6,
94
95   /**
96    * Use this option to have all of the standard streams
97    * (stdin, stdout and stderror) be inherited.
98    */
99   GNUNET_OS_INHERIT_STD_ALL = 7
100 };
101
102
103 /**
104  * Process information (OS-dependent)
105  */
106 struct GNUNET_OS_Process;
107
108
109 /**
110  * Possible installation paths to request
111  */
112 enum GNUNET_OS_InstallationPathKind
113 {
114   /**
115    * Return the "PREFIX" directory given to configure.
116    */
117   GNUNET_OS_IPK_PREFIX,
118
119   /**
120    * Return the directory where the program binaries are installed. (bin/)
121    */
122   GNUNET_OS_IPK_BINDIR,
123
124   /**
125    * Return the directory where libraries are installed. (lib/gnunet/)
126    */
127   GNUNET_OS_IPK_LIBDIR,
128
129   /**
130    * Return the directory where data is installed (share/gnunet/)
131    */
132   GNUNET_OS_IPK_DATADIR,
133
134   /**
135    * Return the directory where translations are installed (share/locale/)
136    */
137   GNUNET_OS_IPK_LOCALEDIR,
138
139   /**
140    * Return the installation directory of this application, not
141    * the one of the overall GNUnet installation (in case they
142    * are different).
143    */
144   GNUNET_OS_IPK_SELF_PREFIX,
145
146   /**
147    * Return the prefix of the path with application icons (share/icons/).
148    */
149   GNUNET_OS_IPK_ICONDIR,
150
151   /**
152    * Return the prefix of the path with documentation files, including the
153    * license (share/doc/gnunet/).
154    */
155   GNUNET_OS_IPK_DOCDIR,
156
157   /**
158    * Return the directory where helper binaries are installed (lib/gnunet/libexec/)
159    */
160   GNUNET_OS_IPK_LIBEXECDIR
161 };
162
163
164 /**
165  * Process status types
166  */
167 enum GNUNET_OS_ProcessStatusType
168 {
169   /**
170    * The process is not known to the OS (or at
171    * least not one of our children).
172    */
173   GNUNET_OS_PROCESS_UNKNOWN,
174
175   /**
176    * The process is still running.
177    */
178   GNUNET_OS_PROCESS_RUNNING,
179
180   /**
181    * The process is paused (but could be resumed).
182    */
183   GNUNET_OS_PROCESS_STOPPED,
184
185   /**
186    * The process exited with a return code.
187    */
188   GNUNET_OS_PROCESS_EXITED,
189
190   /**
191    * The process was killed by a signal.
192    */
193   GNUNET_OS_PROCESS_SIGNALED
194 };
195
196
197 /**
198  * Get the path to a specific GNUnet installation directory or, with
199  * #GNUNET_OS_IPK_SELF_PREFIX, the current running apps installation
200  * directory.
201  *
202  * @param dirkind what kind of directory is desired?
203  * @return a pointer to the dir path (to be freed by the caller)
204  */
205 char *
206 GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind);
207
208
209 /**
210  * Given the name of a gnunet-helper, gnunet-service or gnunet-daemon
211  * binary, try to prefix it with the libexec/-directory to get the
212  * full path.
213  *
214  * @param progname name of the binary
215  * @return full path to the binary, if possible, otherwise copy of 'progname'
216  */
217 char *
218 GNUNET_OS_get_libexec_binary_path (const char *progname);
219
220
221 /**
222  * Callback function invoked for each interface found.
223  *
224  * @param cls closure
225  * @param name name of the interface (can be NULL for unknown)
226  * @param isDefault is this presumably the default interface
227  * @param addr address of this interface (can be NULL for unknown or unassigned)
228  * @param broadcast_addr the broadcast address (can be NULL for unknown or unassigned)
229  * @param netmask the network mask (can be NULL for unknown or unassigned)
230  * @param addrlen length of the address
231  * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort
232  */
233 typedef int
234 (*GNUNET_OS_NetworkInterfaceProcessor) (void *cls,
235                                         const char *name,
236                                         int isDefault,
237                                         const struct sockaddr *addr,
238                                         const struct sockaddr *broadcast_addr,
239                                         const struct sockaddr *netmask,
240                                         socklen_t addrlen);
241
242
243 /**
244  * @brief Enumerate all network interfaces
245  *
246  * @param proc the callback function
247  * @param proc_cls closure for @a proc
248  */
249 void
250 GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc,
251                                    void *proc_cls);
252
253 /**
254  * @brief Get maximum string length returned by gethostname()
255  */
256 #if HAVE_SYSCONF && defined(_SC_HOST_NAME_MAX)
257 #define GNUNET_OS_get_hostname_max_length() ({ int __sc_tmp = sysconf(_SC_HOST_NAME_MAX); __sc_tmp <= 0 ? 255 : __sc_tmp; })
258 #elif defined(HOST_NAME_MAX)
259 #define GNUNET_OS_get_hostname_max_length() HOST_NAME_MAX
260 #else
261 #define GNUNET_OS_get_hostname_max_length() 255
262 #endif
263
264
265 /**
266  * Get process structure for current process
267  *
268  * The pointer it returns points to static memory location and must not be
269  * deallocated/closed
270  *
271  * @return pointer to the process sturcutre for this process
272  */
273 struct GNUNET_OS_Process *
274 GNUNET_OS_process_current (void);
275
276
277 /**
278  * Sends a signal to the process
279  *
280  * @param proc pointer to process structure
281  * @param sig signal
282  * @return 0 on success, -1 on error
283  */
284 int
285 GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig);
286
287
288 /**
289  * Cleans up process structure contents (OS-dependent) and deallocates it
290  *
291  * @param proc pointer to process structure
292  */
293 void
294 GNUNET_OS_process_destroy (struct GNUNET_OS_Process *proc);
295
296
297 /**
298  * Get the pid of the process in question
299  *
300  * @param proc the process to get the pid of
301  *
302  * @return the current process id
303  */
304 pid_t
305 GNUNET_OS_process_get_pid (struct GNUNET_OS_Process *proc);
306
307
308 /**
309  * Start a process.
310  *
311  * @param pipe_control should a pipe be used to send signals to the child?
312  * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags
313  * @param pipe_stdin pipe to use to send input to child process (or NULL)
314  * @param pipe_stdout pipe to use to get output from child process (or NULL)
315  * @param pipe_stderr pipe to use to get error output from child process (or NULL)
316  * @param filename name of the binary
317  * @param argv NULL-terminated array of arguments to the process
318  * @return pointer to process structure of the new process, NULL on error
319  */
320 struct GNUNET_OS_Process *
321 GNUNET_OS_start_process_vap (int pipe_control,
322                              enum GNUNET_OS_InheritStdioFlags std_inheritance,
323                              struct GNUNET_DISK_PipeHandle *pipe_stdin,
324                              struct GNUNET_DISK_PipeHandle *pipe_stdout,
325                              struct GNUNET_DISK_PipeHandle *pipe_stderr,
326                              const char *filename,
327                              char *const argv[]);
328
329
330 /**
331  * Start a process.
332  *
333  * @param pipe_control should a pipe be used to send signals to the child?
334  * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags
335  * @param pipe_stdin pipe to use to send input to child process (or NULL)
336  * @param pipe_stdout pipe to use to get output from child process (or NULL)
337  * @param pipe_stderr pipe to use to get error output from child process (or NULL)
338  * @param filename name of the binary
339  * @param ... NULL-terminated list of arguments to the process
340  * @return pointer to process structure of the new process, NULL on error
341  */
342 struct GNUNET_OS_Process *
343 GNUNET_OS_start_process (int pipe_control,
344                          enum GNUNET_OS_InheritStdioFlags std_inheritance,
345                          struct GNUNET_DISK_PipeHandle *pipe_stdin,
346                          struct GNUNET_DISK_PipeHandle *pipe_stdout,
347                          struct GNUNET_DISK_PipeHandle *pipe_stderr,
348                          const char *filename, ...);
349
350
351 /**
352  * Start a process.
353  *
354  * @param pipe_control should a pipe be used to send signals to the child?
355  * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags
356  * @param pipe_stdin pipe to use to send input to child process (or NULL)
357  * @param pipe_stdout pipe to use to get output from child process (or NULL)
358  * @param pipe_stderr pipe to use to get error output from child process (or NULL)
359  * @param filename name of the binary
360  * @param va NULL-terminated list of arguments to the process
361  * @return pointer to process structure of the new process, NULL on error
362  */
363 struct GNUNET_OS_Process *
364 GNUNET_OS_start_process_va (int pipe_control,
365                             enum GNUNET_OS_InheritStdioFlags std_inheritance,
366                             struct GNUNET_DISK_PipeHandle *pipe_stdin,
367                             struct GNUNET_DISK_PipeHandle *pipe_stdout,
368                             struct GNUNET_DISK_PipeHandle *pipe_stderr,
369                             const char *filename, va_list va);
370
371 /**
372  * Start a process.
373  *
374  * @param pipe_control should a pipe be used to send signals to the child?
375  * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags
376  * @param lsocks array of listen sockets to dup systemd-style (or NULL);
377  *         must be NULL on platforms where dup is not supported
378  * @param filename name of the binary
379  * @param argv NULL-terminated list of arguments to the process,
380  *             including the process name as the first argument
381  * @return pointer to process structure of the new process, NULL on error
382  */
383 struct GNUNET_OS_Process *
384 GNUNET_OS_start_process_v (int pipe_control,
385                            enum GNUNET_OS_InheritStdioFlags std_inheritance,
386                            const SOCKTYPE *lsocks,
387                            const char *filename,
388                            char *const argv[]);
389
390
391 /**
392  * Start a process.  This function is similar to the GNUNET_OS_start_process_*
393  * except that the filename and arguments can have whole strings which contain
394  * the arguments.  These arguments are to be separated by spaces and are parsed
395  * in the order they appear.  Arguments containing spaces can be used by
396  * quoting them with @em ".
397  *
398  * @param pipe_control should a pipe be used to send signals to the child?
399  * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags
400  * @param lsocks array of listen sockets to dup systemd-style (or NULL);
401  *         must be NULL on platforms where dup is not supported
402  * @param filename name of the binary.  It is valid to have the arguments
403  *         in this string when they are separated by spaces.
404  * @param ... more arguments.  Should be of type `char *`.  It is valid
405  *         to have the arguments in these strings when they are separated by
406  *         spaces.  The last argument MUST be NULL.
407  * @return pointer to process structure of the new process, NULL on error
408  */
409 struct GNUNET_OS_Process *
410 GNUNET_OS_start_process_s (int pipe_control,
411                            unsigned int std_inheritance,
412                            const SOCKTYPE * lsocks,
413                            const char *filename, ...);
414
415
416 /**
417  * Handle to a command action.
418  */
419 struct GNUNET_OS_CommandHandle;
420
421
422 /**
423  * Type of a function to process a line of output.
424  *
425  * @param cls closure
426  * @param line line of output from a command, NULL for the end
427  */
428 typedef void (*GNUNET_OS_LineProcessor) (void *cls, const char *line);
429
430
431 /**
432  * Stop/kill a command.
433  *
434  * @param cmd handle to the process
435  */
436 void
437 GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd);
438
439
440 /**
441  * Run the given command line and call the given function
442  * for each line of the output.
443  *
444  * @param proc function to call for each line of the output
445  * @param proc_cls closure for proc
446  * @param timeout when to time out
447  * @param binary command to run
448  * @param ... arguments to command
449  * @return NULL on error
450  */
451 struct GNUNET_OS_CommandHandle *
452 GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc, void *proc_cls,
453                        struct GNUNET_TIME_Relative timeout, const char *binary,
454                        ...);
455
456
457 /**
458  * Retrieve the status of a process, waiting on him if dead.
459  * Nonblocking version.
460  *
461  * @param proc pointer to process structure
462  * @param type status type
463  * @param code return code/signal number
464  * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise
465  */
466 int
467 GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
468                           enum GNUNET_OS_ProcessStatusType *type,
469                           unsigned long *code);
470
471
472 /**
473  * Wait for a process to terminate.  The return code is discarded.
474  * You must not use #GNUNET_OS_process_status() on the same process
475  * after calling this function!  This function is blocking and should
476  * thus only be used if the child process is known to have terminated
477  * or to terminate very soon.
478  *
479  * @param proc pointer to process structure of the process to wait for
480  * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise
481  */
482 int
483 GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc);
484
485
486 /**
487  * Connects this process to its parent via pipe;
488  * essentially, the parent control handler will read signal numbers
489  * from the #GNUNET_OS_CONTROL_PIPE (as given in an environment
490  * variable) and raise those signals.
491  *
492  * @param cls closure (unused)
493  * @param tc scheduler context (unused)
494  */
495 void
496 GNUNET_OS_install_parent_control_handler (void *cls,
497                                           const struct
498                                           GNUNET_SCHEDULER_TaskContext *tc);
499
500
501 /**
502  * Check whether an executable exists and possibly
503  * if the suid bit is set on the file.
504  * Attempts to find the file using the current
505  * PATH environment variable as a search path.
506  *
507  * @param binary the name of the file to check.
508  *        W32: must not have an .exe suffix.
509  * @param check_suid input true if the binary should be checked for SUID (*nix)
510  *        W32: checks if the program has sufficient privileges by executing this
511  *             binary with the -d flag. -d omits a programs main loop and only
512  *             executes all privileged operations in an binary.
513  * @param params parameters used for w32 privilege checking (can be NULL for != w32, or when not checking for suid/permissions )
514  * @return #GNUNET_YES if the file is SUID (*nix) or can be executed with current privileges (W32),
515  *         #GNUNET_NO if not SUID (but binary exists),
516  *         #GNUNET_SYSERR on error (no such binary or not executable)
517  */
518 int
519 GNUNET_OS_check_helper_binary (const char *binary,
520                                int check_suid,
521                                const char *params);
522
523
524 #if 0                           /* keep Emacsens' auto-indent happy */
525 {
526 #endif
527 #ifdef __cplusplus
528 }
529 #endif
530
531
532 /* ifndef GNUNET_OS_LIB_H */
533 #endif
534 /* end of gnunet_os_lib.h */