bfc1508d (kx 2023-03-24 03:55:33 +0300 1)
bfc1508d (kx 2023-03-24 03:55:33 +0300 2) #ifdef HAVE_CONFIG_H
bfc1508d (kx 2023-03-24 03:55:33 +0300 3) #include <config.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300 4) #endif
bfc1508d (kx 2023-03-24 03:55:33 +0300 5)
bfc1508d (kx 2023-03-24 03:55:33 +0300 6) #include <stdlib.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300 7) #include <stdio.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300 8) #include <string.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300 9) #include <errno.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300 10) #include <error.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300 11) #include <sys/stat.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300 12) #include <sys/wait.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300 13) #include <stdarg.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300 14) #include <unistd.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300 15)
bfc1508d (kx 2023-03-24 03:55:33 +0300 16) #include <defs.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300 17)
bfc1508d (kx 2023-03-24 03:55:33 +0300 18) #include <strbuf.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300 19) #include <system.h>
bfc1508d (kx 2023-03-24 03:55:33 +0300 20)
bfc1508d (kx 2023-03-24 03:55:33 +0300 21)
bfc1508d (kx 2023-03-24 03:55:33 +0300 22) #define SYSTEM_ERRMSG_SIZE 4096
bfc1508d (kx 2023-03-24 03:55:33 +0300 23)
bfc1508d (kx 2023-03-24 03:55:33 +0300 24) void system_error( const char *fmt, ... )
bfc1508d (kx 2023-03-24 03:55:33 +0300 25) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 26) va_list arg_ptr;
bfc1508d (kx 2023-03-24 03:55:33 +0300 27) char buf[SYSTEM_ERRMSG_SIZE];
bfc1508d (kx 2023-03-24 03:55:33 +0300 28) char msg[SYSTEM_ERRMSG_SIZE];
bfc1508d (kx 2023-03-24 03:55:33 +0300 29) char *format = "%s: %s\n";
bfc1508d (kx 2023-03-24 03:55:33 +0300 30)
bfc1508d (kx 2023-03-24 03:55:33 +0300 31) va_start( arg_ptr, fmt );
bfc1508d (kx 2023-03-24 03:55:33 +0300 32)
bfc1508d (kx 2023-03-24 03:55:33 +0300 33) vsnprintf( msg, SYSTEM_ERRMSG_SIZE, (const void *)fmt, arg_ptr );
bfc1508d (kx 2023-03-24 03:55:33 +0300 34)
bfc1508d (kx 2023-03-24 03:55:33 +0300 35) va_end( arg_ptr ); /* Reset variable arguments. */
bfc1508d (kx 2023-03-24 03:55:33 +0300 36)
bfc1508d (kx 2023-03-24 03:55:33 +0300 37) snprintf( buf, SYSTEM_ERRMSG_SIZE, format, "system", msg );
bfc1508d (kx 2023-03-24 03:55:33 +0300 38)
bfc1508d (kx 2023-03-24 03:55:33 +0300 39) (void)write( STDERR_FILENO, buf, strlen( buf ) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 40)
bfc1508d (kx 2023-03-24 03:55:33 +0300 41) exit( 1 );
bfc1508d (kx 2023-03-24 03:55:33 +0300 42) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 43)
bfc1508d (kx 2023-03-24 03:55:33 +0300 44) system_errfunc system_fatal = system_error;
bfc1508d (kx 2023-03-24 03:55:33 +0300 45)
bfc1508d (kx 2023-03-24 03:55:33 +0300 46)
bfc1508d (kx 2023-03-24 03:55:33 +0300 47) static void xexec( const char *cmd )
bfc1508d (kx 2023-03-24 03:55:33 +0300 48) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 49) char *argv[4];
bfc1508d (kx 2023-03-24 03:55:33 +0300 50) const char *shell = getenv ("SHELL");
bfc1508d (kx 2023-03-24 03:55:33 +0300 51)
bfc1508d (kx 2023-03-24 03:55:33 +0300 52) if( !shell ) shell = "/bin/sh";
bfc1508d (kx 2023-03-24 03:55:33 +0300 53)
bfc1508d (kx 2023-03-24 03:55:33 +0300 54) argv[0] = (char *) shell;
bfc1508d (kx 2023-03-24 03:55:33 +0300 55) argv[1] = (char *) "-c";
bfc1508d (kx 2023-03-24 03:55:33 +0300 56) argv[2] = (char *) cmd;
bfc1508d (kx 2023-03-24 03:55:33 +0300 57) argv[3] = NULL;
bfc1508d (kx 2023-03-24 03:55:33 +0300 58)
bfc1508d (kx 2023-03-24 03:55:33 +0300 59) execv( shell, argv );
bfc1508d (kx 2023-03-24 03:55:33 +0300 60)
bfc1508d (kx 2023-03-24 03:55:33 +0300 61) /******************************************
bfc1508d (kx 2023-03-24 03:55:33 +0300 62) xexec() is called by child process, and
bfc1508d (kx 2023-03-24 03:55:33 +0300 63) here child process faced to FATAL error:
bfc1508d (kx 2023-03-24 03:55:33 +0300 64) */
bfc1508d (kx 2023-03-24 03:55:33 +0300 65) system_fatal( "Cannot exec '%s'\n", cmd );
bfc1508d (kx 2023-03-24 03:55:33 +0300 66) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 67)
bfc1508d (kx 2023-03-24 03:55:33 +0300 68) static pid_t xfork( void )
bfc1508d (kx 2023-03-24 03:55:33 +0300 69) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 70) pid_t p = fork();
bfc1508d (kx 2023-03-24 03:55:33 +0300 71)
bfc1508d (kx 2023-03-24 03:55:33 +0300 72) if( p == (pid_t) -1 )
bfc1508d (kx 2023-03-24 03:55:33 +0300 73) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 74) system_fatal( "Cannot %s: %s\n", "fork()", strerror( errno ) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 75) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 76)
bfc1508d (kx 2023-03-24 03:55:33 +0300 77) return p;
bfc1508d (kx 2023-03-24 03:55:33 +0300 78) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 79)
bfc1508d (kx 2023-03-24 03:55:33 +0300 80) pid_t sys_exec_command( struct strbuf *sb, const char *cmd )
bfc1508d (kx 2023-03-24 03:55:33 +0300 81) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 82) int pipe_fh[2];
bfc1508d (kx 2023-03-24 03:55:33 +0300 83)
bfc1508d (kx 2023-03-24 03:55:33 +0300 84) pid_t pid = -1;
bfc1508d (kx 2023-03-24 03:55:33 +0300 85)
bfc1508d (kx 2023-03-24 03:55:33 +0300 86) if( sb )
bfc1508d (kx 2023-03-24 03:55:33 +0300 87) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 88) if( pipe(pipe_fh ) == -1 )
bfc1508d (kx 2023-03-24 03:55:33 +0300 89) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 90) system_fatal( "Cannot create pipe: %s\n", strerror( errno ) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 91) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 92) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 93)
bfc1508d (kx 2023-03-24 03:55:33 +0300 94) pid = xfork();
bfc1508d (kx 2023-03-24 03:55:33 +0300 95)
bfc1508d (kx 2023-03-24 03:55:33 +0300 96) if( pid != 0 )
bfc1508d (kx 2023-03-24 03:55:33 +0300 97) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 98) if( sb )
bfc1508d (kx 2023-03-24 03:55:33 +0300 99) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 100) ssize_t ret;
bfc1508d (kx 2023-03-24 03:55:33 +0300 101)
bfc1508d (kx 2023-03-24 03:55:33 +0300 102) close(pipe_fh[1]);
bfc1508d (kx 2023-03-24 03:55:33 +0300 103) ret = strbuf_read( sb, pipe_fh[0], 1024 );
bfc1508d (kx 2023-03-24 03:55:33 +0300 104) if( ret < 0 )
bfc1508d (kx 2023-03-24 03:55:33 +0300 105) system_fatal( "Cannot read pipe: %s\n", strerror( errno ) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 106) close(pipe_fh[0]);
bfc1508d (kx 2023-03-24 03:55:33 +0300 107) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 108)
bfc1508d (kx 2023-03-24 03:55:33 +0300 109) return pid;
bfc1508d (kx 2023-03-24 03:55:33 +0300 110) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 111)
bfc1508d (kx 2023-03-24 03:55:33 +0300 112) if( sb )
bfc1508d (kx 2023-03-24 03:55:33 +0300 113) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 114) dup2(pipe_fh[1], STDOUT_FILENO);
bfc1508d (kx 2023-03-24 03:55:33 +0300 115) close(pipe_fh[1]);
bfc1508d (kx 2023-03-24 03:55:33 +0300 116) close(pipe_fh[0]);
bfc1508d (kx 2023-03-24 03:55:33 +0300 117) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 118)
bfc1508d (kx 2023-03-24 03:55:33 +0300 119) xexec( cmd );
bfc1508d (kx 2023-03-24 03:55:33 +0300 120) return pid; /* only to avoid compilaton warning */
bfc1508d (kx 2023-03-24 03:55:33 +0300 121) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 122)
bfc1508d (kx 2023-03-24 03:55:33 +0300 123) /*****************************************************************
bfc1508d (kx 2023-03-24 03:55:33 +0300 124) sys_wait_command() - Wait for pid.
bfc1508d (kx 2023-03-24 03:55:33 +0300 125)
bfc1508d (kx 2023-03-24 03:55:33 +0300 126) Return values:
bfc1508d (kx 2023-03-24 03:55:33 +0300 127) -------------
bfc1508d (kx 2023-03-24 03:55:33 +0300 128) 0 - SUCCESS
bfc1508d (kx 2023-03-24 03:55:33 +0300 129) >=1 - status returned by child process
bfc1508d (kx 2023-03-24 03:55:33 +0300 130) -1 - Child terminated on signal
bfc1508d (kx 2023-03-24 03:55:33 +0300 131) -2 - Child terminated on unknown reason
bfc1508d (kx 2023-03-24 03:55:33 +0300 132) -3 - Cannot waitpid: waitpid() retusrs -1
bfc1508d (kx 2023-03-24 03:55:33 +0300 133)
bfc1508d (kx 2023-03-24 03:55:33 +0300 134) Error message with SIZE length saved into *ERRMSG buffer.
bfc1508d (kx 2023-03-24 03:55:33 +0300 135) *****************************************************************/
bfc1508d (kx 2023-03-24 03:55:33 +0300 136) int sys_wait_command( pid_t pid, struct strbuf *errmsg )
bfc1508d (kx 2023-03-24 03:55:33 +0300 137) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 138) int status;
bfc1508d (kx 2023-03-24 03:55:33 +0300 139)
bfc1508d (kx 2023-03-24 03:55:33 +0300 140) if( pid < 0 ) return (pid_t) -1;
bfc1508d (kx 2023-03-24 03:55:33 +0300 141)
bfc1508d (kx 2023-03-24 03:55:33 +0300 142) while( waitpid( pid, &status, 0 ) == -1 )
bfc1508d (kx 2023-03-24 03:55:33 +0300 143) if( errno != EINTR )
bfc1508d (kx 2023-03-24 03:55:33 +0300 144) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 145) if( errmsg ) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 146) strbuf_addf( errmsg, "PID %lu: Cannot %s", (unsigned long)pid, "waitpid" );
bfc1508d (kx 2023-03-24 03:55:33 +0300 147) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 148) return (int) -3;
bfc1508d (kx 2023-03-24 03:55:33 +0300 149) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 150)
bfc1508d (kx 2023-03-24 03:55:33 +0300 151) if( WIFEXITED( status ) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 152) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 153) if( WEXITSTATUS (status) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 154) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 155) if( errmsg ) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 156) strbuf_addf( errmsg, "PID %lu: Child returned status %d", (unsigned long)pid, WEXITSTATUS( status ) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 157) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 158) return (int) WEXITSTATUS( status );
bfc1508d (kx 2023-03-24 03:55:33 +0300 159) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 160) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 161) else if( WIFSIGNALED( status ) )
bfc1508d (kx 2023-03-24 03:55:33 +0300 162) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 163) if( errmsg ) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 164) strbuf_addf( errmsg, "PID %lu: Child terminated on signal %d", (unsigned long)pid, WTERMSIG( status ) );
bfc1508d (kx 2023-03-24 03:55:33 +0300 165) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 166) return (int) -1;
bfc1508d (kx 2023-03-24 03:55:33 +0300 167) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 168) else
bfc1508d (kx 2023-03-24 03:55:33 +0300 169) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 170) if( errmsg ) {
bfc1508d (kx 2023-03-24 03:55:33 +0300 171) strbuf_addf( errmsg, "PID %lu: Child terminated on unknown reason", (unsigned long)pid );
bfc1508d (kx 2023-03-24 03:55:33 +0300 172) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 173) return (int) -2;
bfc1508d (kx 2023-03-24 03:55:33 +0300 174) }
bfc1508d (kx 2023-03-24 03:55:33 +0300 175)
bfc1508d (kx 2023-03-24 03:55:33 +0300 176) return 0;
bfc1508d (kx 2023-03-24 03:55:33 +0300 177) }