/*
 * Copyright 1993, 1995 Christopher Seiwald.
 * Copyright 2007 Noel Belcourt.
 *
 * This file is part of Jam - see jam.c for Copyright information.
 */

#include "jam.h"
#include "lists.h"
#include "execcmd.h"
#include "output.h"
#include <errno.h>
#include <signal.h>
#include <stdio.h>
#include <time.h>
#include <unistd.h>  /* needed for vfork(), _exit() prototypes */
#include <sys/resource.h>
#include <sys/times.h>
#include <sys/wait.h>

#if defined(sun) || defined(__sun) || defined(linux)
    #include <wait.h>
#endif

#ifdef USE_EXECUNIX

#include <sys/times.h>

#if defined(__APPLE__)
    #define NO_VFORK
#endif

#ifdef NO_VFORK
    #define vfork() fork()
#endif


/*
 * execunix.c - execute a shell script on UNIX/WinNT/OS2/AmigaOS
 *
 * If $(JAMSHELL) is defined, uses that to formulate execvp()/spawnvp().
 * The default is:
 *
 *  /bin/sh -c %        [ on UNIX/AmigaOS ]
 *  cmd.exe /c %        [ on OS2/WinNT ]
 *
 * Each word must be an individual element in a jam variable value.
 *
 * In $(JAMSHELL), % expands to the command string and ! expands to the slot
 * number (starting at 1) for multiprocess (-j) invocations. If $(JAMSHELL) does
 * not include a %, it is tacked on as the last argument.
 *
 * Do not just set JAMSHELL to /bin/sh or cmd.exe - it will not work!
 *
 * External routines:
 *  exec_cmd() - launch an async command execution.
 *  exec_wait() - wait and drive at most one execution completion.
 *
 * Internal routines:
 *  onintr() - bump intr to note command interruption.
 *
 * 04/08/94 (seiwald) - Coherent/386 support added.
 * 05/04/94 (seiwald) - async multiprocess interface
 * 01/22/95 (seiwald) - $(JAMSHELL) support
 * 06/02/97 (gsar)    - full async multiprocess support for Win32
 */

static clock_t tps = 0;
static struct timeval tv;
static int select_timeout = 0;
static int intr = 0;
static int cmdsrunning = 0;
static struct tms old_time;

#define OUT 0
#define ERR 1

static struct
{
    int     pid;              /* on win32, a real process handle */
    int     fd[2];            /* file descriptors for stdout and stderr */
    FILE   *stream[2];        /* child's stdout (0) and stderr (1) file stream */
    clock_t start_time;       /* start time of child process */
    int     exit_reason;      /* termination status */
    int     action_length;    /* length of action string */
    int     target_length;    /* length of target string */
    char   *action;           /* buffer to hold action and target invoked */
    char   *target;           /* buffer to hold action and target invoked */
    char   *command;          /* buffer to hold command being invoked */
    char   *buffer[2];        /* buffer to hold stdout and stderr, if any */
    void    (*func)( void *closure, int status, timing_info*, char *, char * );
    void   *closure;
    time_t  start_dt;         /* start of command timestamp */
} cmdtab[ MAXJOBS ] = {{0}};

/*
 * onintr() - bump intr to note command interruption
 */

void onintr( int disp )
{
    ++intr;
    printf( "...interrupted\n" );
}


/*
 * exec_cmd() - launch an async command execution.
 */

