diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2019-02-02 23:02:00 +0300 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2019-02-02 23:02:00 +0300 |
commit | 658f9390032ad2f4a70fb2550480ec8ca58a530a (patch) | |
tree | 06b12e0e109cac3f6ddfe75bacc48a896b4df4a0 /winsup/utils/kill.cc | |
parent | 3a3934252c2cb390b3970edb4898f452ea2f641a (diff) |
Cygwin: kill(1): introduce a -W option
Allow to kill processes using Windows PIDs on the command line.
Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
Diffstat (limited to 'winsup/utils/kill.cc')
-rw-r--r-- | winsup/utils/kill.cc | 58 |
1 files changed, 39 insertions, 19 deletions
diff --git a/winsup/utils/kill.cc b/winsup/utils/kill.cc index e34923ac0..7905c4ea7 100644 --- a/winsup/utils/kill.cc +++ b/winsup/utils/kill.cc @@ -26,17 +26,18 @@ static struct option longopts[] = {"list", optional_argument, NULL, 'l'}, {"force", no_argument, NULL, 'f'}, {"signal", required_argument, NULL, 's'}, + {"winpid", no_argument, NULL, 'W'}, {"version", no_argument, NULL, 'V'}, {NULL, 0, NULL, 0} }; -static char opts[] = "hl::fs:V"; +static char opts[] = "hl::fs:WV"; static void usage (FILE *where = stderr) { fprintf (where , "" - "Usage: %1$s [-f] [-signal] [-s signal] pid1 [pid2 ...]\n" + "Usage: %1$s [-fW] [-signal] [-s signal] pid1 [pid2 ...]\n" " %1$s -l [signal]\n" "\n" "Send signals to processes\n" @@ -44,6 +45,8 @@ usage (FILE *where = stderr) " -f, --force force, using win32 interface if necessary\n" " -l, --list print a list of signal names\n" " -s, --signal send signal (use %1$s --list for a list)\n" + " -W, --winpid specified pids are windows PIDs, not Cygwin PIDs\n" + " (use with extrem caution!)\n" " -h, --help output usage information and exit\n" " -V, --version output version information and exit\n" "\n", prog_name); @@ -152,19 +155,28 @@ get_debug_priv (void) } static void __stdcall -forcekill (pid_t pid, int sig, int wait) +forcekill (pid_t pid, DWORD winpid, int sig, int wait) { + DWORD dwpid; + /* try to acquire SeDebugPrivilege */ get_debug_priv(); - external_pinfo *p = NULL; - p = (external_pinfo *) cygwin_internal (CW_GETPINFO_FULL, pid); - if (!p) + if (!winpid) { - fprintf (stderr, "%s: %d: No such process\n", prog_name, pid); - return; + external_pinfo *p = (external_pinfo *) + cygwin_internal (CW_GETPINFO_FULL, pid); + if (!p) + { + fprintf (stderr, "%s: %d: No such process\n", prog_name, pid); + return; + } + dwpid = p->dwProcessId; } - DWORD dwpid = p->dwProcessId; + else + /* pid is used for printing only after this point */ + pid = dwpid = winpid; + HANDLE h = OpenProcess (PROCESS_TERMINATE, FALSE, dwpid); if (!h) { @@ -186,6 +198,7 @@ main (int argc, char **argv) { int sig = SIGTERM; int force = 0; + int winpids = 0; int ret = 0; char *gotasig = NULL; @@ -197,7 +210,6 @@ main (int argc, char **argv) opterr = 0; char *p; - long long int pid = 0; for (;;) { @@ -228,6 +240,9 @@ main (int argc, char **argv) case 'f': force = 1; break; + case 'W': + winpids = 1; + break; case 'h': usage (stdout); break; @@ -257,32 +272,37 @@ out: fprintf (stderr, "%s: not enough arguments\n", prog_name); return 1; } - while (*argv != NULL) + for (long long int pid = 0; *argv != NULL; argv++) { - if (!pid) - pid = strtoll (*argv, &p, 10); + DWORD dwpid = 0; + + pid = strtoll (*argv, &p, 10); /* INT_MIN <= pid <= INT_MAX. -f only takes positive pids. */ if (*p != '\0' || pid < (force ? 1 : INT_MIN) || pid > INT_MAX) { fprintf (stderr, "%s: illegal pid: %s\n", prog_name, *argv); ret = 1; + continue; + } + if (winpids) + { + dwpid = pid; + pid = (pid_t) cygwin_internal (CW_WINPID_TO_CYGWIN_PID, dwpid); } - else if (kill ((pid_t) pid, sig) == 0) + if (kill ((pid_t) pid, sig) == 0) { if (force) - forcekill ((pid_t) pid, sig, 1); + forcekill ((pid_t) pid, dwpid, sig, 1); } else if (force) - forcekill ((pid_t) pid, sig, 0); + forcekill ((pid_t) pid, dwpid, sig, 0); else { char buf[1000]; - sprintf (buf, "%s: %lld", prog_name, pid); + sprintf (buf, "%s: %lld", prog_name, dwpid ?: pid); perror (buf); ret = 1; } - argv++; - pid = 0; } return ret; } |