From: Enrico Scholz Date: Wed, 3 Dec 2003 00:07:10 +0000 (+0000) Subject: initial checkin X-Git-Tag: version_0_26_90~15 X-Git-Url: http://git.linux-vserver.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=76c20c5dae332551ea34908689aba63ac12b79cf;p=util-vserver.git initial checkin git-svn-id: http://svn.linux-vserver.org/svn/util-vserver/branches/SYSCALL_SWITCH@463 94cd875c-1c1d-0410-91d2-eb244daf1a30 --- diff --git a/util-vserver/src/vkill.c b/util-vserver/src/vkill.c new file mode 100644 index 0000000..f30da6f --- /dev/null +++ b/util-vserver/src/vkill.c @@ -0,0 +1,216 @@ +// $Id$ --*- c -*-- + +// Copyright (C) 2003 Enrico Scholz +// +// This program 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 Software Foundation; version 2 of the License. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + + +#ifdef HAVE_CONFIG_H +# include +#endif +#include "compat.h" + +#include "vserver.h" +#include "linuxvirtual.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define VERSION_COPYRIGHT_DISCLAIMER + +#define CMD_HELP 0x8000 +#define CMD_VERSION 0x8001 + +#define WRITE_MSG(FD,X) (void)(write(FD,X,sizeof(X)-1)) +#define WRITE_STR(FD,X) writeStr(FD,X) + +static struct option const +CMDLINE_OPTIONS[] = { + { "help", no_argument, 0, CMD_HELP }, + { "version", no_argument, 0, CMD_VERSION }, + { 0,0,0,0 } +}; + +struct Arguments +{ + ctx_t ctx; + int sig; +}; + +static char const * const SIGNALS[] = { + // 0 1 2 3 4 5 6 7 + "UNUSED", "HUP", "INT", "QUIT", "ILL", "TRAP", "ABRT", "UNUSED", + "FPE", "KILL", "USR1", "SEGV", "USR2", "PIPE", "ALRM", "TERM", + "STKFLT", "CHLD", "CONT", "STOP", "TSTP", "TTIN", "TTOU", "IO", + "XCPU", "XFSZ", "VTALRM", "PROF", "WINCH", + 0, +}; + +inline static void UNUSED +writeStr(int fd, char const *cmd) +{ + (void)write(fd, cmd, strlen(cmd)); +} + +static void +showHelp(int fd, char const *cmd, int res) +{ + WRITE_MSG(fd, "Usage: "); + WRITE_STR(fd, cmd); + WRITE_MSG(fd, + " [-c ] [-s ] [--] []+\n" + "Please report bugs to " PACKAGE_BUGREPORT "\n"); + exit(res); +} + +static void +showVersion() +{ + WRITE_MSG(1, + "vkill " VERSION " -- sends signals to processes within other contexts\n" + "This program is part of " PACKAGE_STRING "\n\n" + "Copyright (C) 2003 Enrico Scholz\n" + VERSION_COPYRIGHT_DISCLAIMER); + exit(0); +} + +static int +str2sig(char const *str) +{ + char *errptr; + int res = strtol(str, &errptr, 10); + + if (*errptr!='\0') res=-1; + if (res==-1 && strncmp(str,"SIG",3)==0) str+=3; + if (res==-1) { + char const * const *ptr = SIGNALS; + for (;*ptr!=0; ++ptr) { + if (strcmp(*ptr,str)!=0) continue; + res = ptr-SIGNALS; + break; + } + } + + return res; +} + +static int +kill_wrapper_legacy(ctx_t ctx, char const *proc, int sig) +{ + pid_t pid = fork(); + if (pid==-1) { + perror("fork()"); + exit(1); + } + else if (pid==0) { + int status; + int res; + while ((res=wait4(pid, &status, 0,0))==-1 && + (errno==EAGAIN || errno==EINTR)) {} + + return (res==0 && WIFEXITED(status) && WEXITSTATUS(status)) ? 0 : 1; + } + + execl(LEGACYDIR "/vkill", "legacy/vkill", proc, (void *)(0)); + perror("execl()"); + exit(1); +} + +static int +kill_wrapper(ctx_t ctx, char const *pid, int sig) +{ + //printf("kill_wrapper(%u, %s, %i)\n", ctx, pid, sig); + if (vc_ctx_kill(ctx,atoi(pid),sig)==-1) { + int err = errno; + if (vc_get_version(VC_CAT_COMPAT)==-1) + return kill_wrapper_legacy(ctx, pid, sig); + else { + errno = err; + perror("vc_ctx_kill()"); + return 1; + } + } + + return 0; +} + +int main(int argc, char *argv[]) +{ + int fail = 0; + struct Arguments args = { + .ctx = VC_NOCTX, + .sig = SIGTERM, + }; + + while (1) { + int c = getopt_long(argc, argv, "c:s:", CMDLINE_OPTIONS, 0); + if (c==-1) break; + + switch (c) { + case CMD_HELP : showHelp(1, argv[0], 0); + case CMD_VERSION : showVersion(); + case 'c' : args.ctx = atoi(optarg); break; + case 's' : args.sig = str2sig(optarg); break; + default : + WRITE_MSG(2, "Try '"); + WRITE_STR(2, argv[0]); + WRITE_MSG(2, " --help\" for more information.\n"); + return EXIT_FAILURE; + break; + } + } + + if (args.sig==-1) { + WRITE_MSG(2, "Invalid signal specified\n"); + return EXIT_FAILURE; + } + + if (args.ctx==VC_NOCTX && optind==argc) { + WRITE_MSG(2, "No pid specified\n"); + return EXIT_FAILURE; + } + + if (optind==argc) + fail += kill_wrapper(args.ctx, "0", args.sig); + else for (;optind