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