自分は今OSを勉強していて、その一環としてシステムコールを勉強しています。
MINIXを教材としています。
DUPシステムコールがどのような動作をするのかはなんとなくイメージできるのですが具体的にどのように使われるのか、使われるシチュエーションが全く想像できません。
dupシステムコールの使われ方やdupシステムコールの動作などわかりやすく教えてほしいです。
回答よろしくお願いします。
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答2件
0
IOリダイレクトの実現にdupを使うことを知ってます。例えば、
$ prog > file.txt
とした場合、prog自身がファイル("file.txt")をopen/fopenするのではありませんね。progは、標準出力(1番)がファイルへのパスとなった状態で起動されています。printf()などで標準出力へ書き出すと、自動的にファイルに書き出すことになります。このprogを起動(fork)するのはシェル(bash等)ですので、親プロセスはシェル、子プロセスはprogです。
さて、forkされた子プロセスの標準入出力パス(0, 1, 2番)は、親プロセスの標準入出力パスを受け継ぐことになっています。それは、上記のリダイレクトを実現するには、progをforkする時点で、シェル自身の標準出力パス(1番)がファイル("file.txt")へのパスになっていなければならないことを意味します。この辺りにdupが使われます。
例1: $ prog > file.txt の場合
progの0番パスはキーボード、1番はファイルへのパス、です。すなわち、シェルはパス1番をファイルにしたい、こんな手順で行います。
- 一旦、シェル自身のパス1番を他のパス番号に退避させる path_save = dup(1);
- パス1番をクローズする close(1);
- ファイルをオープンする path = open("file.txt", ???);
パス1番をクローズした状態でopen()すれば、そのパス番号は1番です。progを起動できる状態になったので、
4. progを起動(fork/exec)する
prog を起動した後、シェルにとってパス番号1番(ファイル)は不要になります。close(1); dup(path_save); を行って、シェルのパス1番(コンソール)を復旧し、最後に close(path_save); すれば元の状態に戻ります。
例2: $ prog1 | prog2 パイプラインの場合
- prog1 の0番はキーボード、1番はパイプ
- prog2 の0番はパイプ、1番はコンソール
ですから、それぞれ prog1, prog2 を起動する時点でシェル自身も同じパス番号の構成にならなくてはいけない。この場合、シェルがパイプをopenするのは一度だけ、それをdupして2つのプロセスをつなぐことがミソです。手順は長くなるので省略しますが、ちょっとしたパズルです。興味があれば考えてみてください。
…という具合で、dupを使うのは主にシェルであり、一般のプログラムが使う機会は滅多にないと思いますが、重要な機能を実現していると言えます。
投稿2018/07/19 04:38
総合スコア1380
0
私が使ったことがあるのは、ファイルディスクリプタの一時的な待避のためです。
「Aという処理の時だけ一時的に、標準出力をこのファイルにリダイレクトして、また元の出力先に戻す」
というケースでは、1を未使用FDにdupして、1をクローズして、出力ファイルをオープンして、Aの処理を行い、戻すときは1をクローズして、さっきdupした先からdupして戻し、dup先をクローズします。これで元の状態に戻ります。
投稿2018/07/18 17:26
総合スコア84499
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2018/07/19 01:22
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。