dupシステムコール(リダイレクト)
Rev.5を表示中。最新版はこちら。
ファイル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]のため、エラーは表示されません。