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>
This commit is contained in:
parent
3a3934252c
commit
658f939003
|
@ -322,6 +322,15 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
||||||
res = p ? p->dwProcessId : 0;
|
res = p ? p->dwProcessId : 0;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case CW_WINPID_TO_CYGWIN_PID:
|
||||||
|
{
|
||||||
|
DWORD winpid = va_arg (arg, DWORD);
|
||||||
|
pid_t pid = cygwin_pid (winpid);
|
||||||
|
res = pid ?: winpid + MAX_PID;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
case CW_EXTRACT_DOMAIN_AND_USER:
|
case CW_EXTRACT_DOMAIN_AND_USER:
|
||||||
{
|
{
|
||||||
WCHAR nt_domain[MAX_DOMAIN_NAME_LEN + 1];
|
WCHAR nt_domain[MAX_DOMAIN_NAME_LEN + 1];
|
||||||
|
|
|
@ -158,6 +158,7 @@ typedef enum
|
||||||
CW_GETNSS_GRP_SRC,
|
CW_GETNSS_GRP_SRC,
|
||||||
CW_EXCEPTION_RECORD_FROM_SIGINFO_T,
|
CW_EXCEPTION_RECORD_FROM_SIGINFO_T,
|
||||||
CW_CYGHEAP_PROFTHR_ALL,
|
CW_CYGHEAP_PROFTHR_ALL,
|
||||||
|
CW_WINPID_TO_CYGWIN_PID,
|
||||||
} cygwin_getinfo_types;
|
} cygwin_getinfo_types;
|
||||||
|
|
||||||
#define CW_LOCK_PINFO CW_LOCK_PINFO
|
#define CW_LOCK_PINFO CW_LOCK_PINFO
|
||||||
|
@ -220,6 +221,7 @@ typedef enum
|
||||||
#define CW_GETNSS_GRP_SRC CW_GETNSS_GRP_SRC
|
#define CW_GETNSS_GRP_SRC CW_GETNSS_GRP_SRC
|
||||||
#define CW_EXCEPTION_RECORD_FROM_SIGINFO_T CW_EXCEPTION_RECORD_FROM_SIGINFO_T
|
#define CW_EXCEPTION_RECORD_FROM_SIGINFO_T CW_EXCEPTION_RECORD_FROM_SIGINFO_T
|
||||||
#define CW_CYGHEAP_PROFTHR_ALL CW_CYGHEAP_PROFTHR_ALL
|
#define CW_CYGHEAP_PROFTHR_ALL CW_CYGHEAP_PROFTHR_ALL
|
||||||
|
#define CW_WINPID_TO_CYGWIN_PID CW_WINPID_TO_CYGWIN_PID
|
||||||
|
|
||||||
/* Token type for CW_SET_EXTERNAL_TOKEN */
|
/* Token type for CW_SET_EXTERNAL_TOKEN */
|
||||||
enum
|
enum
|
||||||
|
|
|
@ -692,6 +692,8 @@ kill -l [signal]
|
||||||
-f, --force force, using win32 interface if necessary
|
-f, --force force, using win32 interface if necessary
|
||||||
-l, --list print a list of signal names
|
-l, --list print a list of signal names
|
||||||
-s, --signal send signal (use kill --list for a list)
|
-s, --signal send signal (use kill --list for a list)
|
||||||
|
-W, --winpid specified pids are windows PIDs, not Cygwin PIDs
|
||||||
|
(use with extrem caution!)
|
||||||
-h, --help output usage information and exit
|
-h, --help output usage information and exit
|
||||||
-V, --version output version information and exit
|
-V, --version output version information and exit
|
||||||
</screen>
|
</screen>
|
||||||
|
@ -717,7 +719,13 @@ $ /bin/kill --version
|
||||||
</screen> which should give the Cygwin
|
</screen> which should give the Cygwin
|
||||||
<command>kill</command> version number and copyright information. </para>
|
<command>kill</command> version number and copyright information. </para>
|
||||||
|
|
||||||
<para>Unless you specific the <literal>-f</literal> option, the "pid"
|
<para>The <literal>-f</literal> option uses Windows functions to
|
||||||
|
terminate processes forcefully. Use <literal>-f</literal> to
|
||||||
|
terminate native Windows processes not started by Cygwin processes.
|
||||||
|
<literal>-f</literal> can also be useful to terminate Cygwin processes
|
||||||
|
not answering to SIGKILL.</para>
|
||||||
|
|
||||||
|
<para>Unless you specific the <literal>-W</literal> option, the "pid"
|
||||||
values used by <command>kill</command> are the Cygwin pids, not the
|
values used by <command>kill</command> are the Cygwin pids, not the
|
||||||
Windows pids. To get a list of running programs and their Cygwin pids,
|
Windows pids. To get a list of running programs and their Cygwin pids,
|
||||||
use the Cygwin <command>ps</command> program. <command>ps -W</command>
|
use the Cygwin <command>ps</command> program. <command>ps -W</command>
|
||||||
|
|
|
@ -26,17 +26,18 @@ static struct option longopts[] =
|
||||||
{"list", optional_argument, NULL, 'l'},
|
{"list", optional_argument, NULL, 'l'},
|
||||||
{"force", no_argument, NULL, 'f'},
|
{"force", no_argument, NULL, 'f'},
|
||||||
{"signal", required_argument, NULL, 's'},
|
{"signal", required_argument, NULL, 's'},
|
||||||
|
{"winpid", no_argument, NULL, 'W'},
|
||||||
{"version", no_argument, NULL, 'V'},
|
{"version", no_argument, NULL, 'V'},
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
static char opts[] = "hl::fs:V";
|
static char opts[] = "hl::fs:WV";
|
||||||
|
|
||||||
static void
|
static void
|
||||||
usage (FILE *where = stderr)
|
usage (FILE *where = stderr)
|
||||||
{
|
{
|
||||||
fprintf (where , ""
|
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"
|
" %1$s -l [signal]\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Send signals to processes\n"
|
"Send signals to processes\n"
|
||||||
|
@ -44,6 +45,8 @@ usage (FILE *where = stderr)
|
||||||
" -f, --force force, using win32 interface if necessary\n"
|
" -f, --force force, using win32 interface if necessary\n"
|
||||||
" -l, --list print a list of signal names\n"
|
" -l, --list print a list of signal names\n"
|
||||||
" -s, --signal send signal (use %1$s --list for a list)\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"
|
" -h, --help output usage information and exit\n"
|
||||||
" -V, --version output version information and exit\n"
|
" -V, --version output version information and exit\n"
|
||||||
"\n", prog_name);
|
"\n", prog_name);
|
||||||
|
@ -152,19 +155,28 @@ get_debug_priv (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __stdcall
|
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 */
|
/* try to acquire SeDebugPrivilege */
|
||||||
get_debug_priv();
|
get_debug_priv();
|
||||||
|
|
||||||
external_pinfo *p = NULL;
|
if (!winpid)
|
||||||
p = (external_pinfo *) cygwin_internal (CW_GETPINFO_FULL, pid);
|
{
|
||||||
|
external_pinfo *p = (external_pinfo *)
|
||||||
|
cygwin_internal (CW_GETPINFO_FULL, pid);
|
||||||
if (!p)
|
if (!p)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s: %d: No such process\n", prog_name, pid);
|
fprintf (stderr, "%s: %d: No such process\n", prog_name, pid);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
DWORD dwpid = p->dwProcessId;
|
dwpid = p->dwProcessId;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
/* pid is used for printing only after this point */
|
||||||
|
pid = dwpid = winpid;
|
||||||
|
|
||||||
HANDLE h = OpenProcess (PROCESS_TERMINATE, FALSE, dwpid);
|
HANDLE h = OpenProcess (PROCESS_TERMINATE, FALSE, dwpid);
|
||||||
if (!h)
|
if (!h)
|
||||||
{
|
{
|
||||||
|
@ -186,6 +198,7 @@ main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int sig = SIGTERM;
|
int sig = SIGTERM;
|
||||||
int force = 0;
|
int force = 0;
|
||||||
|
int winpids = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
char *gotasig = NULL;
|
char *gotasig = NULL;
|
||||||
|
|
||||||
|
@ -197,7 +210,6 @@ main (int argc, char **argv)
|
||||||
opterr = 0;
|
opterr = 0;
|
||||||
|
|
||||||
char *p;
|
char *p;
|
||||||
long long int pid = 0;
|
|
||||||
|
|
||||||
for (;;)
|
for (;;)
|
||||||
{
|
{
|
||||||
|
@ -228,6 +240,9 @@ main (int argc, char **argv)
|
||||||
case 'f':
|
case 'f':
|
||||||
force = 1;
|
force = 1;
|
||||||
break;
|
break;
|
||||||
|
case 'W':
|
||||||
|
winpids = 1;
|
||||||
|
break;
|
||||||
case 'h':
|
case 'h':
|
||||||
usage (stdout);
|
usage (stdout);
|
||||||
break;
|
break;
|
||||||
|
@ -257,32 +272,37 @@ out:
|
||||||
fprintf (stderr, "%s: not enough arguments\n", prog_name);
|
fprintf (stderr, "%s: not enough arguments\n", prog_name);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
while (*argv != NULL)
|
for (long long int pid = 0; *argv != NULL; argv++)
|
||||||
{
|
{
|
||||||
if (!pid)
|
DWORD dwpid = 0;
|
||||||
|
|
||||||
pid = strtoll (*argv, &p, 10);
|
pid = strtoll (*argv, &p, 10);
|
||||||
/* INT_MIN <= pid <= INT_MAX. -f only takes positive pids. */
|
/* INT_MIN <= pid <= INT_MAX. -f only takes positive pids. */
|
||||||
if (*p != '\0' || pid < (force ? 1 : INT_MIN) || pid > INT_MAX)
|
if (*p != '\0' || pid < (force ? 1 : INT_MIN) || pid > INT_MAX)
|
||||||
{
|
{
|
||||||
fprintf (stderr, "%s: illegal pid: %s\n", prog_name, *argv);
|
fprintf (stderr, "%s: illegal pid: %s\n", prog_name, *argv);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
else if (kill ((pid_t) pid, sig) == 0)
|
if (winpids)
|
||||||
|
{
|
||||||
|
dwpid = pid;
|
||||||
|
pid = (pid_t) cygwin_internal (CW_WINPID_TO_CYGWIN_PID, dwpid);
|
||||||
|
}
|
||||||
|
if (kill ((pid_t) pid, sig) == 0)
|
||||||
{
|
{
|
||||||
if (force)
|
if (force)
|
||||||
forcekill ((pid_t) pid, sig, 1);
|
forcekill ((pid_t) pid, dwpid, sig, 1);
|
||||||
}
|
}
|
||||||
else if (force)
|
else if (force)
|
||||||
forcekill ((pid_t) pid, sig, 0);
|
forcekill ((pid_t) pid, dwpid, sig, 0);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
char buf[1000];
|
char buf[1000];
|
||||||
sprintf (buf, "%s: %lld", prog_name, pid);
|
sprintf (buf, "%s: %lld", prog_name, dwpid ?: pid);
|
||||||
perror (buf);
|
perror (buf);
|
||||||
ret = 1;
|
ret = 1;
|
||||||
}
|
}
|
||||||
argv++;
|
|
||||||
pid = 0;
|
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue