allow base attribute in configuration file tags
[metaproxy-moved-to-github.git] / src / filter_cgi.cpp
index 3412ca8..dc71907 100644 (file)
@@ -1,5 +1,5 @@
 /* This file is part of Metaproxy.
-   Copyright (C) 2005-2010 Index Data
+   Copyright (C) Index Data
 
 Metaproxy is free software; you can redistribute it and/or modify it under
 the terms of the GNU General Public License as published by the Free
@@ -24,6 +24,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 #include <yaz/log.h>
 
 #include <unistd.h>
+#include <signal.h>
 #include <sys/wait.h>
 #include <sstream>
 
@@ -43,26 +44,40 @@ namespace metaproxy_1 {
         class CGI::Rep {
             friend class CGI;
             std::list<CGI::Exec> exec_map;
+            std::map<pid_t,pid_t> children;
+            boost::mutex m_mutex;
+        public:
+            ~Rep();
         };
     }
 }
 
 yf::CGI::CGI() : m_p(new Rep)
 {
+
+}
+
+yf::CGI::Rep::~Rep()
+{
+    std::map<pid_t,pid_t>::const_iterator it;
+    boost::mutex::scoped_lock lock(m_mutex);
+
+    for (it = children.begin(); it != children.end(); it++)
+        kill(it->second, SIGTERM);
 }
 
 yf::CGI::~CGI()
-{  // must have a destructor because of boost::scoped_ptr
+{
 }
 
 void yf::CGI::process(mp::Package &package) const
 {
     Z_GDU *zgdu_req = package.request().get();
     Z_GDU *zgdu_res = 0;
-    
+
     if (!zgdu_req)
         return;
-    
+
     if (zgdu_req->which != Z_GDU_HTTP_Request)
     {
         package.move();
@@ -90,14 +105,11 @@ void yf::CGI::process(mp::Package &package) const
             int r;
             pid_t pid;
             int status;
-            int fd;
-            
+
             pid = ::fork();
             switch (pid)
             {
             case 0: /* child */
-                for (fd = 3; fd <= 1023; fd++)
-                    close(fd);
                 setenv("PATH_INFO", path_info.c_str(), 1);
                 setenv("QUERY_STRING", query_string.c_str(), 1);
                 r = execl(it->program.c_str(), it->program.c_str(), (char *) 0);
@@ -111,8 +123,18 @@ void yf::CGI::process(mp::Package &package) const
                 package.response() = zgdu_res;
                 break;
             default: /* parent */
+                if (pid)
+                {
+                    boost::mutex::scoped_lock lock(m_p->m_mutex);
+                    m_p->children[pid] = pid;
+                }
                 waitpid(pid, &status, 0);
 
+                if (pid)
+                {
+                    boost::mutex::scoped_lock lock(m_p->m_mutex);
+                    m_p->children.erase(pid);
+                }
                 zgdu_res = odr.create_HTTP_Response(
                     package.session(), zgdu_req->u.HTTP_Request, 200);
                 package.response() = zgdu_res;
@@ -124,7 +146,7 @@ void yf::CGI::process(mp::Package &package) const
     package.move();
 }
 
-void yf::CGI::configure(const xmlNode *ptr, bool test_only)
+void yf::CGI::configure(const xmlNode *ptr, bool test_only, const char *path)
 {
     for (ptr = ptr->children; ptr; ptr = ptr->next)
     {
@@ -143,7 +165,7 @@ void yf::CGI::configure(const xmlNode *ptr, bool test_only)
                     exec.program = mp::xml::get_text(attr->children);
                 else
                     throw mp::filter::FilterException
-                        ("Bad attribute " 
+                        ("Bad attribute "
                          + std::string((const char *) attr->name)
                          + " in cgi section");
             }
@@ -151,7 +173,7 @@ void yf::CGI::configure(const xmlNode *ptr, bool test_only)
         }
         else
         {
-            throw mp::filter::FilterException("Bad element " 
+            throw mp::filter::FilterException("Bad element "
                                                + std::string((const char *)
                                                              ptr->name));
         }