dupシステムコール(リダイレクト)
Rev.3を表示中。最新版はこちら。
ファイル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:標準エラー
・標準出力は表示されませんが、標準エラーには表示されています。
[root@localhost kitamura]# cat hoge 2>&1 >/dev/null cat: hoge: そのようなファイルやディレクトリはありません [root@localhost kitamura]# echo hogehoge > hoge [root@localhost kitamura]# cat hoge 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
標準出力/標準エラーは表示されていません。
[root@localhost kitamura]# rm hoge rm: `hoge' を削除できません: そのようなファイルやディレクトリはありません [root@localhost kitamura]# cat hoge >/dev/null 2>&1 [root@localhost kitamura]# echo hogehoge > hoge [root@localhost kitamura]# cat hoge >/dev/null 2>&1 [root@localhost kitamura]# >/dev/nul[dup2(/dev/null, 1)]:files->fd[1] =/dev/null 2>&1 [dup2(1, 2) ]:files->fd[2]=files->fd[1](/dev/null)
リダイレクト元が標準出力の場合省略できます。リダイレクト先の&は、ファイルIDで、&がなければファイルとなります。