Header And Logo

PostgreSQL
| The world's most advanced open source database.

Functions

system.c File Reference

#include <AvailabilityMacros.h>
#include <sys/wait.h>
#include <signal.h>
#include <unistd.h>
#include <paths.h>
#include <errno.h>
Include dependency graph for system.c:

Go to the source code of this file.

Functions

int system (const char *command)

Function Documentation

int system ( const char *  command  ) 

Definition at line 52 of file system.c.

References EINTR, NULL, sigaddset, SIGCHLD, and SIGQUIT.

Referenced by do_init(), do_shell(), editFile(), exec_prog(), ExecuteRecoveryCommand(), pgarch_archiveXlog(), psql_command(), regression_main(), RestoreArchivedFile(), RestoreWALFileForRecovery(), run_diff(), runPgDump(), runShellCommand(), start_postmaster(), stop_postmaster(), test_config_settings(), and yearistype().

{
    pid_t       pid;
    int         pstat;
    struct sigaction ign,
                intact,
                quitact;
    sigset_t    newsigblock,
                oldsigblock;

    if (!command)               /* just checking... */
        return (1);

    /*
     * Ignore SIGINT and SIGQUIT, block SIGCHLD. Remember to save existing
     * signal dispositions.
     */
    ign.sa_handler = SIG_IGN;
    (void) sigemptyset(&ign.sa_mask);
    ign.sa_flags = 0;
    (void) sigaction(SIGINT, &ign, &intact);
    (void) sigaction(SIGQUIT, &ign, &quitact);
    (void) sigemptyset(&newsigblock);
    (void) sigaddset(&newsigblock, SIGCHLD);
    (void) sigprocmask(SIG_BLOCK, &newsigblock, &oldsigblock);
    switch (pid = fork())
    {
        case -1:                /* error */
            break;
        case 0:         /* child */

            /*
             * Restore original signal dispositions and exec the command.
             */
            (void) sigaction(SIGINT, &intact, NULL);
            (void) sigaction(SIGQUIT, &quitact, NULL);
            (void) sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
            execl(_PATH_BSHELL, "sh", "-c", command, (char *) NULL);
            _exit(127);
        default:                /* parent */
            do
            {
                pid = wait4(pid, &pstat, 0, (struct rusage *) 0);
            } while (pid == -1 && errno == EINTR);
            break;
    }
    (void) sigaction(SIGINT, &intact, NULL);
    (void) sigaction(SIGQUIT, &quitact, NULL);
    (void) sigprocmask(SIG_SETMASK, &oldsigblock, NULL);
    return (pid == -1 ? -1 : pstat);
}