*at syscalls: Implementation
Subsystems (4)
PATCH 1/3 *at syscalls: Implementation
fs/compat.c +42 -6
@@ -68,10 +68,10 @@ asmlinkage long compat_sys_utime(char __ tv[0 ].tv_usec =0 ; tv[1 ].tv_usec =0 ; } -return do_utimes (filename, t ? tv :NULL ); +return do_utimes (AT_FDCWD , filename, t ? tv :NULL ); } -asmlinkage long compat_sys_utimes (char __user *filename,struct compat_timeval __user *t) +asmlinkage long compat_sys_futimesat (int dfd,char __user *filename,struct compat_timeval __user *t) {struct timeval tv[2 ];
@@ -82,14 +82,19 @@ asmlinkage long compat_sys_utimes(char _ get_user(tv[1].tv_usec, &t[1].tv_usec))return -EFAULT ; } -return do_utimes (filename, t ? tv :NULL ); +return do_utimes (dfd, filename, t ? tv :NULL ); +} + +asmlinkage long compat_sys_utimes (char __user *filename,struct compat_timeval __user *t) +{ +return compat_sys_futimesat (AT_FDCWD , filename, t); }asmlinkage long compat_sys_newstat (char __user * filename,struct compat_stat __user *statbuf) {struct kstat stat; -int error =vfs_stat (filename, &stat); +int error =vfs_stat_fd (AT_FDCWD , filename, &stat);if (!error) error =cp_compat_stat (&stat, statbuf);
@@ -100,10 +105,31 @@ asmlinkage long compat_sys_newlstat(char struct compat_stat __user *statbuf) {struct kstat stat; -int error =vfs_lstat (filename, &stat); +int error =vfs_lstat_fd (AT_FDCWD , filename, &stat); + +if (!error) + error =cp_compat_stat (&stat, statbuf); +return error; +} + +asmlinkage long compat_sys_newfstatat (int dfd,char __user * filename, +struct compat_stat __user *statbuf,int flag) +{ +struct kstat stat; +int error = -EINVAL ; + +if ((flag & ~AT_SYMLINK_NOFOLLOW ) !=0 ) + goto out; + +if (flag &AT_SYMLINK_NOFOLLOW ) + error =vfs_lstat_fd (dfd, filename, &stat); +else + error =vfs_stat_fd (dfd, filename, &stat);if (!error) error =cp_compat_stat (&stat, statbuf); + +out:return error; }
@@ -1276,7 +1302,17 @@ out:asmlinkage long compat_sys_open (const char __user *filename,int flags,int mode) { -return do_sys_open (filename, flags, mode); +return do_sys_open (AT_FDCWD , filename, flags, mode); +} + +/* +* Exactly like fs/open.c:sys_openat(), except that it doesn't set the +* O_LARGEFILE flag. +*/ +asmlinkage long +compat_sys_openat (int dfd,const char __user *filename,int flags,int mode) +{ +return do_sys_open (dfd, filename, flags, mode); }/*
fs/exec.c +1 -1
@@ -477,7 +477,7 @@ struct file *open_exec(const char *name)int err;struct file *file; - err =path_lookup_open (name,LOOKUP_FOLLOW , &nd,FMODE_READ ); + err =path_lookup_open (AT_FDCWD , name,LOOKUP_FOLLOW , &nd,FMODE_READ ); file =ERR_PTR (err);if (!err) {
fs/namei.c +131 -36
406 lines not on this page · raw message
fs/open.c +51 -9
133 lines not on this page · raw message
fs/stat.c +44 -10
128 lines not on this page · raw message
include/linux/fcntl.h +7 -0
@@ -23,6 +23,13 @@#define DN_ATTRIB 0x00000020/* File changed attibutes */ #define DN_MULTISHOT 0x80000000/* Don't remove notifier */ +#define AT_FDCWD -100/* Special value used to indicate +openat should use the current +working directory. */ +#define AT_SYMLINK_NOFOLLOW 0x100/* Do not follow symbolic links. */ +#define AT_REMOVEDIR 0x200/* Remove directory instead of +unlinking file. */ +#ifdef __KERNEL__#ifndef force_o_largefile
include/linux/fs.h +5 -2
@@ -1314,7 +1314,8 @@ static inline int break_lease(struct ino/* fs/open.c */ extern int do_truncate (struct dentry *,loff_t start,struct file *filp); -extern long do_sys_open (const char __user *filename,int flags,int mode); +extern long do_sys_open (int fdf,const char __user *filename,int flags, +int mode);extern struct file *filp_open (const char *,int ,int );extern struct file *dentry_open (struct dentry *,struct vfsmount *,int );extern int filp_close (struct file *,fl_owner_t id);
@@ -1442,7 +1443,7 @@ static inline void allow_write_access(st }extern int do_pipe (int *); -extern int open_namei (const char *,int ,int ,struct nameidata *); +extern int open_namei (int dfd,const char *,int ,int ,struct nameidata *);extern int may_open (struct nameidata *,int ,int );extern int kernel_read (struct file *,unsigned long ,char *,unsigned long );
@@ -1640,6 +1641,8 @@ extern int vfs_readdir(struct file *, fiextern int vfs_stat (char __user *,struct kstat *);extern int vfs_lstat (char __user *,struct kstat *); +extern int vfs_stat_fd (int dfd,char __user *,struct kstat *); +extern int vfs_lstat_fd (int dfd,char __user *,struct kstat *);extern int vfs_fstat (unsigned int ,struct kstat *);extern int vfs_ioctl (struct file *,unsigned int ,unsigned int ,unsigned long );
include/linux/namei.h +4 -3
@@ -56,10 +56,11 @@ enum {LAST_NORM, LAST_ROOT, LAST_DOT, LA#define LOOKUP_ACCESS (0x0400)extern int FASTCALL (__user_walk (const char __user *,unsigned ,struct nameidata *)); +extern int FASTCALL (__user_walk_fd (int dfd,const char __user *,unsigned ,struct nameidata *));#define user_path_walk (name,nd) \ - __user_walk(name, LOOKUP_FOLLOW, nd) + __user_walk_fd(AT_FDCWD, name, LOOKUP_FOLLOW, nd)#define user_path_walk_link (name,nd) \ - __user_walk(name, 0, nd) + __user_walk_fd(AT_FDCWD, name, 0, nd)extern int FASTCALL (path_lookup (const char *,unsigned ,struct nameidata *));extern int FASTCALL (path_walk (const char *,struct nameidata *));extern int FASTCALL (link_path_walk (const char *,struct nameidata *));
@@ -67,7 +68,7 @@ extern void path_release(struct nameidatextern void path_release_on_umount (struct nameidata *);extern int __user_path_lookup_open (const char __user *,unsigned lookup_flags,struct nameidata *nd,int open_flags); -extern int path_lookup_open (const char *,unsigned lookup_flags,struct nameidata *,int open_flags); +extern int path_lookup_open (int dfd,const char *name,unsigned lookup_flags,struct nameidata *,int open_flags);extern struct file *lookup_instantiate_filp (struct nameidata *nd,struct dentry *dentry,int (*open)(struct inode *,struct file *));extern struct file *nameidata_to_filp (struct nameidata *nd,int flags);
include/linux/time.h +1 -1
@@ -90,7 +90,7 @@ extern int do_settimeofday(struct timespextern int do_sys_settimeofday (struct timespec *tv,struct timezone *tz);extern void clock_was_set (void );// call when ever the clock is set extern int do_posix_clock_monotonic_gettime (struct timespec *tp); -extern long do_utimes (char __user * filename,struct timeval * times); +extern long do_utimes (int dfd,char __user * filename,struct timeval * times);struct itimerval ;extern int do_setitimer (int which,struct itimerval *value,struct itimerval *ovalue);extern int do_getitimer (int which,struct itimerval *value);