gnunet_os_lib.h 20 KB

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