dupサンプル
読込みサンプル
[root@north dup]# cat ropen.c#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <stdlib.h> void do_dup(void); void do_fopen(void); char buff[6]; void main(int argc,char **argv) { system("rm -f babakaka.txt"); system("echo 0123456789 > babakaka.txt"); if (!strcmp(argv[1], "dup")) { do_dup(); } else { do_fopen(); } } void do_dup() { int fd1 =open("babakaka.txt", O_RDWR); int fd2 = dup(fd1); buff[5] = 0; read(fd1, buff, 5); printf("%s", buff); buff[5] = 0; read(fd2, buff, 5); printf("%s\n", buff); } void do_fopen() { int fd1 =open("babakaka.txt", O_RDWR); int fd2 =open("babakaka.txt", O_RDWR); buff[5] = 0; read(fd1, buff, 5); printf("%s", buff); buff[5] = 0; read(fd2, buff, 5); printf("%s\n", buff); }[root@north dup]# ./ropen.out fopen
0123401234
[root@north dup]# ./ropen.out dup
0123456789
書込みサンプル
[root@north dup]# cat wopen.c#include <stdio.h> #include <fcntl.h> #include <unistd.h> #include <string.h> #include <stdlib.h> void do_dup(void); void do_fopen(void); void main(int argc,char **argv) { system("rm -f babakaka.txt"); system("touch babakaka.txt"); if (!strcmp(argv[1], "dup")) { do_dup(); } else { do_fopen(); } } void do_dup() { int fd1 =open("babakaka.txt", O_RDWR); int fd2 = dup(fd1); write(fd2, "01234", 5); write(fd1, "56789\n", 6); close(fd1); close(fd2); system("cat babakaka.txt"); } void do_fopen() { int fd1 =open("babakaka.txt", O_RDWR); int fd2 =open("babakaka.txt", O_RDWR); write(fd1, "01234", 5); write(fd2, "56789\n", 6); close(fd1); close(fd2); system("cat babakaka.txt"); }[root@north dup]# ./wopen.out fopen
56789
[root@north dup]# ./wopen.out dup
0123456789
カーネル
file = current->files[引数ソースfid]current->files[重複先fid] = file; 重複先fidが指定されてなければcurrent->files[]の空インデックス
struct file { : atomic_long_t f_count; unsigned int f_flags; fmode_t f_mode; loff_t f_pos; <- 読み書き位置 struct fown_struct f_owner; : }; SYSCALL_DEFINE1(dup, unsigned int, fildes) { int ret = -EBADF; struct file *file = fget_raw(fildes); if (file) { ret = get_unused_fd(); if (ret >= 0) fd_install(ret, file); else fput(file); } return ret; } struct file *fget_raw(unsigned int fd) { struct file *file; struct files_struct *files = current->files; rcu_read_lock(); file = fcheck_files(files, fd); if (file) { /* File object ref couldn't be taken */ if (!atomic_long_inc_not_zero(&file->f_count)) file = NULL; } rcu_read_unlock(); return file; } void fd_install(unsigned int fd, struct file *file) { __fd_install(current->files, fd, file); } void __fd_install(struct files_struct *files, unsigned int fd, struct file *file) { struct fdtable *fdt; spin_lock(&files->file_lock); fdt = files_fdtable(files); BUG_ON(fdt->fd[fd] != NULL); rcu_assign_pointer(fdt->fd[fd], file); spin_unlock(&files->file_lock); }