vshost-util-vserver

Build script and sources for util-vserver.
git clone https://ccx.te2000.cz/git/vshost-util-vserver
Log | Files | Refs

command-exec.c (2147B)


      1 // $Id$    --*- c -*--
      2 
      3 // Copyright (C) 2004 Enrico Scholz <enrico.scholz@informatik.tu-chemnitz.de>
      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; version 2 of the License.
      8 //  
      9 // This program is distributed in the hope that it will be useful,
     10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
     11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     12 // GNU General Public License for more details.
     13 //  
     14 // You should have received a copy of the GNU General Public License
     15 // along with this program; if not, write to the Free Software
     16 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     17 
     18 
     19 #ifdef HAVE_CONFIG_H
     20 #  include <config.h>
     21 #endif
     22 
     23 #include "command.h"
     24 #include "util.h"
     25 
     26 #include <unistd.h>
     27 #include <fcntl.h>
     28 #include <errno.h>
     29 #include <assert.h>
     30 
     31 static inline bool
     32 initPipes(int p[2])
     33 {
     34   return (pipe(p)!=-1 &&
     35 	  fcntl(p[1], F_SETFD, FD_CLOEXEC)!=-1);
     36 }
     37 
     38 bool
     39 Command_exec(struct Command *cmd, bool do_fork)
     40 {
     41   int		p[2];
     42 
     43   if (cmd->params_style_==parVEC)
     44     Vector_zeroEnd(&cmd->params.v);
     45 
     46   if (!do_fork)
     47     cmd->pid = 0;
     48   else if (!initPipes(p) ||
     49 	   (cmd->pid = fork())==-1) {
     50     cmd->err = errno;
     51     return false;
     52   }
     53   
     54   if (cmd->pid==0) {
     55     char const **	argv = { 0 };
     56     
     57     if (do_fork) close(p[0]);
     58 
     59     switch (cmd->params_style_) {
     60       case parVEC	:  argv = cmd->params.v.data; break;
     61       case parDATA	:  argv = cmd->params.d;      break;
     62       default		:  break;
     63     }
     64 
     65     execv(cmd->filename ? cmd->filename : argv[0],
     66 	  reinterpret_cast(char **const)(argv));
     67     cmd->err = errno;
     68     assert(cmd->err != 0);
     69 
     70     if (do_fork) {
     71       TEMP_FAILURE_RETRY(write(p[1], &cmd->err, sizeof(cmd->err)));
     72       _exit(1);	// implicates 'close(p[1])'
     73     }
     74   }
     75   else {
     76     close(p[1]);
     77     if (read(p[0], &cmd->err, sizeof(cmd->err))==0)
     78       cmd->err = 0;
     79     else	// cleanup zombies
     80       while (wait4(cmd->pid, 0,0,0)==-1 &&
     81 	     (errno==EINTR || errno==EAGAIN)) {};
     82     close(p[0]);
     83   }
     84 
     85   return cmd->err==0;
     86 }