vshost-util-vserver

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

vkill.c (5346B)


      1 // $Id$    --*- c -*--
      2 
      3 // Copyright (C) 2003 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 "vserver.h"
     24 #include "util.h"
     25 
     26 #include "lib/virtual.h"
     27 
     28 #include <getopt.h>
     29 #include <signal.h>
     30 #include <stdlib.h>
     31 #include <errno.h>
     32 #include <stdio.h>
     33 #include <string.h>
     34 #include <unistd.h>
     35 #include <sys/types.h>
     36 #include <sys/resource.h>
     37 #include <sys/wait.h>
     38 
     39 #define ENSC_WRAPPERS_VSERVER	1
     40 #define ENSC_WRAPPERS_UNISTD	1
     41 #include <wrappers.h>
     42 
     43 #define CMD_HELP	0x8000
     44 #define CMD_VERSION	0x8001
     45 
     46 int		wrapper_exit_code = 1;
     47 
     48 static struct option const
     49 CMDLINE_OPTIONS[] = {
     50   { "help",     no_argument,        0, CMD_HELP },
     51   { "version",  no_argument,        0, CMD_VERSION },
     52   { "xid",      required_argument,  0, 'c' },
     53   { 0,0,0,0 }
     54 };
     55 
     56 struct Arguments
     57 {
     58     xid_t		xid;
     59     int			sig;
     60 };
     61 
     62 static char const * const SIGNALS[] = {
     63   // 0      1      2          3       4       5       6       7
     64   "UNUSED", "HUP", "INT",     "QUIT", "ILL",  "TRAP", "ABRT", "UNUSED",
     65   "FPE",    "KILL", "USR1",   "SEGV", "USR2", "PIPE", "ALRM", "TERM",
     66   "STKFLT", "CHLD", "CONT",   "STOP", "TSTP", "TTIN", "TTOU", "IO",
     67   "XCPU",   "XFSZ", "VTALRM", "PROF", "WINCH",
     68   0,
     69 };
     70 
     71 static void
     72 showHelp(int fd, char const *cmd, int res)
     73 {
     74   WRITE_MSG(fd, "Usage:  ");
     75   WRITE_STR(fd, cmd);
     76   WRITE_MSG(fd,
     77 	    " [--xid|-c <xid>] [-s <signal>] [--] <pid>*\n"
     78 	    "Please report bugs to " PACKAGE_BUGREPORT "\n");
     79   exit(res);
     80 }
     81 
     82 static void
     83 showVersion()
     84 {
     85   WRITE_MSG(1,
     86 	    "vkill " VERSION " -- sends signals to processes within other contexts\n"
     87 	    "This program is part of " PACKAGE_STRING "\n\n"
     88 	    "Copyright (C) 2003 Enrico Scholz\n"
     89 	    VERSION_COPYRIGHT_DISCLAIMER);
     90   exit(0);
     91 }
     92 
     93 static int
     94 str2sig(char const *str)
     95 {
     96   char	*errptr;
     97   int	res = strtol(str, &errptr, 10);
     98   
     99   if (*errptr!='\0') res=-1;
    100   if (res==-1 && strncmp(str,"SIG",3)==0) str+=3;
    101   if (res==-1) {
    102     char const * const	*ptr = SIGNALS;
    103     for (;*ptr!=0; ++ptr) {
    104       if (strcmp(*ptr,str)!=0) continue;
    105       res = ptr-SIGNALS;
    106       break;
    107     }
    108   }
    109 
    110   return res;
    111 }
    112 
    113 #if defined(VC_ENABLE_API_LEGACY)
    114 inline static ALWAYSINLINE int
    115 kill_wrapper_legacy(xid_t UNUSED xid, char const *proc, int UNUSED sig)
    116 {
    117   pid_t		pid;
    118 
    119   signal(SIGCHLD, SIG_DFL);
    120   pid = Efork();
    121 
    122   if (pid>0) {
    123     int		status;
    124     int		res;
    125     while ((res=wait4(pid, &status, 0,0))==-1 &&
    126 	   (errno==EAGAIN || errno==EINTR)) {}
    127 
    128     return (res==0 && WIFEXITED(status) && WEXITSTATUS(status)) ? 0 : 1;
    129   }
    130 
    131   execl(LEGACYDIR "/vkill", "legacy/vkill", proc, (void *)(0));
    132   perror("vkill: execl()");
    133   exit(1);
    134 }
    135 #endif
    136 
    137 inline static int
    138 kill_wrapper(xid_t xid, char const *pid_s, int sig)
    139 {
    140   pid_t	pid;
    141   long	tmp;
    142 
    143   if (!isNumber(pid_s, &tmp, true)) {
    144     WRITE_MSG(2, "vkill: '");
    145     WRITE_STR(2, pid_s);
    146     WRITE_MSG(2, "' is not a number\n");
    147   }
    148   pid = (pid_t) tmp;
    149 
    150   if (xid==VC_NOCTX)
    151     xid = vc_get_task_xid(pid);
    152   if (vc_ctx_kill(xid,pid,sig)==-1) {
    153 #if defined(VC_ENABLE_API_LEGACY)
    154     int		err = errno;
    155     if (vc_get_version(VC_CAT_COMPAT)==-1)
    156       return kill_wrapper_legacy(xid, pid_s, sig);
    157     else {
    158       errno = err;
    159 #else
    160     {
    161 #endif
    162       perror("vkill: vc_ctx_kill()");
    163       return 1;
    164     }
    165   }
    166   return 0;
    167 }
    168 
    169 
    170 int main(int argc, char *argv[])
    171 {
    172   int			fail = 0;
    173   struct Arguments	args = {
    174     .xid = VC_NOCTX,
    175     .sig = SIGTERM,
    176   };
    177   
    178   while (1) {
    179     int		c = getopt_long(argc, argv, "c:s:", CMDLINE_OPTIONS, 0);
    180     if (c==-1) break;
    181 
    182     switch (c) {
    183       case CMD_HELP	:  showHelp(1, argv[0], 0);
    184       case CMD_VERSION	:  showVersion();
    185       case 'c'		:  args.xid = Evc_xidopt2xid(optarg,true); break;
    186       case 's'		:  args.sig = str2sig(optarg);             break;
    187       default		:
    188 	WRITE_MSG(2, "Try '");
    189 	WRITE_STR(2, argv[0]);
    190 	WRITE_MSG(2, " --help' for more information.\n");
    191 	return EXIT_FAILURE;
    192 	break;
    193     }
    194   }
    195 
    196   if (args.sig==-1) {
    197     WRITE_MSG(2, "Invalid signal specified\n");
    198     return EXIT_FAILURE;
    199   }
    200 
    201   if (args.xid==VC_NOCTX && optind==argc) {
    202     WRITE_MSG(2, "No pid specified\n");
    203     return EXIT_FAILURE;
    204   }
    205 
    206   if (optind==argc)
    207     fail += kill_wrapper(args.xid, "0", args.sig);
    208   else for (;optind<argc;++optind)
    209     fail += kill_wrapper(args.xid, argv[optind], args.sig);
    210 
    211   return fail==0 ? EXIT_SUCCESS : EXIT_FAILURE;
    212 }
    213 
    214 #ifdef TESTSUITE
    215 void
    216 vkill_test()
    217 {
    218   assert(str2sig("0") ==0 );
    219   assert(str2sig("1") ==1 );
    220   assert(str2sig("10")==10);
    221   assert(str2sig("SIGHUP")==1);
    222   assert(str2sig("HUP")   ==1);
    223   assert(str2sig("SIGCHLD")==17);
    224   assert(str2sig("CHLD")   ==17);
    225   assert(str2sig("x")==-1);
    226   assert(str2sig("1 0")==-1);
    227 
    228   return 0;
    229 }
    230 #endif