Cを手を動かしながら読み進めてみた。以下のような簡単なbashのようなシェルを作ってみようというもの。非常にわかりやすく書かれており、C言語の勉強にはもってこいだと感じた。(僕はC言語にはあまり触れたことがない。設定ファイルの読み込み等。ユーザー入力やファイル(stdin)を読み込んで実行。メモリを解放して終了。この流れが基本的なライフサイクルだが、今回作るシェルはbashのようなものなので、実行のたびに設定やシェルの終了がないことに注意する。プログラムの概形は以下のようになる。EXIT_SUCCESS;}シェルの簡単なループまずコマンドを扱う基本的な流れは以下のとおり。入力からコマンドを読み取る。コマンドの文字列をプログラムや引数として解釈する。解釈したコマンドを実行する。loopのコマンドの概形は以下のとおり。{////プロンプトの入力を読み取って、関数や引数に分割して、実行、そしてメモリ等を解放している。line)ユーザがどれだけの文字の量を入力してくるのかわからないので、まずある程度の量を見積もっておき、それを超えたら再割り当てするようにする(Cではこれが定石らしい)。{////最初の部分は宣言ばかりで、while以下がキモになる。しているが、これはintであることに気をつける。EOFはcharではなくintだからだ。改行もしくは文字の終端がきたら終了する。それ以外はcharを連結してstringを作る。次にはじめに準備したbufferのサイズを超えていないか、になる。超えていたらreallocateする。それを使うと以下のように簡単に短縮される。line)今さっき読み込んだものの引数を解釈していく。ここでは簡単のために、引数の解釈にはスペースを利用する。ように分割された引数を持つこととなる。トークナイズすれば良い。同じロジックであるが、先ほどはnullで終わるcharの配列を扱っていたのに対して、今回はnullで終わるポインターの配列を扱っている。ポインターをはじめのトークンに与えている。bytesをつけている。文字のポインターの配列のポインターを格納している。言っててわからなくなってきた。終わるとnullでトークンの配列作成が終わる。シェルの開始シェルの開始がもっともシェルの大切な部分になる。プロセスをUNIX上で動かすには2つしか方法がない。1つ目は、初期化(Init)だ。UNIXのコンピューターが起動する時、カーネルがロードされる。一度カーネルがロードされ初期化されると、カーネルはそのたった1つのプロセスのみが動き(それを初期化と言うのだが)、コンピューターが動いている間はそのプロセスはずっと動き続ける。多くのプログラムはこのように初期化されないためもう一つの方法が出てくる。OSがプロセスを複製するのだ(オリジナルが親、コピーが子になる)。子プロセスに0を返し、子プロセスは親プロセスに自身のプロセスID(PID)を返す。新しいプロセスを開始するには既存のプロセスから複製することが大切なのだ。ところが、ここで問題がある。欲しいのは既存のプロセスの複製ではなく、違うプロセスなのだ。現在のプロセスを全く異なるプロセスに書き換えることができる。フォークすることで2つのプロセスができる。利用していて新しいプロセスに書き換わる。親プロセスはこれをしながらも他のことを行い続けることが可能で、子プロセスとの関連は持ち続ける。起動のコードはこんな感じになる。{////プロセスをまずフォークするが、そのpidが0の時は子プロセスに相当する。利用している(execの仲間)。プログラムが実行する時にファイルのフルパスを与えるのではなく、その名前を与えてOSに探してもらうことを表す。-1を返す時はエラーがあったことになる。システムエラーをプログラムの名前とともにプリントする。エラーがどこからきているか検証できる。フォークでエラーがあった時である。if文の最後のブロックはフォークが成功し、親プロセスの時の処理が対応する。子プロセスの実行完了を親プロセスは待ってあげねばならない。プロセスの状態が変わるまで待機する。プロセスは正常に終了することもあれば、エラーや強制終了で終わることがあって多くのことを想定しないといけない。プロセスが終了するかキルされるまで待機することにする。使うことになるが、カレントディレクトリはプロセスのプロパティだからである。親プロセスの持つカレントディレクトリは移動前のままになる。子プロセスも親プロセスの持つカレントディレクトリを継承することになる。読んでももともと呼ばれていたシェル自体を終了することができない。終わらせたいシェルの中に組み込む必要がある。した設定が書かれている。いくつかのコマンドをシェルそのものに加えていかねばならない。それらは以下のようになる。二つ目の引数が存在するか確認し、なければエラーを出す。0を返してシェルのループを終了する。これはビルトインとプロセス両方の起動を行う。{////最後の仕上げ必要なヘッダーファイルをインクルードする。ここで実装したのは非常に簡単なbashのようなシェルで、以下のようないくつかの問題はある。コードはgithubにあげておいた。スペースで引数を判断するので"“で囲まれた複数の単語までそれぞれが引数として認識されてしまう。パイプライン処理は対応していないビルトインのコマンドが少なすぎるワイルドカードで検索(glob)できない※CのライブラリやUNIXについてわからないことがあればここが非常に参考になるとのこと。(ベトナム)でiPhoneをひったくられた話(盗難時のロックとか対処法とか保険とか)プログラミングの勉強をする前に知っておきたかったこと・知っておいてほしいことブロックチェーンまわりの技術本を書きましたウェブサイトを作る時に便利なサービスたち(ロゴ生成、LP作成、画像引用とか)中国の深センの病院を退院して無事帰国しました。(医療搬送とかお金とか海外旅行保険の話)月別アーカイブ参加グループテクノロジーはてなブログをはじめよう!ngo275さんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。