2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

bashのexecute_command_internal()に関する疑問(メモ)

Last updated at Posted at 2021-08-02

bashのexecute_command_internal()の658行目あたりに子プロセスが実行する部分がある。

こんな感じ

pid_t paren_pid;
int s;

/*中略*/

paren_pid = make_child(/*sは使われない*/);


if (paren_pid == 0) {
   
    s  = (/*フラグとかを評価*/)
    s += (/*フラグとかを評価*/)
    
    last_command_exit_value = 
        execute_in_subshell(/*sは使われない*/)
    
    /*ここで初めてsの値が使われる*/
    if (s)
        subshell_exit(last_command_exit_value);
    else
        sh_exit(last_command_exit_value);
} 


/*これ以降sは使われない*/

コマンドがサブシェルで実行されるときは、このコードが実行されるっぽい。bashはmake_child()を呼び出して内部でfork()を呼び出す。そして、子プロセスはsにフラグの判定結果を代入して、その結果によってsubshell_exit()かsh_exit()を呼び出す
これら2つの関数は最終的にexit()を呼び出すだけで、メモリを開放する以外にあまり違いはないように見える。

ここまでの処理で疑問がある。

ローカル変数sは親プロセスでは使われておらず、サブシェル内で終了方法を判定する以外に使われていない。

プロセスはフォークするとそのプロセスのコピーがつくられつので、スタックやヒープの情報は保存されている。
なので、sを親プロセスで定義しているのはなんのためなのかがわからない。
つまり、上記のコードを以下のようにしたほうが良いのではないかと思った。

pid_t paren_pid;

/*中略*/

paren_pid = make_child(/*sは使われない*/);

if (paren_pid == 0) {
    int s;
    s  = (/*フラグとかを評価*/)
    s += (/*フラグとかを評価*/)
    
    last_command_exit_value = 
        execute_in_subshell(/*sは使われない*/)
    
    /*ここで初めてsの値が使われる*/
    if (s)
        subshell_exit(last_command_exit_value);
    else
        sh_exit(last_command_exit_value);
}

/*これ以降sは使われない*/

もしかしたら、完全に抜けている知識があるせいでこのような疑問を持ってしまうのかもしれないが、一応メモのために載せた。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?