execute.c
author viric@llimona
Tue, 27 Mar 2007 23:29:56 +0200
changeset 58 3c492266923e
parent 49 09bb8a5583e9
child 65 dced0efccc19
permissions -rw-r--r--
Preparing v0.2.3
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
49
09bb8a5583e9 Added the license.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
     1
/*
09bb8a5583e9 Added the license.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
     2
    Task Spooler - a task queue system for the unix user
09bb8a5583e9 Added the license.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
     3
    Copyright (C) 2007  LluĂ­s Batlle i Rossell
09bb8a5583e9 Added the license.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
     4
09bb8a5583e9 Added the license.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
     5
    Please find the license in the provided COPYING file.
09bb8a5583e9 Added the license.
lbatlle@npdl268.bpo.hp.com
parents: 44
diff changeset
     6
*/
8
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
     7
#include <unistd.h>
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
     8
#include <stdio.h>
9
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
     9
#include <signal.h>
22
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    10
#include <assert.h>
44
4dcf05746ece Better include files.
viric@llimona
parents: 35
diff changeset
    11
#include <string.h>
19
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    12
#include <sys/types.h>
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    13
#include <sys/wait.h>
44
4dcf05746ece Better include files.
viric@llimona
parents: 35
diff changeset
    14
#include <stdlib.h>
8
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
    15
9
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
    16
#include "msg.h"
8
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
    17
#include "main.h"
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
    18
9
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
    19
static void program_signal();
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
    20
19
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    21
/* Returns errorlevel */
35
83d0da612dc4 Kill the running job works fine.
viric@llimona
parents: 30
diff changeset
    22
static int run_parent(int fd_read_filename, int pid)
8
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
    23
{
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
    24
    int status;
19
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    25
    int errorlevel;
22
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    26
    char *ofname = 0;
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    27
    int namesize;
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    28
    int res;
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    29
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    30
    /* Read the filename */
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    31
    /* This is linked with the write() in this same file, in run_child() */
30
ab88478a7e9b The commandline parameters are centered in a struct.
viric@llimona
parents: 28
diff changeset
    32
    if (command_line.store_output) {
22
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    33
        res = read(fd_read_filename, &namesize, sizeof(namesize));
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    34
        if (res == -1)
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    35
        {
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    36
            perror("read filename");
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    37
            exit(-1);
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    38
        }
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    39
        assert(res == sizeof(namesize));
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    40
        ofname = (char *) malloc(namesize);
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    41
        res = read(fd_read_filename, ofname, namesize);
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    42
        assert(res == namesize);
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    43
    }
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    44
    close(fd_read_filename);
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    45
35
83d0da612dc4 Kill the running job works fine.
viric@llimona
parents: 30
diff changeset
    46
    c_send_runjob_ok(ofname, pid);
22
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    47
    free(ofname);
19
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    48
8
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
    49
    wait(&status);
19
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    50
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    51
    if (WIFEXITED(status))
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    52
    {
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    53
        /* We force the proper cast */
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    54
        signed char tmp;
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    55
        tmp = WEXITSTATUS(status);
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    56
        errorlevel = tmp;
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    57
    } else
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    58
        return -1;
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    59
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    60
    return errorlevel;
44
4dcf05746ece Better include files.
viric@llimona
parents: 35
diff changeset
    61
}
8
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
    62
30
ab88478a7e9b The commandline parameters are centered in a struct.
viric@llimona
parents: 28
diff changeset
    63
static void run_child(const char *command, int fd_send_filename)
8
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
    64
{
9
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
    65
    int p[2];
28
107abb4ec98a Unified socket path, depending on the username and $TMPDIR.
viric@llimona
parents: 22
diff changeset
    66
    char outfname[] = "/tmp/ts-out.XXXXXX";
22
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    67
    int namesize;
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    68
    int outfd;
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    69
30
ab88478a7e9b The commandline parameters are centered in a struct.
viric@llimona
parents: 28
diff changeset
    70
    if (command_line.store_output)
22
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    71
    {
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    72
        int res;
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    73
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    74
        close(1); /* stdout */
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    75
        close(2); /* stderr */
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    76
        /* Prepare the filename */
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    77
        outfd = mkstemp(outfname); /* stdout */
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    78
        dup(outfd); /* stderr */
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    79
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    80
        /* Send the filename */
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    81
        namesize = sizeof(outfname);
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    82
        res = write(fd_send_filename, (char *)&namesize, sizeof(namesize));
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    83
        write(fd_send_filename, outfname, sizeof(outfname));
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    84
    }
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    85
    close(fd_send_filename);
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    86
9
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
    87
    /* Closing input */
18
af4898956964 Now commands of any-length are accepted.
viric@llimona
parents: 9
diff changeset
    88
    pipe(p);
9
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
    89
    close(p[1]); /* closing the write handle */
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
    90
    close(0);
22
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
    91
    dup(p[0]); /* the pipe reading goes to stdin */
9
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
    92
8
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
    93
    execlp("bash", "bash", "-c", command, NULL);
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
    94
}
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
    95
30
ab88478a7e9b The commandline parameters are centered in a struct.
viric@llimona
parents: 28
diff changeset
    96
int run_job(const char *command)
8
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
    97
{
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
    98
    int pid;
19
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
    99
    int errorlevel;
22
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
   100
    int p[2];
8
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
   101
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
   102
9
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   103
    /* For the parent */
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   104
    /*program_signal(); Still not needed*/
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   105
22
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
   106
    /* Prepare the output filename sending */
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
   107
    pipe(p);
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
   108
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
   109
    pid = fork();
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
   110
8
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
   111
    switch(pid)
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
   112
    {
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
   113
        case 0:
9
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   114
            close(server_socket);
22
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
   115
            close(p[0]);
30
ab88478a7e9b The commandline parameters are centered in a struct.
viric@llimona
parents: 28
diff changeset
   116
            run_child(command, p[1]);
8
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
   117
            break;
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
   118
        case -1:
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
   119
            perror("Error in fork");
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
   120
            exit(-1);
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
   121
            ;
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
   122
        default:
22
afdc8410633f Now output can go to filenames.
viric@llimona
parents: 19
diff changeset
   123
            close(p[1]);
35
83d0da612dc4 Kill the running job works fine.
viric@llimona
parents: 30
diff changeset
   124
            errorlevel = run_parent(p[0], pid);
8
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
   125
            break;
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
   126
    }
19
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
   127
5efc347cca8d The finished jobs store the errorlevel, and can be listed.
viric@llimona
parents: 18
diff changeset
   128
    return errorlevel;
8
03339adb7014 Some more code for execution.
viric@llimona
parents:
diff changeset
   129
}
9
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   130
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   131
static void sigchld_handler(int val)
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   132
{
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   133
}
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   134
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   135
static void program_signal()
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   136
{
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   137
  struct sigaction act;
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   138
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   139
  act.sa_handler = sigchld_handler;
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   140
  /* Reset the mask */
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   141
  memset(&act.sa_mask,0,sizeof(act.sa_mask));
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   142
  act.sa_flags = SA_NOCLDSTOP;
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   143
  act.sa_restorer = NULL;
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   144
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   145
  sigaction(SIGCHLD, &act, NULL);
9acd8ae3190c First usable version!
lbatlle@npdl268.bpo.hp.com
parents: 8
diff changeset
   146
}