void exec_cmd
(
    char * string,
    void (*func)( void *closure, int status, timing_info*, char *, char * ),
    void * closure,
    LIST * shell,
    char * action,
    char * target
)
{
    static int initialized = 0;
    int    out[2];
    int    err[2];
    int    slot;
    int    len;
    char * argv[ MAXARGC + 1 ];  /* +1 for NULL */

    /* Find a slot in the running commands table for this one. */
    for ( slot = 0; slot < MAXJOBS; ++slot )
        if ( !cmdtab[ slot ].pid )
            break;

    if ( slot == MAXJOBS )
    {
        printf( "no slots for child!\n" );
        exit( EXITBAD );
    }

    /* Forumulate argv. If shell was defined, be prepared for % and ! subs.
     * Otherwise, use stock /bin/sh on unix or cmd.exe on NT.
     */
    if ( shell )
    {
        int  i;
        char jobno[4];
        int  gotpercent = 0;

        sprintf( jobno, "%d", slot + 1 );

        for ( i = 0; shell && i < MAXARGC; ++i, shell = list_next( shell ) )
        {
            switch ( shell->string[0] )
            {
                case '%': argv[ i ] = string; ++gotpercent; break;
                case '!': argv[ i ] = jobno;                break;
                default : argv[ i ] = shell->string;
            }
            if ( DEBUG_EXECCMD )
                printf( "argv[%d] = '%s'\n", i, argv[ i ] );
        }

        if ( !gotpercent )
        argv[ i++ ] = string;

        argv[ i ] = 0;
    }
    else
    {
        argv[ 0 ] = "/bin/sh";
        argv[ 1 ] = "-c";
        argv[ 2 ] = string;
        argv[ 3 ] = 0;
    }

    /* Increment jobs running. */
    ++cmdsrunning;

    /* Save off actual command string. */
    cmdtab[ slot ].command = BJAM_MALLOC_ATOMIC( strlen( string ) + 1 );
    strcpy( cmdtab[ slot ].command, string );

    /* Initialize only once. */
    if ( !initialized )
    {
        times( &old_time );
        initialized = 1;
    }

    /* Create pipes from child to parent. */
    {
        if ( pipe( out ) < 0 )
            exit( EXITBAD );

        if ( pipe( err ) < 0 )
            exit( EXITBAD );
    }

    /* Start the command */

    cmdtab[ slot ].start_dt = time(0);

    if ( 0 < globs.timeout )
    {
        /*
         * Handle hung processes by manually tracking elapsed time and signal
         * process when time limit expires.
         */
        struct tms buf;
        cmdtab[ slot ].start_time = times( &buf );

        /* Make a global, only do this once. */
        if ( tps == 0 ) tps = sysconf( _SC_CLK_TCK );
    }

    if ( ( cmdtab[ slot ].pid = vfork() ) == 0 )
    {
        int pid = getpid();

        close( out[0] );
        close( err[0] );

        dup2( out[1], STDOUT_FILENO );

        if ( globs.pipe_action == 0 )
            dup2( out[1], STDERR_FILENO );
        else
            dup2( err[1], STDERR_FILENO );

        close( out[1] );
        close( err[1] );

        /* Make this process a process group leader so that when we kill it, all
         * child processes of this process are terminated as well. We use
         * killpg(pid, SIGKILL) to kill the process group leader and all its
         * children.
         */
        if ( 0 < globs.timeout )
        {
            struct rlimit r_limit;
            r_limit.rlim_cur = globs.timeout;
            r_limit.rlim_max = globs.timeout;
            setrlimit( RLIMIT_CPU, &r_limit );
        }
        setpgid( pid,pid );
        execvp( argv[0], argv );
        perror( "execvp" );
        _exit( 127 );
    }
    else if ( cmdtab[ slot ].pid == -1 )
    {
        perror( "vfork" );
        exit( EXITBAD );
    }

    setpgid( cmdtab[ slot ].pid, cmdtab[ slot ].pid );

    /* close write end of pipes */
    close( out[1] );
    close( err[1] );

    /* child writes stdout to out[1], parent reads from out[0] */
    cmdtab[ slot ].fd[ OUT ] = out[0];
    cmdtab[ slot ].stream[ OUT ] = fdopen( cmdtab[ slot ].fd[ OUT ], "rb" );
    if ( cmdtab[ slot ].stream[ OUT ] == NULL )
    {
        perror( "fdopen" );
        exit( EXITBAD );
    }

    /* child writes stderr to err[1], parent reads from err[0] */
    if (globs.pipe_action == 0)
    {
      close(err[0]);
    }
    else
    {
        cmdtab[ slot ].fd[ ERR ] = err[0];
        cmdtab[ slot ].stream[ ERR ] = fdopen( cmdtab[ slot ].fd[ ERR ], "rb" );
        if ( cmdtab[ slot ].stream[ ERR ] == NULL )
        {
            perror( "fdopen" );
            exit( EXITBAD );
        }
    }

    /* Ensure enough room for rule and target name. */
    if ( action && target )
    {
        len = strlen( action ) + 1;
        if ( cmdtab[ slot ].action_length < len )
        {
            BJAM_FREE( cmdtab[ slot ].action );
            cmdtab[ slot ].action = BJAM_MALLOC_ATOMIC( len );
            cmdtab[ slot ].action_length = len;
        }
        strcpy( cmdtab[ slot ].action, action );
        len = strlen( target ) + 1;
        if ( cmdtab[ slot ].target_length < len )
        {
            BJAM_FREE( cmdtab[ slot ].target );
            cmdtab[ slot ].target = BJAM_MALLOC_ATOMIC( len );
            cmdtab[ slot ].target_length = len;
        }
        strcpy( cmdtab[ slot ].target, target );
    }
    else
    {
        BJAM_FREE( cmdtab[ slot ].action );
        BJAM_FREE( cmdtab[ slot ].target );
        cmdtab[ slot ].action = 0;
        cmdtab[ slot ].target = 0;
        cmdtab[ slot ].action_length = 0;
        cmdtab[ slot ].target_length = 0;
    }

    /* Save the operation for exec_wait() to find. */
    cmdtab[ slot ].func = func;
    cmdtab[ slot ].closure = closure;

    /* Wait until we are under the limit of concurrent commands. Do not trust
     * globs.jobs alone.
     */
    while ( ( cmdsrunning >= MAXJOBS ) || ( cmdsrunning >= globs.jobs ) )
        if ( !exec_wait() )
            break;
}


