gnunet_os_lib.h (21047B)
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 * Setup OS subsystem for the given project data and package. 325 * Initializes GNU Gettext. 326 * 327 * @param package_name name of the package for GNU gettext 328 * @param pd project data to use to determine paths 329 */ 330 void 331 GNUNET_OS_init (const char *package_name, 332 const struct GNUNET_OS_ProjectData *pd); 333 334 335 /** 336 * Get the path to a specific GNUnet installation directory or, with 337 * #GNUNET_OS_IPK_SELF_PREFIX, the current running apps installation 338 * directory. 339 * 340 * @param pd project data to use to determine paths 341 * @param dirkind what kind of directory is desired? 342 * @return a pointer to the dir path (to be freed by the caller) 343 */ 344 char * 345 GNUNET_OS_installation_get_path (const struct GNUNET_OS_ProjectData *pd, 346 enum GNUNET_OS_InstallationPathKind dirkind); 347 348 349 /** 350 * Given the name of a gnunet-helper, gnunet-service or gnunet-daemon 351 * binary, try to prefix it with the libexec/-directory to get the 352 * full path. 353 * 354 * @param pd project data to use to determine paths 355 * @param progname name of the binary 356 * @return full path to the binary, if possible, otherwise copy of 'progname' 357 */ 358 char * 359 GNUNET_OS_get_libexec_binary_path (const struct GNUNET_OS_ProjectData *pd, 360 const char *progname); 361 362 363 /** 364 * Given the name of a helper, service or daemon binary construct the full 365 * path to the binary using the SUID_BINARY_PATH in the PATHS section of the 366 * configuration. If that option is not present, fall back to 367 * GNUNET_OS_get_libexec_binary_path. If @a progname is an absolute path, a 368 * copy of this path is returned. 369 * 370 * @param pd project data to use to determine paths 371 * @param cfg configuration to inspect 372 * @param progname name of the binary 373 * @return full path to the binary, if possible, a copy of @a progname 374 * otherwise 375 */ 376 char * 377 GNUNET_OS_get_suid_binary_path (const struct GNUNET_OS_ProjectData *pd, 378 const struct GNUNET_CONFIGURATION_Handle *cfg, 379 const char *progname); 380 381 382 /** 383 * Callback function invoked for each interface found. 384 * 385 * @param cls closure 386 * @param name name of the interface (can be NULL for unknown) 387 * @param isDefault is this presumably the default interface 388 * @param addr address of this interface (can be NULL for unknown or unassigned) 389 * @param broadcast_addr the broadcast address (can be NULL for unknown or unassigned) 390 * @param netmask the network mask (can be NULL for unknown or unassigned) 391 * @param addrlen length of the address 392 * @return #GNUNET_OK to continue iteration, #GNUNET_SYSERR to abort 393 */ 394 typedef enum GNUNET_GenericReturnValue 395 (*GNUNET_OS_NetworkInterfaceProcessor)(void *cls, 396 const char *name, 397 int isDefault, 398 const struct sockaddr *addr, 399 const struct sockaddr *broadcast_addr, 400 const struct sockaddr *netmask, 401 socklen_t addrlen); 402 403 404 /** 405 * @brief Enumerate all network interfaces 406 * 407 * @param proc the callback function 408 * @param proc_cls closure for @a proc 409 */ 410 void 411 GNUNET_OS_network_interfaces_list (GNUNET_OS_NetworkInterfaceProcessor proc, 412 void *proc_cls); 413 414 #ifndef HAVE_SYSCONF 415 #define HAVE_SYSCONF 0 416 #endif 417 418 /** 419 * @brief Get maximum string length returned by gethostname() 420 */ 421 #if HAVE_SYSCONF && defined(_SC_HOST_NAME_MAX) 422 #define GNUNET_OS_get_hostname_max_length() ({ int __sc_tmp = sysconf ( \ 423 _SC_HOST_NAME_MAX); __sc_tmp <= \ 424 0 ? 255 : __sc_tmp; }) 425 #elif defined(HOST_NAME_MAX) 426 #define GNUNET_OS_get_hostname_max_length() HOST_NAME_MAX 427 #else 428 #define GNUNET_OS_get_hostname_max_length() 255 429 #endif 430 431 432 /** 433 * Get process structure for current process 434 * 435 * The pointer it returns points to static memory location and must not be 436 * deallocated/closed 437 * 438 * @return pointer to the process sturcutre for this process 439 */ 440 struct GNUNET_OS_Process * 441 GNUNET_OS_process_current (void); 442 443 444 /** 445 * Sends a signal to the process 446 * 447 * @param proc pointer to process structure 448 * @param sig signal 449 * @return 0 on success, -1 on error 450 */ 451 int 452 GNUNET_OS_process_kill (struct GNUNET_OS_Process *proc, 453 int sig); 454 455 456 /** 457 * Cleans up process structure contents (OS-dependent) and deallocates it 458 * 459 * @param proc pointer to process structure 460 */ 461 void 462 GNUNET_OS_process_destroy (struct GNUNET_OS_Process *proc); 463 464 465 /** 466 * Get the pid of the process in question 467 * 468 * @param proc the process to get the pid of 469 * 470 * @return the current process id 471 */ 472 pid_t 473 GNUNET_OS_process_get_pid (struct GNUNET_OS_Process *proc); 474 475 476 /** 477 * Start a process. 478 * 479 * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags 480 * @param pipe_stdin pipe to use to send input to child process (or NULL) 481 * @param pipe_stdout pipe to use to get output from child process (or NULL) 482 * @param pipe_stderr pipe to use to get error output from child process (or NULL) 483 * @param filename name of the binary 484 * @param argv NULL-terminated array of arguments to the process 485 * @return pointer to process structure of the new process, NULL on error 486 */ 487 struct GNUNET_OS_Process * 488 GNUNET_OS_start_process_vap ( 489 enum GNUNET_OS_InheritStdioFlags std_inheritance, 490 struct GNUNET_DISK_PipeHandle *pipe_stdin, 491 struct GNUNET_DISK_PipeHandle *pipe_stdout, 492 struct GNUNET_DISK_PipeHandle *pipe_stderr, 493 const char *filename, 494 char *const argv[]); 495 496 497 /** 498 * Start a process. 499 * 500 * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags 501 * @param pipe_stdin pipe to use to send input to child process (or NULL) 502 * @param pipe_stdout pipe to use to get output from child process (or NULL) 503 * @param pipe_stderr pipe to use to get error output from child process (or NULL) 504 * @param filename name of the binary 505 * @param ... NULL-terminated list of arguments to the process 506 * @return pointer to process structure of the new process, NULL on error 507 */ 508 struct GNUNET_OS_Process * 509 GNUNET_OS_start_process ( 510 enum GNUNET_OS_InheritStdioFlags std_inheritance, 511 struct GNUNET_DISK_PipeHandle *pipe_stdin, 512 struct GNUNET_DISK_PipeHandle *pipe_stdout, 513 struct GNUNET_DISK_PipeHandle *pipe_stderr, 514 const char *filename, 515 ...); 516 517 518 /** 519 * Start a process. 520 * 521 * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags 522 * @param pipe_stdin pipe to use to send input to child process (or NULL) 523 * @param pipe_stdout pipe to use to get output from child process (or NULL) 524 * @param pipe_stderr pipe to use to get error output from child process (or NULL) 525 * @param filename name of the binary 526 * @param va NULL-terminated list of arguments to the process 527 * @return pointer to process structure of the new process, NULL on error 528 */ 529 struct GNUNET_OS_Process * 530 GNUNET_OS_start_process_va ( 531 enum GNUNET_OS_InheritStdioFlags std_inheritance, 532 struct GNUNET_DISK_PipeHandle *pipe_stdin, 533 struct GNUNET_DISK_PipeHandle *pipe_stdout, 534 struct GNUNET_DISK_PipeHandle *pipe_stderr, 535 const char *filename, 536 va_list va); 537 538 539 /** 540 * Start a process. 541 * 542 * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags 543 * @param lsocks array of listen sockets to dup systemd-style (or NULL); 544 * must be NULL on platforms where dup is not supported 545 * @param filename name of the binary 546 * @param argv NULL-terminated list of arguments to the process, 547 * including the process name as the first argument 548 * @return pointer to process structure of the new process, NULL on error 549 */ 550 struct GNUNET_OS_Process * 551 GNUNET_OS_start_process_v ( 552 enum GNUNET_OS_InheritStdioFlags std_inheritance, 553 const int *lsocks, 554 const char *filename, 555 char *const argv[]); 556 557 558 /** 559 * Start a process. This function is similar to the GNUNET_OS_start_process_* 560 * except that the filename and arguments can have whole strings which contain 561 * the arguments. These arguments are to be separated by spaces and are parsed 562 * in the order they appear. Arguments containing spaces can be used by 563 * quoting them with @em ". 564 * 565 * @param std_inheritance a set of GNUNET_OS_INHERIT_STD_* flags 566 * @param lsocks array of listen sockets to dup systemd-style (or NULL); 567 * must be NULL on platforms where dup is not supported 568 * @param filename name of the binary. It is valid to have the arguments 569 * in this string when they are separated by spaces. 570 * @param ... more arguments. Should be of type `char *`. It is valid 571 * to have the arguments in these strings when they are separated by 572 * spaces. The last argument MUST be NULL. 573 * @return pointer to process structure of the new process, NULL on error 574 */ 575 struct GNUNET_OS_Process * 576 GNUNET_OS_start_process_s ( 577 enum GNUNET_OS_InheritStdioFlags std_inheritance, 578 const int *lsocks, 579 const char *filename, 580 ...); 581 582 583 /** 584 * Handle to a command action. 585 */ 586 struct GNUNET_OS_CommandHandle; 587 588 589 /** 590 * Type of a function to process a line of output. 591 * 592 * @param cls closure 593 * @param line line of output from a command, NULL for the end 594 */ 595 typedef void 596 (*GNUNET_OS_LineProcessor) (void *cls, const char *line); 597 598 599 /** 600 * Stop/kill a command. 601 * 602 * @param cmd handle to the process 603 */ 604 void 605 GNUNET_OS_command_stop (struct GNUNET_OS_CommandHandle *cmd); 606 607 608 /** 609 * Run the given command line and call the given function 610 * for each line of the output. 611 * 612 * @param proc function to call for each line of the output 613 * @param proc_cls closure for proc 614 * @param timeout when to time out 615 * @param binary command to run 616 * @param ... arguments to command 617 * @return NULL on error 618 */ 619 struct GNUNET_OS_CommandHandle * 620 GNUNET_OS_command_run ( 621 GNUNET_OS_LineProcessor proc, 622 void *proc_cls, 623 struct GNUNET_TIME_Relative timeout, 624 const char *binary, 625 ...); 626 627 628 /** 629 * Retrieve the status of a process. 630 * Nonblocking version. 631 * 632 * @param proc pointer to process structure 633 * @param type status type 634 * @param code return code/signal number 635 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise 636 */ 637 enum GNUNET_GenericReturnValue 638 GNUNET_OS_process_status (struct GNUNET_OS_Process *proc, 639 enum GNUNET_OS_ProcessStatusType *type, 640 unsigned long *code); 641 642 643 /** 644 * Wait for a process to terminate. The return code is discarded. 645 * You must not use #GNUNET_OS_process_status() on the same process 646 * after calling this function! This function is blocking and should 647 * thus only be used if the child process is known to have terminated 648 * or to terminate very soon. 649 * 650 * @param proc pointer to process structure of the process to wait for 651 * @return #GNUNET_OK on success, #GNUNET_SYSERR otherwise 652 */ 653 enum GNUNET_GenericReturnValue 654 GNUNET_OS_process_wait (struct GNUNET_OS_Process *proc); 655 656 657 /** 658 * Retrieve the status of a process, waiting on it if dead. 659 * Blocking version. 660 * 661 * @param proc pointer to process structure 662 * @param type status type 663 * @param code return code/signal number 664 * @return #GNUNET_OK on success, #GNUNET_NO if the process is still running, #GNUNET_SYSERR otherwise 665 */ 666 enum GNUNET_GenericReturnValue 667 GNUNET_OS_process_wait_status (struct GNUNET_OS_Process *proc, 668 enum GNUNET_OS_ProcessStatusType *type, 669 unsigned long *code); 670 671 672 /** 673 * Connects this process to its parent via pipe; 674 * essentially, the parent control handler will read signal numbers 675 * from the #GNUNET_OS_CONTROL_PIPE (as given in an environment 676 * variable) and raise those signals. 677 * 678 * @param cls closure (unused) 679 */ 680 void 681 GNUNET_OS_install_parent_control_handler (void *cls); 682 683 684 /** 685 * Check whether an executable exists and possibly 686 * if the suid bit is set on the file. 687 * Attempts to find the file using the current 688 * PATH environment variable as a search path. 689 * 690 * @param binary the name of the file to check. 691 * W32: must not have an .exe suffix. 692 * @param check_suid input true if the binary should be checked for SUID (*nix) 693 * W32: checks if the program has sufficient privileges by executing this 694 * binary with the -d flag. -d omits a programs main loop and only 695 * executes all privileged operations in an binary. 696 * @param params parameters used for w32 privilege checking (can be NULL for != w32, or when not checking for suid/permissions ) 697 * @return #GNUNET_YES if the file is SUID (*nix) or can be executed with current privileges (W32), 698 * #GNUNET_NO if not SUID (but binary exists), 699 * #GNUNET_SYSERR on error (no such binary or not executable) 700 */ 701 enum GNUNET_GenericReturnValue 702 GNUNET_OS_check_helper_binary (const char *binary, 703 bool check_suid, 704 const char *params); 705 706 707 #if 0 /* keep Emacsens' auto-indent happy */ 708 { 709 #endif 710 #ifdef __cplusplus 711 } 712 #endif 713 714 /* ifndef GNUNET_OS_LIB_H */ 715 #endif 716 717 /** @} */ /* end of group */ 718 719 /** @} */ /* end of group addition */ 720 721 /* end of gnunet_os_lib.h */