]> git.tdb.fi Git - builder.git/blob - source/externalaction.cpp
Use package directory as work dir for ExternalActions and make filename arguments...
[builder.git] / source / externalaction.cpp
1 /* $Id$
2
3 This file is part of builder
4 Copyright © 2006-2007 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <sys/wait.h>
9 #include <iostream>
10 #include <msp/path/utils.h>
11 #include "builder.h"
12 #include "externalaction.h"
13
14 using namespace std;
15 using namespace Msp;
16
17 int ExternalAction::check()
18 {
19         if(builder.get_dry_run())
20         {
21                 signal_done.emit();
22                 return 0;
23         }
24
25         if(!pid)
26                 return exit_code;
27
28         int status;
29         if(waitpid(pid, &status, WNOHANG)==pid)
30         {
31                 signal_done.emit();
32                 if(WIFEXITED(status))
33                         exit_code=WEXITSTATUS(status);
34                 else
35                         exit_code=254;
36                 pid=0;
37                 return exit_code;
38         }
39         else
40                 return -1;
41 }
42
43 /**
44 Starts the external program.  Fill in argv before calling this.
45 */
46 void ExternalAction::launch()
47 {
48         if(builder.get_verbose()>=2)
49         {
50                 for(StringList::const_iterator i=argv.begin(); i!=argv.end(); ++i)
51                 {
52                         if(i!=argv.begin())
53                                 cout<<' ';
54                         cout<<*i;
55                 }
56                 cout<<'\n';
57         }
58
59         if(builder.get_dry_run())
60                 pid=-1;
61         else
62         {
63                 pid=fork();
64                 if(pid==0)
65                 {
66                         char *argv_[argv.size()+1];
67
68                         unsigned j=0;
69                         for(StringList::iterator i=argv.begin(); i!=argv.end(); ++i)
70                                 argv_[j++]=strdup(i->c_str());
71                         argv_[j]=0;
72
73                         if(!work_dir.empty())
74                                 chdir(work_dir);
75                         execvp(argv_[0], argv_);
76                         cout<<"Couldn't execute "<<argv.front()<<'\n';
77                         exit(1);
78                 }
79                 else if(pid<0)
80                         pid=0;
81         }
82 }