killコマンドでやってること


アニメ『キルラキル』

バトルものはつい視聴を止められなくなってしまいます。アニメは一日数時間、と決めて強い意志で見ないと、寝不足になって仕方がありません。戦闘能力は、装備に依存するのは当たり前なのですが、露出部分が大半なのに強くなる仕組みってところが、面白さを増してます。聖闘士星矢のクロス的な。

今回はキルつながりでkillコマンドです。
killコマンドって内部で何をしているのでしょう。プロセスが係るので、最終的にはシステムコールするしかないような気がします。
まず普段使ってるkillコマンドが内部かどうか確認。

takk@deb9:~$ type kill
kill はシェル組み込み関数です
takk@deb9:~$ 

内部コマンドでした。ですので、helpで使い方が確認できます。

akk@deb9:~$ help kill
kill: kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... または kill -l [sigspec]
    Send a signal to a job.
    
    Send the processes identified by PID or JOBSPEC the signal named by
    SIGSPEC or SIGNUM.  If neither SIGSPEC nor SIGNUM is present, then
    SIGTERM is assumed.
    
    Options:
      -s sig	SIG is a signal name
      -n sig	SIG is a signal number
      -l	list the signal names; if arguments follow `-l' they are
    		assumed to be signal numbers for which names should be listed
      -L	synonym for -l
    
    Kill is a shell builtin for two reasons: it allows job IDs to be used
    instead of process IDs, and allows processes to be killed if the limit
    on processes that you can create is reached.
    
    Exit Status:
    Returns success unless an invalid option is given or an error occurs.
takk@deb9:~$ 

このヘルプの文言から、ソース検索してみます。

takk@deb9:~/src/bash-4.4$ grep 'Kill is a shell' -r * --exclude-dir {po,tests}
builtins/kill.def:Kill is a shell builtin for two reasons: it allows job IDs to be used
takk@deb9:~/src/bash-4.4$ 

kill.defにありそうです。getoptsと同じく.defファイルになってます。

次は、kill.defからpidを使用している箇所を探します。pidという名称がどこから来たのかというと、単に感です。プロセスをkillするなら、当然pidを使っているだろう、と。

takk@deb9:~/src/bash-4.4$ grep -n pid builtins/kill.def
25:$SHORT_DOC kill [-s sigspec | -n signum | -sigspec] pid | jobspec ... or kill -l [sigspec]
75:static void kill_error __P((pid_t, int));
92:  pid_t pid;
93:  intmax_t pid_value;
184:      if (*word && legal_number (list->word->word, &pid_value) && (pid_value == (pid_t)pid_value))
186:	  pid = (pid_t) pid_value;
188:	  if (kill_pid (pid, sig, pid < -1) < 0)
193:		kill_error (pid, errno);
226:	     to be careful.  We take the pid of the first job in the pipeline
228:	  pid = IS_JOBCONTROL (job) ? j->pgrp : j->pipe->pid;
232:	  if (kill_pid (pid, sig, 1) < 0)
237:		kill_error (pid, errno);
246:	  sh_badpid (list->word->word);
257:kill_error (pid, e)
258:     pid_t pid;
266:  builtin_error ("(%ld) - %s", (long)pid, x);
takk@deb9:~/src/bash-4.4$ 

188,232行目のkill_pidでプロセスをkillしてるっぽいですね。

さらにkill_pidで検索します。

takk@deb9:~/src/bash-4.4$ grep kill_pid -r *
builtins/kill.def:	  if (kill_pid (pid, sig, pid < -1) < 0)
builtins/kill.def:	  if (kill_pid (pid, sig, 1) < 0)
jobs.c:kill_pid (pid, sig, group)
jobs.h:extern int kill_pid __P((pid_t, int, int));
nojobs.c:kill_pid (pid, signal, group)
takk@deb9:~/src/bash-4.4$ 

jobs.cにkill_pidの本体があるようです。
さらに検索。

takk@deb9:~/src/bash-4.4$ grep -n 'pid.*sig' jobs.c
3340:kill_pid (pid, sig, group)
3370:	    result = killpg (pid, sig);
3380:		  kill (p->pid, sig);
3403:	result = killpg (pid, sig);
3408:    result = kill (pid, sig);
3519:      if (pid < 0 && errno == EINTR && wait_sigint_received)
4306:  kill (getpid (), sig);
takk@deb9:~/src/bash-4.4$ 

どうも内部では、killpgやkillを使っており、結局これはシステムコールやライブラリってことになりますね。

man 2 kill。

takk@deb9:~/src/bash-4.4$ (LANG=C;man 2 kill | head)
KILL(2)                    Linux Programmer's Manual                   KILL(2)

NAME
       kill - send signal to a process

SYNOPSIS
       #include <sys/types.h>
       #include <signal.h>

       int kill(pid_t pid, int sig);
takk@deb9:~/src/bash-4.4$ 

man 3 killpg。

takk@deb9:~/src/bash-4.4$ (LANG=C;man 3 killpg | head)
KILLPG(3)                  Linux Programmer's Manual                 KILLPG(3)

NAME
       killpg - send signal to a process group

SYNOPSIS
       #include <signal.h>

       int killpg(int pgrp, int sig);

takk@deb9:~/src/bash-4.4$ 

システムコールだけではなく、ライブラリコールもありましたが、結局はプロセス操作するのに、あるものを使うしかないってことが分かりました。

Leave a Reply

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

CAPTCHA