3 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2007,
4 2009, 2011 Red Hat, Inc.
6 This file is part of Cygwin.
8 This software is a copyrighted work licensed under the terms of the
9 Cygwin license. Please consult the file "CYGWIN_LICENSE" for
19 #include <sys/cygwin.h>
20 #include <cygwin/version.h>
24 static char *prog_name
;
26 static struct option longopts
[] =
28 {"help", no_argument
, NULL
, 'h' },
29 {"list", optional_argument
, NULL
, 'l'},
30 {"force", no_argument
, NULL
, 'f'},
31 {"signal", required_argument
, NULL
, 's'},
32 {"version", no_argument
, NULL
, 'V'},
36 static char opts
[] = "hl::fs:V";
39 usage (FILE *where
= stderr
)
42 "Usage: %1$s [-f] [-signal] [-s signal] pid1 [pid2 ...]\n"
45 "Send signals to processes\n"
47 " -f, --force force, using win32 interface if necessary\n"
48 " -l, --list print a list of signal names\n"
49 " -s, --signal send signal (use %1$s --list for a list)\n"
50 " -h, --help output usage information and exit\n"
51 " -V, --version output version information and exit\n"
53 exit (where
== stderr
? 1 : 0);
59 printf ("kill (cygwin) %d.%d.%d\n"
61 "Copyright (C) 1996 - %s Red Hat, Inc.\n"
62 "This is free software; see the source for copying conditions. There is NO\n"
63 "warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\n",
64 CYGWIN_VERSION_DLL_MAJOR
/ 1000,
65 CYGWIN_VERSION_DLL_MAJOR
% 1000,
66 CYGWIN_VERSION_DLL_MINOR
,
67 strrchr (__DATE__
, ' ') + 1);
73 if (signo
>= 0 && signo
< NSIG
)
74 return sys_sigabbrev
[signo
];
75 static char buf
[sizeof ("Unknown signal") + 32];
76 sprintf (buf
, "Unknown signal %d", signo
);
81 getsig (const char *in_sig
)
87 if (strncmp (in_sig
, "SIG", 3) == 0)
91 sprintf (buf
, "SIG%-.20s", in_sig
);
94 intsig
= strtosigno (sig
) ?: atoi (in_sig
);
96 if (!intsig
&& (strcmp (buf
, "SIG0") != 0 && (strtol (in_sig
, &p
, 10) != 0 || *p
)))
102 test_for_unknown_sig (int sig
, const char *sigstr
)
104 if (sig
< 0 || sig
> NSIG
)
106 fprintf (stderr
, "%1$s: unknown signal: %2$s\n"
107 "Try `%1$s --help' for more information.\n",
114 listsig (const char *in_sig
)
118 for (sig
= 1; sig
< NSIG
- 1; sig
++)
119 printf ("%s%c", strsigno (sig
) + 3, (sig
< NSIG
- 1) ? ' ' : '\n');
122 sig
= getsig (in_sig
);
123 test_for_unknown_sig (sig
, in_sig
);
124 if (atoi (in_sig
) == sig
)
125 puts (strsigno (sig
) + 3);
127 printf ("%d\n", sig
);
132 get_debug_priv (void)
136 TOKEN_PRIVILEGES tkp
;
138 if (!OpenProcessToken (GetCurrentProcess (),
139 TOKEN_ADJUST_PRIVILEGES
| TOKEN_QUERY
, &tok
))
142 if (!LookupPrivilegeValue (NULL
, SE_DEBUG_NAME
, &luid
))
148 tkp
.PrivilegeCount
= 1;
149 tkp
.Privileges
[0].Luid
= luid
;
150 tkp
.Privileges
[0].Attributes
= SE_PRIVILEGE_ENABLED
;
152 AdjustTokenPrivileges (tok
, FALSE
, &tkp
, sizeof tkp
, NULL
, NULL
);
157 static void __stdcall
158 forcekill (int pid
, int sig
, int wait
)
160 // try to acquire SeDebugPrivilege
163 external_pinfo
*p
= NULL
;
164 /* cygwin_internal misinterprets negative pids (Win9x pids) */
166 p
= (external_pinfo
*) cygwin_internal (CW_GETPINFO_FULL
, pid
);
167 DWORD dwpid
= p
? p
->dwProcessId
: (DWORD
) pid
;
168 HANDLE h
= OpenProcess (PROCESS_TERMINATE
, FALSE
, (DWORD
) dwpid
);
171 if (!wait
|| GetLastError () != ERROR_INVALID_PARAMETER
)
172 fprintf (stderr
, "%s: couldn't open pid %u\n",
173 prog_name
, (unsigned) dwpid
);
176 if (!wait
|| WaitForSingleObject (h
, 200) != WAIT_OBJECT_0
)
177 if (sig
&& !TerminateProcess (h
, sig
<< 8)
178 && WaitForSingleObject (h
, 200) != WAIT_OBJECT_0
)
179 fprintf (stderr
, "%s: couldn't kill pid %u, %u\n",
180 prog_name
, (unsigned) dwpid
, (unsigned int) GetLastError ());
185 main (int argc
, char **argv
)
190 char *gotasig
= NULL
;
192 prog_name
= program_invocation_short_name
;
200 long long int pid
= 0;
205 char **av
= argv
+ optind
;
206 if ((ch
= getopt_long (argc
, argv
, opts
, longopts
, NULL
)) == EOF
)
212 sig
= getsig (gotasig
);
217 optarg
= argv
[optind
];
244 optind
= 1 + av
- argv
;
246 sig
= getsig (gotasig
);
255 test_for_unknown_sig (sig
, gotasig
);
258 while (*argv
!= NULL
)
261 pid
= strtoll (*argv
, &p
, 10);
263 || (!force
&& (pid
< INT_MIN
|| pid
> INT_MAX
))
264 || (force
&& (pid
<= 0 || pid
> UINT_MAX
)))
266 fprintf (stderr
, "%s: illegal pid: %s\n", prog_name
, *argv
);
269 else if (pid
<= INT_MAX
&& kill ((pid_t
) pid
, sig
) == 0)
272 forcekill ((pid_t
) pid
, sig
, 1);
275 forcekill ((pid_t
) pid
, sig
, 0);
279 sprintf (buf
, "%s: %lld", prog_name
, pid
);