preadシステムコール(pipe)


pread/pwriteはfile->f_modeがFMODE_PREAD/FMODE_PWRITEでないと返値-ESPIPEのエラーで、pipeのfile->f_modeには、FMODE_PREAD/FMODE_PWRITEは設定されません。
#define ESPIPE          29

SYSCALL_DEFINE(pread64)(unsigned int fd, char __user *buf,
                       size_t count, loff_t pos)
{
       struct file *file;
       ssize_t ret = -EBADF;
       int fput_needed;

       if (pos < 0)
               return -EINVAL;

       file = fget_light(fd, &fput_needed);
       if (file) {
               ret = -ESPIPE;
               if (file->f_mode & FMODE_PREAD)
                       ret = vfs_read(file, buf, count, &pos);
               fput_light(file, fput_needed);
       }

       return ret;
}

SYSCALL_DEFINE(pwrite64)(unsigned int fd, const char __user *buf,
                        size_t count, loff_t pos)
{
       struct file *file;
       ssize_t ret = -EBADF;
       int fput_needed;

       if (pos < 0)
               return -EINVAL;

       file = fget_light(fd, &fput_needed);
       if (file) {
               ret = -ESPIPE;
               if (file->f_mode & FMODE_PWRITE)  
                       ret = vfs_write(file, buf, count, &pos);
               fput_light(file, fput_needed);
       }

       return ret;
}
pipe作成での有効flagsはO_CLOEXEC | O_NONBLOCK | O_DIRECTのみで、FMODE_PREAD | FMODE_PWRITEならエラーとなります。
SYSCALL_DEFINE2(pipe2, int __user *, fildes, int, flags)
{
       int fd[2];
       int error;

       error = do_pipe_flags(fd, flags);
       if (!error) {
               if (copy_to_user(fildes, fd, sizeof(fd))) {
                       sys_close(fd[0]);
                       sys_close(fd[1]);
                       error = -EFAULT;
               }
       }
       return error;
}

int do_pipe_flags(int *fd, int flags)
{
       struct file *fw, *fr;
       int error;
       int fdw, fdr;

       if (flags & ~(O_CLOEXEC | O_NONBLOCK | O_DIRECT))
               return -EINVAL;

       fw = create_write_pipe(flags);
       if (IS_ERR(fw))
               return PTR_ERR(fw);
       fr = create_read_pipe(fw, flags);
       error = PTR_ERR(fr);
       if (IS_ERR(fr))
               goto err_write_pipe;

       error = get_unused_fd_flags(flags);
       if (error < 0)
               goto err_read_pipe;
       fdr = error;

       error = get_unused_fd_flags(flags);
       if (error < 0)
               goto err_fdr;
       fdw = error;

       audit_fd_pair(fdr, fdw);
       fd_install(fdr, fr);
       fd_install(fdw, fw);
       fd[0] = fdr;
       fd[1] = fdw;

       return 0;

err_fdr:
       put_unused_fd(fdr);
err_read_pipe:
       path_put(&fr->f_path);
       put_filp(fr);
err_write_pipe:
       free_write_pipe(fw);
       return error;
}


最終更新 2016/11/28 14:09:55 - north
(2016/11/28 14:09:55 作成)


検索

アクセス数
3698085
最近のコメント
コアダンプファイル - sakaia
list_head構造体 - yocto_no_yomikata
勧告ロックと強制ロック - wataash
LKMからのファイル出力 - 重松 宏昌
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
Adsense
広告情報が設定されていません。