Initial import.
authorlace <>
Sat, 2 Jun 2007 19:52:32 +0000 (19:52 +0000)
committerlace <>
Sat, 2 Jun 2007 19:52:32 +0000 (19:52 +0000)
src/tgkill.c [new file with mode: 0644]

diff --git a/src/tgkill.c b/src/tgkill.c
new file mode 100644 (file)
index 0000000..17ada08
--- /dev/null
@@ -0,0 +1,225 @@
+/* $Id$
+   Copyright 2007, Red Hat Inc.  */
+
+#include <stdio.h>
+#include <signal.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <asm/unistd.h>
+#include <unistd.h>
+#define tkill(tid, sig) syscall (__NR_tkill, (tid), (sig))
+
+#define LENGTH(x) (sizeof (x) / sizeof (*(x)))
+
+struct signal
+  {
+    int signo;
+    const char *name;
+  };
+static const struct signal sigtab[] =
+  {
+#ifdef SIG0
+    { SIG0, "0" },
+#endif
+#ifdef SIGHUP
+    { SIGHUP, "HUP" },
+#endif
+#ifdef SIGINT
+    { SIGINT, "INT" },
+#endif
+#ifdef SIGQUIT
+    { SIGQUIT, "QUIT" },
+#endif
+#ifdef SIGILL
+    { SIGILL, "ILL" },
+#endif
+#ifdef SIGTRAP
+    { SIGTRAP, "TRAP" },
+#endif
+#ifdef SIGABRT
+    { SIGABRT, "ABRT" },
+#endif
+#ifdef SIGBUS
+    { SIGBUS, "BUS" },
+#endif
+#ifdef SIGFPE
+    { SIGFPE, "FPE" },
+#endif
+#ifdef SIGKILL
+    { SIGKILL, "KILL" },
+#endif
+#ifdef SIGUSR1
+    { SIGUSR1, "USR1" },
+#endif
+#ifdef SIGSEGV
+    { SIGSEGV, "SEGV" },
+#endif
+#ifdef SIGUSR2
+    { SIGUSR2, "USR2" },
+#endif
+#ifdef SIGPIPE
+    { SIGPIPE, "PIPE" },
+#endif
+#ifdef SIGALRM
+    { SIGALRM, "ALRM" },
+#endif
+#ifdef SIGTERM
+    { SIGTERM, "TERM" },
+#endif
+#ifdef SIGSTKFLT
+    { SIGSTKFLT, "STKFLT" },
+#endif
+#ifdef SIGCHLD
+    { SIGCHLD, "CHLD" },
+#endif
+#ifdef SIGCONT
+    { SIGCONT, "CONT" },
+#endif
+#ifdef SIGSTOP
+    { SIGSTOP, "STOP" },
+#endif
+#ifdef SIGTSTP
+    { SIGTSTP, "TSTP" },
+#endif
+#ifdef SIGTTIN
+    { SIGTTIN, "TTIN" },
+#endif
+#ifdef SIGTTOU
+    { SIGTTOU, "TTOU" },
+#endif
+#ifdef SIGURG
+    { SIGURG, "URG" },
+#endif
+#ifdef SIGXCPU
+    { SIGXCPU, "XCPU" },
+#endif
+#ifdef SIGXFSZ
+    { SIGXFSZ, "XFSZ" },
+#endif
+#ifdef SIGVTALRM
+    { SIGVTALRM, "VTALRM" },
+#endif
+#ifdef SIGPROF
+    { SIGPROF, "PROF" },
+#endif
+#ifdef SIGWINCH
+    { SIGWINCH, "WINCH" },
+#endif
+#ifdef SIGIO
+    { SIGIO, "IO" },
+#endif
+#ifdef SIGPWR
+    { SIGPWR, "PWR" },
+#endif
+#ifdef SIGSYS
+    { SIGSYS, "SYS" },
+#endif
+#ifdef disableSIGRTMIN /* initializer element is not constant */
+    { SIGRTMIN, "RTMIN" },
+#endif
+#ifdef disableSIGRTMAX /* initializer element is not constant */
+    { SIGRTMAX, "RTMAX" },
+#endif
+  };
+
+static void list (void)
+{
+  const struct signal *sig;
+
+  for (sig = sigtab; sig < sigtab + LENGTH (sigtab); sig++)
+    printf ("%2d\t%s\n", sig->signo, sig->name);
+  exit (EXIT_SUCCESS);
+}
+
+static
+#ifdef __GNUC__
+  __attribute__((__unused__))
+#endif
+  void fail (const char *where)
+{
+  fprintf (stderr, "Error parsing arguments: %s\n", where);
+  exit (EXIT_FAILURE);
+}
+
+static int parse_number (const char *text)
+{
+  char *end;
+  long val;
+
+  val = strtol (text, &end, 0);
+  if (val >= 0 && (int) val == val && (end == NULL || *end == 0))
+    return val;
+
+  return -1;
+}
+
+static int parse_signal (const char *text_orig)
+{
+  const char *text = text_orig;
+  const struct signal *sig;
+  int retval;
+
+  retval = parse_number (text);
+  if (retval >= 0)
+    return retval;
+
+  if (strncasecmp (text, "SIG", 3) == 0)
+    text += 3;
+  for (sig = sigtab; sig < sigtab + LENGTH (sigtab); sig++)
+    if (strcasecmp (sig->name, text) == 0)
+      return sig->signo;
+
+  fail (text_orig);
+  /* NOTREACHED */
+  return -1;
+}
+
+static void help (void)
+{
+  fputs ("\
+tgkill -h\n\
+tgkill -l\n\
+tgkill {-s sigspec | -n sigspec | -sigspec} pid ...\n\
+", stdout);
+  exit (EXIT_SUCCESS);
+}
+
+int main (int argc, char **argv)
+{
+  char **argp;
+  int signo;
+
+  if (argc == 2 && strcmp (argv[1], "-h") == 0)
+    help ();
+  if (argc == 2 && strcmp (argv[1], "-l") == 0)
+    list ();
+
+  if (argc > 3 && (strcmp (argv[1], "-s") == 0 || strcmp (argv[1], "-n") == 0))
+    {
+      signo = parse_signal (argv[2]);
+      argp = argv + 3;
+    }
+  else if (argc > 2 && argv[1][0] == '-')
+    {
+      signo = parse_signal (argv [1] + 1);
+      argp = argv + 2;
+    }
+  else
+    fail ("<general>");
+
+  while (argp < argv + argc)
+    {
+      const char *arg = *argp++;
+      int pid;
+
+      pid = parse_number (arg);
+      if (pid == -1)
+        fail (arg);
+
+      if (tkill (pid, signo) != 0)
+        perror (arg);
+    }
+
+  return EXIT_SUCCESS;
+}