-fix
[oweals/gnunet.git] / src / include / gnunet_os_lib.h
1 /*
2      This file is part of GNUnet.
3      (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 2, 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., 59 Temple Place - Suite 330,
18      Boston, MA 02111-1307, USA.
19 */
20
21 /**
22  * @file include/gnunet_os_lib.h
23  * @brief low level process routines
24  * @author Christian Grothoff
25  * @author Krista Bennett
26  * @author Gerd Knorr <kraxel@bytesex.org>
27  * @author Ioana Patrascu
28  * @author Tzvetan Horozov
29  * @author Milan
30  *
31  * This code manages child processes.  We can communicate with child
32  * processes using signals.  Because signals are not supported on W32
33  * and Java (at least not nicely), we can alternatively use a pipe
34  * to send signals to the child processes (if the child process is
35  * a full-blown GNUnet process that supports reading signals from 
36  * a pipe, of course).  Naturally, this also only works for 'normal'
37  * termination via signals, and not as a replacement for SIGKILL.
38  * Thus using pipes to communicate signals should only be enabled if
39  * the child is a Java process OR if we are on Windoze.
40  */
41
42 #ifndef GNUNET_OS_LIB_H
43 #define GNUNET_OS_LIB_H
44
45 #ifdef __cplusplus
46 extern "C"
47 {
48 #if 0                           /* keep Emacsens' auto-indent happy */
49 }
50 #endif
51 #endif
52
53 #include "gnunet_common.h"
54 #include "gnunet_configuration_lib.h"
55 #include "gnunet_scheduler_lib.h"
56
57 /**
58  * Process information (OS-dependent)
59  */
60 struct GNUNET_OS_Process;
61
62
63 /**
64  * Possible installation paths to request
65  */
66 enum GNUNET_OS_InstallationPathKind
67 {
68   /**
69    * Return the "PREFIX" directory given to configure.
70    */
71   GNUNET_OS_IPK_PREFIX,
72
73   /**
74    * Return the directory where the program binaries are installed. (bin/)
75    */
76   GNUNET_OS_IPK_BINDIR,
77
78   /**
79    * Return the directory where libraries are installed. (lib/gnunet/)
80    */
81   GNUNET_OS_IPK_LIBDIR,
82
83   /**
84    * Return the directory where data is installed (share/gnunet/)
85    */
86   GNUNET_OS_IPK_DATADIR,
87
88   /**
89    * Return the directory where translations are installed (share/locale/)
90    */
91   GNUNET_OS_IPK_LOCALEDIR,
92
93   /**
94    * Return the installation directory of this application, not
95    * the one of the overall GNUnet installation (in case they
96    * are different).
97    */
98   GNUNET_OS_IPK_SELF_PREFIX,
99
100   /**
101    * Return the prefix of the path with application icons (share/icons/).
102    */
103   GNUNET_OS_IPK_ICONDIR,
104
105   /**
106    * Return the prefix of the path with documentation files, including the
107    * license (share/doc/gnunet/).
108    */
109   GNUNET_OS_IPK_DOCDIR
110 };
111
112
113 /**
114  * Process status types
115  */
116 enum GNUNET_OS_ProcessStatusType
117 {
118   /**
119    * The process is not known to the OS (or at
120    * least not one of our children).
121    */
122   GNUNET_OS_PROCESS_UNKNOWN,
123
124   /**
125    * The process is still running.
126    */
127   GNUNET_OS_PROCESS_RUNNING,
128
129   /**
130    * The process is paused (but could be resumed).
131    */
132   GNUNET_OS_PROCESS_STOPPED,
133
134   /**
135    * The process exited with a return code.
136    */
137   GNUNET_OS_PROCESS_EXITED,
138
139   /**
140    * The process was killed by a signal.
141    */
142   GNUNET_OS_PROCESS_SIGNALED
143 };
144
145
146 /**
147  * Get the path to a specific GNUnet installation directory or, with
148  * GNUNET_OS_IPK_SELF_PREFIX, the current running apps installation
149  * directory.
150  *
151  * @param dirkind what kind of directory is desired?
152  * @return a pointer to the dir path (to be freed by the caller)
153  */
154 char *
155 GNUNET_OS_installation_get_path (enum GNUNET_OS_InstallationPathKind dirkind);
156
157
158 /**
159  * Callback function invoked for each interface found.
160  *
161  * @param cls closure
162  * @param name name of the interface (can be NULL for unknown)
163  * @param isDefault is this presumably the default interface
164  * @param addr address of this interface (can be NULL for unknown or unassigned)
165  * @param broadcast_addr the broadcast address (can be NULL for unknown or unassigned)
166  * @param netmask the network mask (can be NULL for unknown or unassigned))
167  * @param addrlen length of the address
168  * @return GNUNET_OK to continue iteration, GNUNET_SYSERR to abort
169  */
170 typedef int (*GNUNET_OS_NetworkInterfaceProcessor) (void *cls, const char *name,
171                                                     int isDefault,
172                                                     const struct sockaddr *
173                                                     addr,
174                                                     const struct sockaddr *
175                                                     broadcast_addr,
176                                                     const struct sockaddr *
177                                                     netmask, socklen_t addrlen);
178
179
180 /**
181  * @brief Enumerate all network interfaces
182  * @param proc the callback function
183  * @param proc_cls closure for proc
184  */
185 void
186 GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc,
187                                    void *proc_cls);
188
189 /**
190  * @brief Get maximum string length returned by gethostname()
191  */
192 #if HAVE_SYSCONF && defined(_SC_HOST_NAME_MAX)
193 #define GNUNET_OS_get_hostname_max_length() ({ int __sc_tmp = sysconf(_SC_HOST_NAME_MAX); __sc_tmp <= 0 ? 255 : __sc_tmp; })
194 #elif defined(HOST_NAME_MAX)
195 #define GNUNET_OS_get_hostname_max_length() HOST_NAME_MAX
196 #else
197 #define GNUNET_OS_get_hostname_max_length() 255
198 #endif
199
200
201 /**
202  * Get process structure for current process
203  *
204  * The pointer it returns points to static memory location and must not be
205  * deallocated/closed
206  *
207  * @return pointer to the process sturcutre for this process
208  */
209 struct GNUNET_OS_Process *
210 GNUNET_OS_process_current (void);
211
212
213 /**
214  * Sends a signal to the process
215  *
216  * @param proc pointer to process structure
217  * @param sig signal
218  * @return 0 on success, -1 on error
219  */
220 int
221 GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, int sig);
222
223
224 /**
225  * Cleans up process structure contents (OS-dependent) and deallocates it
226  *
227  * @param proc pointer to process structure
228  */
229 void
230 GNUNET_OS_process_close (struct GNUNET_OS_Process *proc);
231
232
233 /**
234  * Get the pid of the process in question
235  *
236  * @param proc the process to get the pid of
237  *
238  * @return the current process id
239  */
240 pid_t
241 GNUNET_OS_process_get_pid (struct GNUNET_OS_Process *proc);
242
243
244 /**
245  * Set process priority
246  *
247  * @param proc pointer to process structure
248  * @param prio priority value
249  * @return GNUNET_OK on success, GNUNET_SYSERR on error
250  */
251 int
252 GNUNET_OS_set_process_priority (struct GNUNET_OS_Process *proc,
253                                 enum GNUNET_SCHEDULER_Priority prio);
254
255
256 /**
257  * Start a process.
258  *
259  * @param pipe_control should a pipe be used to send signals to the child?
260  * @param pipe_stdin pipe to use to send input to child process (or NULL)
261  * @param pipe_stdout pipe to use to get output from child process (or NULL)
262  * @param filename name of the binary
263  * @param argv NULL-terminated array of arguments to the process
264  * @return pointer to process structure of the new process, NULL on error
265  */
266 struct GNUNET_OS_Process *
267 GNUNET_OS_start_process_vap (int pipe_control,
268                              struct GNUNET_DISK_PipeHandle *pipe_stdin,
269                              struct GNUNET_DISK_PipeHandle *pipe_stdout,
270                              const char *filename, 
271                              char *const argv[]);
272
273
274 /**
275  * Start a process.
276  *
277  * @param pipe_control should a pipe be used to send signals to the child?
278  * @param pipe_stdin pipe to use to send input to child process (or NULL)
279  * @param pipe_stdout pipe to use to get output from child process (or NULL)
280  * @param filename name of the binary
281  * @param ... NULL-terminated list of arguments to the process
282  * @return pointer to process structure of the new process, NULL on error
283  */
284 struct GNUNET_OS_Process *
285 GNUNET_OS_start_process (int pipe_control,
286                          struct GNUNET_DISK_PipeHandle *pipe_stdin,
287                          struct GNUNET_DISK_PipeHandle *pipe_stdout,
288                          const char *filename, ...);
289
290
291 /**
292  * Start a process.
293  *
294  * @param pipe_control should a pipe be used to send signals to the child?
295  * @param pipe_stdin pipe to use to send input to child process (or NULL)
296  * @param pipe_stdout pipe to use to get output from child process (or NULL)
297  * @param filename name of the binary
298  * @param va NULL-terminated list of arguments to the process
299  * @return pointer to process structure of the new process, NULL on error
300  */
301 struct GNUNET_OS_Process *
302 GNUNET_OS_start_process_va (int pipe_control,
303                             struct GNUNET_DISK_PipeHandle *pipe_stdin,
304                             struct GNUNET_DISK_PipeHandle *pipe_stdout,
305                             const char *filename, va_list va);
306
307 /**
308  * Start a process.
309  *
310  * @param pipe_control should a pipe be used to send signals to the child?
311  * @param lsocks array of listen sockets to dup systemd-style (or NULL);
312  *         must be NULL on platforms where dup is not supported
313  * @param filename name of the binary
314  * @param argv NULL-terminated list of arguments to the process,
315  *             including the process name as the first argument
316  * @return pointer to process structure of the new process, NULL on error
317  */
318 struct GNUNET_OS_Process *
319 GNUNET_OS_start_process_v (int pipe_control,
320                            const SOCKTYPE *lsocks, 
321                            const char *filename,
322                            char *const argv[]);
323
324
325 /**
326  * Handle to a command action.
327  */
328 struct GNUNET_OS_CommandHandle;
329
330
331 /**
332  * Type of a function to process a line of output.
333  *
334  * @param cls closure
335  * @param line line of output from a command, NULL for the end
336  */
337 typedef void (*GNUNET_OS_LineProcessor) (void *cls, const char *line);
338
339
340 /**
341  * Stop/kill a command.
342  *
343  * @param cmd handle to the process
344  */
345 void
346 GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd);
347
348
349 /**
350  * Run the given command line and call the given function
351  * for each line of the output.
352  *
353  * @param proc function to call for each line of the output
354  * @param proc_cls closure for proc
355  * @param timeout when to time out
356  * @param binary command to run
357  * @param ... arguments to command
358  * @return NULL on error
359  */
360 struct GNUNET_OS_CommandHandle *
361 GNUNET_OS_command_run (GNUNET_OS_LineProcessor proc, void *proc_cls,
362                        struct GNUNET_TIME_Relative timeout, const char *binary,
363                        ...);
364
365
366 /**
367  * Retrieve the status of a process.  Nonblocking version.
368  *
369  * @param proc pointer to process structure
370  * @param type status type
371  * @param code return code/signal number
372  * @return GNUNET_OK on success, GNUNET_NO if the process is still running, GNUNET_SYSERR otherwise
373  */
374 int
375 GNUNET_OS_process_status (struct GNUNET_OS_Process *proc,
376                           enum GNUNET_OS_ProcessStatusType *type,
377                           unsigned long *code);
378
379
380 /**
381  * Wait for a process to terminate.  The return code is discarded.
382  * You must not use 'GNUNET_OS_process_status' on the same process
383  * after calling this function!  This function is blocking and should
384  * thus only be used if the child process is known to have terminated
385  * or to terminate very soon.
386  *
387  * @param proc pointer to process structure of the process to wait for
388  * @return GNUNET_OK on success, GNUNET_SYSERR otherwise
389  */
390 int
391 GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc);
392
393
394 /**
395  * Connects this process to its parent via pipe;
396  * essentially, the parent control handler will read signal numbers
397  * from the 'GNUNET_OS_CONTROL_PIPE' (as given in an environment
398  * variable) and raise those signals.
399  *
400  * @param cls closure (unused)
401  * @param tc scheduler context (unused)
402  */
403 void
404 GNUNET_OS_install_parent_control_handler (void *cls,
405                                           const struct
406                                           GNUNET_SCHEDULER_TaskContext *tc);
407
408
409 /**
410  * Check whether an executable exists and possibly
411  * if the suid bit is set on the file.
412  * Attempts to find the file using the current
413  * PATH environment variable as a search path.
414  *
415  * @param binary the name of the file to check
416  * @return GNUNET_YES if the file is SUID,
417  *         GNUNET_NO if not SUID (but binary exists)
418  *         GNUNET_SYSERR on error (no such binary or not executable)
419  */
420 int
421 GNUNET_OS_check_helper_binary (const char *binary);
422
423
424 #if 0                           /* keep Emacsens' auto-indent happy */
425 {
426 #endif
427 #ifdef __cplusplus
428 }
429 #endif
430
431
432 /* ifndef GNUNET_OS_LIB_H */
433 #endif
434 /* end of gnunet_os_lib.h */