~ubuntu-branches/ubuntu/vivid/cctools/vivid

« back to all changes in this revision

Viewing changes to ftsh/src/timed_exec.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Hanke
  • Date: 2011-05-07 09:05:00 UTC
  • Revision ID: james.westby@ubuntu.com-20110507090500-lqpmdtwndor6e7os
Tags: upstream-3.3.2
ImportĀ upstreamĀ versionĀ 3.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
Copyright (C) 2003-2004 Douglas Thain and the University of Wisconsin
 
3
Copyright (C) 2005- The University of Notre Dame
 
4
This software is distributed under the GNU General Public License.
 
5
See the file COPYING for details.
 
6
*/
 
7
 
 
8
#include "timed_exec.h"
 
9
#include "ftsh_error.h"
 
10
#include "stringtools.h"
 
11
#include "full_io.h"
 
12
#include "multi_fork.h"
 
13
 
 
14
#include <stdlib.h>
 
15
#include <stdio.h>
 
16
#include <unistd.h>
 
17
#include <signal.h>
 
18
#include <sys/wait.h>
 
19
#include <time.h>
 
20
#include <stdio.h>
 
21
#include <errno.h>
 
22
#include <string.h>
 
23
#include <fcntl.h>
 
24
 
 
25
timed_exec_t timed_exec( int line, const char *path, char **argv, int fds[3], pid_t *pid, int *status, time_t stoptime )
 
26
{
 
27
        int fresult;
 
28
        int pfds[2];
 
29
        int child_errno;
 
30
        int actual;
 
31
        struct multi_fork_status s;
 
32
 
 
33
        actual = pipe(pfds);
 
34
        if(actual!=0) return TIMED_EXEC_NOEXEC;
 
35
 
 
36
        fresult = multi_fork(1,&s,stoptime,line);
 
37
        if(fresult>=0) {
 
38
                /* Move our standard I/O streams into the expected places. */
 
39
                /* It seems that cygwin doesn't like dup2 on the same fd. */
 
40
 
 
41
                int i, maxfd;
 
42
 
 
43
                for( i=0; i<=2; i++ ) {
 
44
                        if( fds[i]!=i ) {
 
45
                                if( dup2(fds[i],i) != i ) {
 
46
                                        ftsh_error(FTSH_ERROR_PROCESS,line,"failure to dup2(%d,%d): %s\n",fds[i],i,strerror(errno));
 
47
                                        goto done;
 
48
                                }
 
49
                        }
 
50
                }
 
51
 
 
52
                /* Close all of the file descriptors that we don't need. */
 
53
 
 
54
                maxfd = sysconf( _SC_OPEN_MAX );
 
55
                if(maxfd<=0) maxfd = 255;
 
56
                for(i=3;i<maxfd;i++) {
 
57
                        if(i==pfds[1]) continue;
 
58
                        close(i);
 
59
                }
 
60
 
 
61
                /* Set the pipe to automatically close after exec. */
 
62
 
 
63
                if( fcntl(pfds[1],F_SETFL,FD_CLOEXEC)==0 ) {
 
64
                        setsid();
 
65
                        execvp(path,argv);
 
66
                }
 
67
 
 
68
                /*
 
69
                If anything goes wrong, write the errno to the pipe,
 
70
                where the parent process can collect and print it.
 
71
                */
 
72
 
 
73
                done:
 
74
                child_errno = errno;
 
75
                full_write(pfds[1],&child_errno,sizeof(child_errno));
 
76
                _exit(1);
 
77
 
 
78
        } else {
 
79
 
 
80
                /*
 
81
                Now clear the pipe.  If it contains an int, then the process
 
82
                forked, but was unable to exec.  Set the reason appropriately.
 
83
                Otherwise, live with what we have.
 
84
                */
 
85
 
 
86
                close(pfds[1]);
 
87
                actual = full_read(pfds[0],&child_errno,sizeof(int));
 
88
                close(pfds[0]);
 
89
        
 
90
                *status = s.status;
 
91
                *pid = s.pid;
 
92
 
 
93
                if(actual==sizeof(int)) {
 
94
                        return TIMED_EXEC_NOEXEC;
 
95
                } else if(fresult==MULTI_FORK_SUCCESS) {
 
96
                        return TIMED_EXEC_SUCCESS;
 
97
                } else if(fresult==MULTI_FORK_TIMEOUT) {
 
98
                        return TIMED_EXEC_TIMEOUT;
 
99
                } else {
 
100
                        return TIMED_EXEC_FAILURE;
 
101
                }
 
102
        }
 
103
}
 
104
 
 
105