11c606a6 (kx 2023-04-11 01:18:34 +0300 1)
11c606a6 (kx 2023-04-11 01:18:34 +0300 2) /**********************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 3)
11c606a6 (kx 2023-04-11 01:18:34 +0300 4) Copyright 2019 Andrey V.Kosteltsev
11c606a6 (kx 2023-04-11 01:18:34 +0300 5)
11c606a6 (kx 2023-04-11 01:18:34 +0300 6) Licensed under the Radix.pro License, Version 1.0 (the "License");
11c606a6 (kx 2023-04-11 01:18:34 +0300 7) you may not use this file except in compliance with the License.
11c606a6 (kx 2023-04-11 01:18:34 +0300 8) You may obtain a copy of the License at
11c606a6 (kx 2023-04-11 01:18:34 +0300 9)
11c606a6 (kx 2023-04-11 01:18:34 +0300 10) https://radix.pro/licenses/LICENSE-1.0-en_US.txt
11c606a6 (kx 2023-04-11 01:18:34 +0300 11)
11c606a6 (kx 2023-04-11 01:18:34 +0300 12) Unless required by applicable law or agreed to in writing, software
11c606a6 (kx 2023-04-11 01:18:34 +0300 13) distributed under the License is distributed on an "AS IS" BASIS,
11c606a6 (kx 2023-04-11 01:18:34 +0300 14) WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
11c606a6 (kx 2023-04-11 01:18:34 +0300 15) implied.
11c606a6 (kx 2023-04-11 01:18:34 +0300 16)
11c606a6 (kx 2023-04-11 01:18:34 +0300 17) **********************************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 18)
11c606a6 (kx 2023-04-11 01:18:34 +0300 19) #include <config.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 20)
11c606a6 (kx 2023-04-11 01:18:34 +0300 21) #include <stdlib.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 22) #include <stdio.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 23) #include <string.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 24) #include <errno.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 25) #include <error.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 26) #include <sys/stat.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 27) #include <sys/wait.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 28) #include <stdarg.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 29) #include <unistd.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 30)
11c606a6 (kx 2023-04-11 01:18:34 +0300 31) #include <msglog.h>
11c606a6 (kx 2023-04-11 01:18:34 +0300 32)
11c606a6 (kx 2023-04-11 01:18:34 +0300 33)
11c606a6 (kx 2023-04-11 01:18:34 +0300 34) static void xexec( const char *cmd )
11c606a6 (kx 2023-04-11 01:18:34 +0300 35) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 36) char *argv[4];
11c606a6 (kx 2023-04-11 01:18:34 +0300 37) const char *shell = getenv ("SHELL");
11c606a6 (kx 2023-04-11 01:18:34 +0300 38)
11c606a6 (kx 2023-04-11 01:18:34 +0300 39) if( !shell ) shell = "/bin/sh";
11c606a6 (kx 2023-04-11 01:18:34 +0300 40)
11c606a6 (kx 2023-04-11 01:18:34 +0300 41) argv[0] = (char *) shell;
11c606a6 (kx 2023-04-11 01:18:34 +0300 42) argv[1] = (char *) "-c";
11c606a6 (kx 2023-04-11 01:18:34 +0300 43) argv[2] = (char *) cmd;
11c606a6 (kx 2023-04-11 01:18:34 +0300 44) argv[3] = NULL;
11c606a6 (kx 2023-04-11 01:18:34 +0300 45)
11c606a6 (kx 2023-04-11 01:18:34 +0300 46) execv( shell, argv );
11c606a6 (kx 2023-04-11 01:18:34 +0300 47)
11c606a6 (kx 2023-04-11 01:18:34 +0300 48) /******************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 49) xexec() is called by child process, and
11c606a6 (kx 2023-04-11 01:18:34 +0300 50) here child process faced to FATAL error:
11c606a6 (kx 2023-04-11 01:18:34 +0300 51) */
11c606a6 (kx 2023-04-11 01:18:34 +0300 52) logmsg( errlog, MSG_FATAL, "%s: Cannot exec", cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 53) exit( EXIT_FAILURE );
11c606a6 (kx 2023-04-11 01:18:34 +0300 54) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 55)
11c606a6 (kx 2023-04-11 01:18:34 +0300 56) static pid_t xfork( void )
11c606a6 (kx 2023-04-11 01:18:34 +0300 57) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 58) pid_t p = fork();
11c606a6 (kx 2023-04-11 01:18:34 +0300 59)
11c606a6 (kx 2023-04-11 01:18:34 +0300 60) if( p == (pid_t) -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 61) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 62) FATAL_ERROR( "Cannot %s", "fork" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 63) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 64)
11c606a6 (kx 2023-04-11 01:18:34 +0300 65) return p;
11c606a6 (kx 2023-04-11 01:18:34 +0300 66) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 67)
11c606a6 (kx 2023-04-11 01:18:34 +0300 68) pid_t sys_exec_command( const char *cmd )
11c606a6 (kx 2023-04-11 01:18:34 +0300 69) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 70) pid_t pid = xfork();
11c606a6 (kx 2023-04-11 01:18:34 +0300 71)
11c606a6 (kx 2023-04-11 01:18:34 +0300 72) if( pid != 0 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 73) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 74) return pid;
11c606a6 (kx 2023-04-11 01:18:34 +0300 75) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 76)
11c606a6 (kx 2023-04-11 01:18:34 +0300 77) xexec( cmd );
11c606a6 (kx 2023-04-11 01:18:34 +0300 78) return pid; /* only to avoid compilaton warning */
11c606a6 (kx 2023-04-11 01:18:34 +0300 79) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 80)
11c606a6 (kx 2023-04-11 01:18:34 +0300 81)
11c606a6 (kx 2023-04-11 01:18:34 +0300 82) /*****************************************************************
11c606a6 (kx 2023-04-11 01:18:34 +0300 83) sys_wait_command() - Wait for pid.
11c606a6 (kx 2023-04-11 01:18:34 +0300 84)
11c606a6 (kx 2023-04-11 01:18:34 +0300 85) Return values:
11c606a6 (kx 2023-04-11 01:18:34 +0300 86) -------------
11c606a6 (kx 2023-04-11 01:18:34 +0300 87) 0 - SUCCESS
11c606a6 (kx 2023-04-11 01:18:34 +0300 88) >=1 - status returned by child process
11c606a6 (kx 2023-04-11 01:18:34 +0300 89) -1 - Child terminated on signal
11c606a6 (kx 2023-04-11 01:18:34 +0300 90) -2 - Child terminated on unknown reason
11c606a6 (kx 2023-04-11 01:18:34 +0300 91) -3 - Cannot waitpid: waitpid() retusrs -1
11c606a6 (kx 2023-04-11 01:18:34 +0300 92)
11c606a6 (kx 2023-04-11 01:18:34 +0300 93) Error message with SIZE length saved into *ERRMSG buffer.
11c606a6 (kx 2023-04-11 01:18:34 +0300 94) *****************************************************************/
11c606a6 (kx 2023-04-11 01:18:34 +0300 95) int sys_wait_command( pid_t pid, char *errmsg, size_t size )
11c606a6 (kx 2023-04-11 01:18:34 +0300 96) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 97) int status;
11c606a6 (kx 2023-04-11 01:18:34 +0300 98)
11c606a6 (kx 2023-04-11 01:18:34 +0300 99) if( pid < 0 ) return (pid_t) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 100)
11c606a6 (kx 2023-04-11 01:18:34 +0300 101) while( waitpid( pid, &status, 0 ) == -1 )
11c606a6 (kx 2023-04-11 01:18:34 +0300 102) if( errno != EINTR )
11c606a6 (kx 2023-04-11 01:18:34 +0300 103) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 104) if( errmsg && size ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 105) (void)snprintf( errmsg, size, "PID %lu: Cannot %s", (unsigned long)pid, "waitpid" );
11c606a6 (kx 2023-04-11 01:18:34 +0300 106) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 107) return (int) -3;
11c606a6 (kx 2023-04-11 01:18:34 +0300 108) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 109)
11c606a6 (kx 2023-04-11 01:18:34 +0300 110) if( WIFEXITED( status ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 111) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 112) if( WEXITSTATUS (status) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 113) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 114) if( errmsg && size ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 115) (void)snprintf( errmsg, size, "PID %lu: Child returned status %d", (unsigned long)pid, WEXITSTATUS( status ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 116) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 117) return (int) WEXITSTATUS( status );
11c606a6 (kx 2023-04-11 01:18:34 +0300 118) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 119) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 120) else if( WIFSIGNALED( status ) )
11c606a6 (kx 2023-04-11 01:18:34 +0300 121) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 122) if( errmsg && size ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 123) (void)snprintf( errmsg, size, "PID %lu: Child terminated on signal %d", (unsigned long)pid, WTERMSIG( status ) );
11c606a6 (kx 2023-04-11 01:18:34 +0300 124) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 125) return (int) -1;
11c606a6 (kx 2023-04-11 01:18:34 +0300 126) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 127) else
11c606a6 (kx 2023-04-11 01:18:34 +0300 128) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 129) if( errmsg && size ) {
11c606a6 (kx 2023-04-11 01:18:34 +0300 130) (void)snprintf( errmsg, size, "PID %lu: Child terminated on unknown reason", (unsigned long)pid );
11c606a6 (kx 2023-04-11 01:18:34 +0300 131) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 132) return (int) -2;
11c606a6 (kx 2023-04-11 01:18:34 +0300 133) }
11c606a6 (kx 2023-04-11 01:18:34 +0300 134)
11c606a6 (kx 2023-04-11 01:18:34 +0300 135) return 0;
11c606a6 (kx 2023-04-11 01:18:34 +0300 136) }