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 fopen0123401234
[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 fopen56789
[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);
}






