killコマンド(外部)


アニメ『キルミーベイベー』

四コマ原作なので、少しずつ見るのにちょうどよいです。くすっと笑えます。
というか、きららファンタジアが気になってしょうがないので、スマホにインストールしてプレイしようとしたのですが、運悪くメンテナンス中でプレイできず。夜中にまたトライしてみます。

今回は外部コマンドのkillのソースを見てみます。
コマンドのパスを確認

takk@deb9:~/src$ which kill
/bin/kill
takk@deb9:~/src$ 

フルパスでパッケージ検索。

takk@deb9:~/src$ apt-file search /bin/kill
avarice: /usr/bin/kill-avarice
ctn: /usr/bin/kill_ctndisp
ctn: /usr/bin/kill_ctnnetwork
ion: /usr/bin/killm
klibc-utils: /usr/lib/klibc/bin/kill
le-dico-de-rene-cougnenc: /usr/bin/killposte
procps: /bin/kill
psmisc: /usr/bin/killall
takk@deb9:~/src$ 

procpsですね。
ソース取得。

takk@deb9:~/src$ apt-get source procps
takk@deb9:~/src$ ls
procps-3.3.12                  procps_3.3.12-3.dsc
procps_3.3.12-3.debian.tar.xz  procps_3.3.12.orig.tar.xz
takk@deb9:~/src$ cd procps-3.3.12/
takk@deb9:~/src/procps-3.3.12$ 

ソースの場所を特定するため、例によってユニークな文言を探します。

takk@deb9:~/src/procps-3.3.12$ /bin/kill -h

Usage:
 kill [options] <pid> [...]

Options:
 <pid> [...]            send signal to every <pid> listed
 -<signal>, -s, --signal <signal>
                        specify the <signal> to be sent
 -l, --list=[<signal>]  list all signal names, or convert one to a name
 -L, --table            list all signal names in a nice table

 -h, --help     display this help and exit
 -V, --version  output version information and exit

For more details see kill(1).
takk@deb9:~/src/procps-3.3.12$ 

検索します。

takk@deb9:~/src/procps-3.3.12$ grep 'convert one to a name' -r * --exclude-dir={po,testsuite}
skill.c:	fputs(_(" -l, --list=[<signal>]  list all signal names, or convert one to a name\n"), out);
takk@deb9:~/src/procps-3.3.12$ 

skill.cっぽいです。killコマンドが実行されたときに、HELLOと表示するように修正。これが表示されたら、このソースで確定です。

takk@deb9:~/src/procps-3.3.12$ cat -n skill.c
~省略~
   418	static void __attribute__ ((__noreturn__))
   419	    kill_main(int argc, char **argv)
   420	{
   421		int signo, i;
   422		int loop = 1;
   423		long pid;
   424		int exitvalue = EXIT_SUCCESS;
   425	
   426		static const struct option longopts[] = {
   427			{"list", optional_argument, NULL, 'l'},
   428			{"table", no_argument, NULL, 'L'},
   429			{"signal", required_argument, NULL, 's'},
   430			{"help", no_argument, NULL, 'h'},
   431			{"version", no_argument, NULL, 'V'},
   432			{NULL, 0, NULL, 0}
   433		};
   434		printf("HELLO\n");
   435		setlocale (LC_ALL, "");
   436		bindtextdomain(PACKAGE, LOCALEDIR);
~省略~

ビルドします。

takk@deb9:~/src/procps-3.3.12$ ./configure
takk@deb9:~/src/procps-3.3.12$ make

killという実行ファイルが生成されました。実行します。

takk@deb9:~/src/procps-3.3.12$ ./kill
HELLO

Usage:
 kill [options] <pid> [...]

~省略~

takk@deb9:~/src/procps-3.3.12$ 

HELLOが表示されたので、このファイルで間違いないです。
では、このファイルの中のシステムコールkillを使用している箇所を検索します。
全部見なくても、周辺みればなんとなく処理は分かるかと思います。

takk@deb9:~/src/procps-3.3.12$ grep -n 'kill.*pid' -C3 skill.c
147-	/* do the actual work */
148-	errno = 0;
149-	if (program == PROG_SKILL)
150:		failed = kill(pid, sig_or_pri);
151-	else
152-		failed = setpriority(PRIO_PROCESS, pid, sig_or_pri);
153-	if ((run_time->warnings && failed) || run_time->debugging || run_time->verbose) {
--
480-			    /* Special case for signal digit negative
481-			     * PIDs */
482-			    pid = atoi(argv[optind]);
483:			    if (kill((pid_t)pid, signo) != 0)
484-				exitvalue = EXIT_FAILURE;
485-			    exit(exitvalue);
486-			}
--
498-
499-	for (i = 0; i < argc; i++) {
500-		pid = strtol_or_err(argv[i], _("failed to parse argument"));
501:		if (!kill((pid_t) pid, signo))
502-			continue;
503-        error(0, errno, "(%ld)", pid);
504-		exitvalue = EXIT_FAILURE;
takk@deb9:~/src/procps-3.3.12$ 

なるほど、普段killを使うことが少ないので知りませんでしたが、プロセスIDは複数指定することができるんですね。
試してみます。sleepコマンドを3つ実行。

takk@deb9:~/src/procps-3.3.12$ sleep 10000 &
[1] 23710
takk@deb9:~/src/procps-3.3.12$ sleep 10000 &
[2] 23711
takk@deb9:~/src/procps-3.3.12$ sleep 10000 &
[3] 23712
takk@deb9:~/src/procps-3.3.12$ ps
  PID TTY          TIME CMD
14801 pts/0    00:00:00 bash
23710 pts/0    00:00:00 sleep
23711 pts/0    00:00:00 sleep
23712 pts/0    00:00:00 sleep
23713 pts/0    00:00:00 ps
takk@deb9:~/src/procps-3.3.12$ 

では、複数PIDを指定してkillコマンドを実行します。

takk@deb9:~/src/procps-3.3.12$ kill 23710 23711 23712
takk@deb9:~/src/procps-3.3.12$ ps
  PID TTY          TIME CMD
14801 pts/0    00:00:00 bash
23716 pts/0    00:00:00 ps
[1]   Terminated              sleep 10000
[2]-  Terminated              sleep 10000
[3]+  Terminated              sleep 10000
takk@deb9:~/src/procps-3.3.12$ 

少しだけ賢くなれました。

Leave a Reply

Your email address will not be published. Required fields are marked *

CAPTCHA