無料Wikiサービス | デモページ
検索

アクセス数
最近のコメント
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
はじめ - ノース
はじめ - ノース
はじめ - 楽打連動ユーザー
はじめ - 楽打連動ユーザー
Adsense
広告情報が設定されていません。

dupシステムコール(リダイレクト)


ファイルIDは、struct fileを設定してあるcurrent->files->fd[]のインデックスで、dupシステムコールは、file = fcheck(oldfd)で、リダイレクト元のstruct fileを取得し、files->fd[newfd] = fileでリダイレクト先へ設定します。

struct fileは、ファイル/デバイス毎の入出力のコールバック関数が定義されている構造体で、カーネルと外部とがやり取りするデバイスドライバそのものです。従ってリダイレクト先はリダイレクト元と同じデバイスドライバを介して入出力を行うことになります。
asmlinkage long sys_dup2(unsigned int oldfd, unsigned int newfd)
{
       int err = -EBADF;
       struct file * file, *tofree;
       struct files_struct * files = current->files;

       spin_lock(&files->file_lock);
       if (!(file = fcheck(oldfd)))
               goto out_unlock;
       err = newfd;
       if (newfd == oldfd)
               goto out_unlock;
       err = -EBADF;
       if (newfd >= current->rlim[RLIMIT_NOFILE].rlim_cur)
               goto out_unlock;
       get_file(file);                 /* We are now finished with oldfd */

       err = expand_files(files, newfd);
       if (err < 0)
               goto out_fput;

       err = -EBUSY;
       tofree = files->fd[newfd];
       if (!tofree && FD_ISSET(newfd, files->open_fds))
               goto out_fput;

       files->fd[newfd] = file;
       FD_SET(newfd, files->open_fds);
       FD_CLR(newfd, files->close_on_exec);
       spin_unlock(&files->file_lock);

       if (tofree)
               filp_close(tofree, files);
       err = newfd;
out:
       return err;
out_unlock:
       spin_unlock(&files->file_lock);
       goto out;

out_fput:
       spin_unlock(&files->file_lock);
       fput(file);
       goto out;
}
リダイレクトというネーミングから、川の流れの向きが変わる様なイメージを連想します。通常の使用では、この理解で問題ないですが、実装からするとこの名称は誤解をまねくのではと。流れをリダイレクト先の給水場の給入口へ流すのでなく、その給出口へ流すということで、ある意味、水路そのものを施工(共有)するということです。

1:標準出力
2:標準エラー
command 2>&1 >/dev/nullでは、標準エラーには表示されています。
2>&1      [dup2(1, 2)        ]:files->fd[2]=files->fd[1]
>/dev/null[dup2(/dev/null, 1)]:files->fd[1]=/dev/null
標準エラーは、/dev/null設定される前のfiles->fd[1]のため、エラーは表示されてしまいます。

command >/dev/null 2>&1 標準出力/標準エラーは表示されていません。
>/dev/nul[dup2(/dev/null, 1)]:files->fd[1]  =/dev/null
2>&1     [dup2(1, 2)        ]:files->fd[2]=files->fd[1](/dev/null)
標準エラーは、/dev/null設定されたfiles->fd[1]のため、エラーは表示されません。

補足

リダイレクト元が標準出力の場合省略できます。リダイレクト先の&は、ファイルIDで、&がなければファイルとなります。

最終更新 2014/08/05 14:55:23 - north
(2014/08/04 18:34:01 作成)