Include program counter on action limit notification log
[gnash.git] / cygnal / proc.cpp
blobc102d46c0dd9549f2b44927c54fa6372c1832f97
1 //
2 // Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 Free Software
3 // Foundation, Inc
4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 3 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU General Public License for more details.
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
17 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 #include <sys/types.h>
21 #include <sys/stat.h>
22 #include <cstdio>
23 #include <unistd.h>
24 #include <fcntl.h>
25 #include <string>
26 #include <cstring>
27 #include <csignal>
28 #include <iostream>
29 #include <cstdlib>
31 #include "log.h"
32 #include "crc.h"
33 #include "proc.h"
34 #include "network.h"
36 using namespace std;
37 using namespace gnash;
39 namespace cygnal
42 LogFile& dbglogfile = LogFile::getDefaultInstance();
43 static CRcInitFile& crcfile = CRcInitFile::getDefaultInstance();
45 Proc::Proc (void)
47 // GNASH_REPORT_FUNCTION;
50 Proc::~Proc (void)
52 // GNASH_REPORT_FUNCTION;
55 bool
56 Proc::startCGI(void)
58 // GNASH_REPORT_FUNCTION;
59 log_unimpl("%s", __PRETTY_FUNCTION__);
60 return false;
63 Proc&
64 Proc::getDefaultInstance()
66 // GNASH_REPORT_FUNCTION;
67 static Proc c;
68 return c;
72 bool
73 Proc::startCGI(const string &filespec, boost::uint16_t port)
75 // GNASH_REPORT_FUNCTION;
76 return startCGI(filespec, false, port);
79 bool
80 Proc::startCGI(const string &filespec)
82 // GNASH_REPORT_FUNCTION;
83 return startCGI(filespec, false, 0);
86 bool
87 Proc::startCGI(const string &filespec, bool outflag)
90 return startCGI(filespec, outflag, 0);
93 bool
94 Proc::startCGI(const string &filespec, bool outflag, boost::uint16_t port)
96 // GNASH_REPORT_FUNCTION;
97 struct stat procstats;
98 pid_t childpid;
99 char *cmd_line[20];
101 _output[filespec] = outflag;
103 string path;
104 if (crcfile.getCgiRoot().size() > 0) {
105 path = crcfile.getCgiRoot().c_str();
106 log_debug (_("Document Root for CGI files is: %s"), path);
107 } else {
108 // Yes, I know this is a hack.
109 path = "/var/www/html/cygnal/cgi-bin";
111 // string path = filespec;
112 path += filespec;
114 // simple debug junk
115 log_debug("Starting \"%s\"", path);
117 // See if the file actually exists, otherwise we can't spawn it
118 if (stat(path.c_str(), &procstats) == -1) {
119 log_error("Invalid filespec for CGI: \"%s\"", path);
120 // perror(filespec.c_str());
121 return (false);
124 // setup a command line. By default, argv[0] is the name of the process
125 cmd_line[0] = new char(filespec.size()+1);
126 strcpy(cmd_line[0], filespec.c_str());
128 // If the parent has verbosity on, chances are the child should too.
129 // if (dbglogfile.getVerbosity() > 0) {
130 cmd_line[1] = new char(3);
131 strcpy(cmd_line[1], "-n");
132 cmd_line[2] = new char(4);
133 strcpy(cmd_line[2], "-vv");
134 cmd_line[3] = 0;
135 // }
137 // When running multiple cgis, we prefer to specify the port it's using.
138 if (port > 0) {
139 cmd_line[3] = new char(3);
140 strcpy(cmd_line[3], "-p");
141 cmd_line[4] = new char(10);
142 sprintf(cmd_line[4], "%d", port);
143 cmd_line[5] = 0;
147 // fork ourselves silly
148 childpid = fork();
150 // boost::mutex::scoped_lock lock(_mutex);
152 // childpid is a positive integer, if we are the parent, and fork() worked
153 if (childpid > 0) {
154 _pids[filespec] = childpid;
155 return (true);
158 // childpid is -1, if the fork failed, so print out an error message
159 if (childpid == -1) {
160 // fork() failed
161 perror(filespec.c_str());
162 return (false);
165 // If we are the child, exec the new process, then go away
166 if (childpid == 0) {
167 // Turn off all output, if requested
168 if (outflag == false) {
169 close(1);
170 open("/dev/null", O_WRONLY);
171 close(2);
172 open("/dev/null", O_WRONLY);
174 // Start the desired executable
175 execv(path.c_str(), cmd_line);
176 perror(path.c_str());
177 exit(EXIT_SUCCESS);
180 return (true);
184 Proc::findCGI(const string &filespec)
186 // GNASH_REPORT_FUNCTION;
187 log_debug("Finding \"%s\"", filespec);
188 boost::mutex::scoped_lock lock(_mutex);
190 return _pids[filespec];
193 bool
194 Proc::stopCGI(void)
196 // GNASH_REPORT_FUNCTION;
197 log_unimpl("%s", __PRETTY_FUNCTION__);
198 boost::mutex::scoped_lock lock(_mutex);
200 return false;
203 bool
204 Proc::stopCGI(const string &filespec)
206 // GNASH_REPORT_FUNCTION;
207 log_debug("Stopping \"%s\"", filespec);
209 boost::mutex::scoped_lock lock(_mutex);
210 pid_t pid = _pids[filespec];
212 if (kill (pid, SIGQUIT) == -1) {
213 return (false);
214 } else {
215 return (true);
219 bool
220 Proc::setOutput(const string &filespec, bool outflag)
222 // GNASH_REPORT_FUNCTION;
223 boost::mutex::scoped_lock lock(_mutex);
224 _output[filespec] = outflag;
226 return (true);
229 bool
230 Proc::getOutput(const string &filespec)
232 // GNASH_REPORT_FUNCTION;
233 boost::mutex::scoped_lock lock(_mutex);
235 return _output[filespec];
238 bool
239 Proc::connectCGI (const string &host, boost::uint16_t port)
241 // GNASH_REPORT_FUNCTION;
242 return createClient(host, port);
246 } // end of cygnal namespace