/* Returns 1 if file is closed, 0 if descriptor is still live.
 *
 * i is index into cmdtab
 *
 * s (stream) indexes:
 *  - cmdtab[ i ].stream[ s ]
 *  - cmdtab[ i ].buffer[ s ]
 *  - cmdtab[ i ].fd    [ s ]
 */

int read_descriptor( int i, int s )
{
    int  ret;
    int  len;
    char buffer[BUFSIZ];

    while ( 0 < ( ret = fread( buffer, sizeof(char),  BUFSIZ-1, cmdtab[ i ].stream[ s ] ) ) )
    {
        buffer[ret] = 0;
        if  ( !cmdtab[ i ].buffer[ s ] )
        {
            /* Never been allocated. */
            cmdtab[ i ].buffer[ s ] = (char*)BJAM_MALLOC_ATOMIC( ret + 1 );
            memcpy( cmdtab[ i ].buffer[ s ], buffer, ret + 1 );
        }
        else
        {
            /* Previously allocated. */
            char * tmp = cmdtab[ i ].buffer[ s ];
            len = strlen( tmp );
            cmdtab[ i ].buffer[ s ] = (char*)BJAM_MALLOC_ATOMIC( len + ret + 1 );
            memcpy( cmdtab[ i ].buffer[ s ], tmp, len );
            memcpy( cmdtab[ i ].buffer[ s ] + len, buffer, ret + 1 );
            BJAM_FREE( tmp );
        }
    }

    return feof(cmdtab[ i ].stream[ s ]);
}


void close_streams( int i, int s )
{
    /* Close the stream and pipe descriptor. */
    fclose(cmdtab[ i ].stream[ s ]);
    cmdtab[ i ].stream[ s ] = 0;

    close(cmdtab[ i ].fd[ s ]);
    cmdtab[ i ].fd[ s ] = 0;
}


void populate_file_descriptors( int * fmax, fd_set * fds)
{
    int i, fd_max = 0;
    struct tms buf;
    clock_t current = times( &buf );
    select_timeout = globs.timeout;

    /* Compute max read file descriptor for use in select. */
    FD_ZERO(fds);
    for ( i = 0; i < globs.jobs; ++i )
    {
        if ( 0 < cmdtab[ i ].fd[ OUT ] )
        {
            fd_max = fd_max < cmdtab[ i ].fd[ OUT ] ? cmdtab[ i ].fd[ OUT ] : fd_max;
            FD_SET(cmdtab[ i ].fd[ OUT ], fds);
        }
        if ( globs.pipe_action != 0 )
        {
            if (0 < cmdtab[ i ].fd[ ERR ])
            {
                fd_max = fd_max < cmdtab[ i ].fd[ ERR ] ? cmdtab[ i ].fd[ ERR ] : fd_max;
                FD_SET(cmdtab[ i ].fd[ ERR ], fds);
            }
        }

        if (globs.timeout && cmdtab[ i ].pid) {
            clock_t consumed = (current - cmdtab[ i ].start_time) / tps;
            clock_t process_timesout = globs.timeout - consumed;
            if (0 < process_timesout && process_timesout < select_timeout) {
                select_timeout = process_timesout;
            }
            if ( globs.timeout <= consumed )
            {
                killpg( cmdtab[ i ].pid, SIGKILL );
                cmdtab[ i ].exit_reason = EXIT_TIMEOUT;
            }
        }
    }
    *fmax = fd_max;
}


/*
 * exec_wait() - wait and drive at most one execution completion.
 */

int exec_wait()
{
    int         i;
    int         ret;
    int         fd_max;
    int         pid;
    int         status;
    int         finished;
    int         rstat;
    timing_info time_info;
    fd_set      fds;
    struct tms  new_time;

    /* Handle naive make1() which does not know if commands are running. */
    if ( !cmdsrunning )
        return 0;

    /* Process children that signaled. */
    finished = 0;
    while ( !finished && cmdsrunning )
    {
        /* Compute max read file descriptor for use in select(). */
        populate_file_descriptors( &fd_max, &fds );

        if ( 0 < globs.timeout )
        {
            /* Force select() to timeout so we can terminate expired processes.
             */
            tv.tv_sec = select_timeout;
            tv.tv_usec = 0;

            /* select() will wait until: i/o on a descriptor, a signal, or we
             * time out.
             */
            ret = select( fd_max + 1, &fds, 0, 0, &tv );
        }
        else
        {
            /* select() will wait until i/o on a descriptor or a signal. */
            ret = select( fd_max + 1, &fds, 0, 0, 0 );
        }

        if ( 0 < ret )
        {
            for ( i = 0; i < globs.jobs; ++i )
            {
                int out = 0;
                int err = 0;
                if ( FD_ISSET( cmdtab[ i ].fd[ OUT ], &fds ) )
                    out = read_descriptor( i, OUT );

                if ( ( globs.pipe_action != 0 ) &&
                    ( FD_ISSET( cmdtab[ i ].fd[ ERR ], &fds ) ) )
                    err = read_descriptor( i, ERR );

                /* If feof on either descriptor, then we are done. */
                if ( out || err )
                {
                    /* Close the stream and pipe descriptors. */
                    close_streams( i, OUT );
                    if ( globs.pipe_action != 0 )
                        close_streams( i, ERR );

                    /* Reap the child and release resources. */
                    pid = waitpid( cmdtab[ i ].pid, &status, 0 );

                    if ( pid == cmdtab[ i ].pid )
                    {
                        finished = 1;
                        pid = 0;
                        cmdtab[ i ].pid = 0;

                        /* Set reason for exit if not timed out. */
                        if ( WIFEXITED( status ) )
                        {
                            cmdtab[ i ].exit_reason = 0 == WEXITSTATUS( status )
                                ? EXIT_OK
                                : EXIT_FAIL;
                        }

                        /* Print out the rule and target name. */
                        out_action( cmdtab[ i ].action, cmdtab[ i ].target,
                            cmdtab[ i ].command, cmdtab[ i ].buffer[ OUT ],
                            cmdtab[ i ].buffer[ ERR ], cmdtab[ i ].exit_reason
                        );

                        times( &new_time );

                        time_info.system = (double)( new_time.tms_cstime - old_time.tms_cstime ) / CLOCKS_PER_SEC;
                        time_info.user   = (double)( new_time.tms_cutime - old_time.tms_cutime ) / CLOCKS_PER_SEC;
                        time_info.start  = cmdtab[ i ].start_dt;
                        time_info.end    = time( 0 );

                        old_time = new_time;

                        /* Drive the completion. */
                        --cmdsrunning;

                        if ( intr )
                            rstat = EXEC_CMD_INTR;
                        else if ( status != 0 )
                            rstat = EXEC_CMD_FAIL;
                        else
                            rstat = EXEC_CMD_OK;

                        /* Assume -p0 in effect so only pass buffer[ 0 ]
                         * containing merged output.
                         */
                        (*cmdtab[ i ].func)( cmdtab[ i ].closure, rstat,
                            &time_info, cmdtab[ i ].command,
                            cmdtab[ i ].buffer[ 0 ] );

                        BJAM_FREE( cmdtab[ i ].buffer[ OUT ] );
                        cmdtab[ i ].buffer[ OUT ] = 0;

                        BJAM_FREE( cmdtab[ i ].buffer[ ERR ] );
                        cmdtab[ i ].buffer[ ERR ] = 0;

                        BJAM_FREE( cmdtab[ i ].command );
                        cmdtab[ i ].command = 0;

                        cmdtab[ i ].func = 0;
                        cmdtab[ i ].closure = 0;
                        cmdtab[ i ].start_time = 0;
                    }
                    else
                    {
                        printf( "unknown pid %d with errno = %d\n", pid, errno );
                        exit( EXITBAD );
                    }
                }
            }
        }
    }

    return 1;
}

# endif /* USE_EXECUNIX */
