DragonFly submit List (threaded) for 2009-07
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]
openat(2)
Hello,
I'm implementing the openat(2) system call. Here is a patch
containing the kernel-side part. If there is no objection, I'll
commit it in a couple of days alongside the userland wrappers and man
page.
Cheers,
Nicolas
diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c
index 20b33f6..d66ef2f 100644
--- a/sys/kern/init_sysent.c
+++ b/sys/kern/init_sysent.c
@@ -537,4 +537,5 @@ struct sysent sysent[] = {
{ AS(fstatvfs_args), (sy_call_t *)sys_fstatvfs }, /* 501
= fstatvfs */
{ AS(fhstatvfs_args), (sy_call_t *)sys_fhstatvfs }, /* 502
= fhstatvfs */
{ AS(getvfsstat_args), (sy_call_t *)sys_getvfsstat }, /* 503
= getvfsstat */
+ { AS(openat_args), (sy_call_t *)sys_openat }, /* 504 = openat */
};
diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c
index 817e44b..5664413 100644
--- a/sys/kern/syscalls.c
+++ b/sys/kern/syscalls.c
@@ -511,4 +511,5 @@ char *syscallnames[] = {
"fstatvfs", /* 501 = fstatvfs */
"fhstatvfs", /* 502 = fhstatvfs */
"getvfsstat", /* 503 = getvfsstat */
+ "openat", /* 504 = openat */
};
diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master
index 3b2672e..8527373 100644
--- a/sys/kern/syscalls.master
+++ b/sys/kern/syscalls.master
@@ -688,3 +688,7 @@
502 STD BSD { int fhstatvfs(const struct fhandle *u_fhp, struct
statvfs *buf); }
503 STD BSD { int getvfsstat(struct statfs *buf, \
struct statvfs *vbuf, long vbufsize, int flags); }
+504 STD BSD { int openat(int fd, char *path, int flags, int mode); }
+; XXX should be { int openat(int fd, const char *path,
int flags, ...);}
+; but we're not ready for `const' or varargs.
+; XXX man page says `mode_t mode'.
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 27b766c..8a87f33 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1837,6 +1837,48 @@ sys_open(struct open_args *uap)
return (error);
}
+/*
+ * openat_args(int fd, char *path, int flags, int mode)
+ */
+int
+sys_openat(struct openat_args *uap)
+{
+ struct thread *td = curthread;
+ struct proc *p = td->td_proc;
+ struct file* fp = NULL;
+ struct vnode *vp;
+ struct nlookupdata nd;
+ int error;
+
+ error = nlookup_init(&nd, uap->path, UIO_USERSPACE, 0);
+ if (error != 0)
+ goto cleanup;
+
+ if (nd.nl_path[0] != '/' && uap->fd != AT_FDCWD) {
+ /*
+ * Use dir pointed to by fd as lookup starting point instead
+ * of current dir.
+ */
+ if ((error = holdvnode(p->p_fd, uap->fd, &fp)) != 0)
+ goto cleanup;
+ vp = (struct vnode*)fp->f_data;
+ if (vp->v_type != VDIR || fp->f_nchandle.ncp == NULL) {
+ error = ENOTDIR;
+ goto cleanup;
+ }
+ cache_drop(&nd.nl_nch);
+ cache_copy(&fp->f_nchandle, &nd.nl_nch);
+ }
+
+ error = kern_open(&nd, uap->flags, uap->mode, &uap->sysmsg_result);
+
+cleanup:
+ if (fp != NULL)
+ fdrop(fp);
+ nlookup_done(&nd);
+ return (error);
+}
+
int
kern_mknod(struct nlookupdata *nd, int mode, int rmajor, int rminor)
{
diff --git a/sys/sys/fcntl.h b/sys/sys/fcntl.h
index 7593dbb..df1db82 100644
--- a/sys/sys/fcntl.h
+++ b/sys/sys/fcntl.h
@@ -197,6 +197,8 @@
#define F_NOEND 0x080 /* l_len = 0, internally used */
#endif
+#define AT_FDCWD 0xFFFAFDCD /* see openat(2) */
+
/*
* Advisory file segment locking data type -
* information passed to system by user
@@ -233,6 +235,7 @@ union fcntl_dat {
__BEGIN_DECLS
int open (const char *, int, ...);
+int openat (int, const char *, int, ...);
int creat (const char *, mode_t);
int fcntl (int, int, ...);
#ifndef _POSIX_SOURCE
diff --git a/sys/sys/syscall-hide.h b/sys/sys/syscall-hide.h
index 0e57ae0..6ef21fc 100644
--- a/sys/sys/syscall-hide.h
+++ b/sys/sys/syscall-hide.h
@@ -334,3 +334,4 @@ HIDE_BSD(statvfs)
HIDE_BSD(fstatvfs)
HIDE_BSD(fhstatvfs)
HIDE_BSD(getvfsstat)
+HIDE_BSD(openat)
diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h
index 38f0fc1..3f5d863 100644
--- a/sys/sys/syscall.h
+++ b/sys/sys/syscall.h
@@ -345,4 +345,5 @@
#define SYS_fstatvfs 501
#define SYS_fhstatvfs 502
#define SYS_getvfsstat 503
-#define SYS_MAXSYSCALL 504
+#define SYS_openat 504
+#define SYS_MAXSYSCALL 505
diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk
index c1598a8..4fa37c8 100644
--- a/sys/sys/syscall.mk
+++ b/sys/sys/syscall.mk
@@ -285,4 +285,5 @@ MIASM = \
statvfs.o \
fstatvfs.o \
fhstatvfs.o \
- getvfsstat.o
+ getvfsstat.o \
+ openat.o
diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h
index 6d72e28..7395548 100644
--- a/sys/sys/sysproto.h
+++ b/sys/sys/sysproto.h
@@ -2159,6 +2159,15 @@ struct getvfsstat_args {
long vbufsize; char vbufsize_[PAD_(long)];
int flags; char flags_[PAD_(int)];
};
+struct openat_args {
+#ifdef _KERNEL
+ struct sysmsg sysmsg;
+#endif
+ int fd; char fd_[PAD_(int)];
+ char * path; char path_[PAD_(char *)];
+ int flags; char flags_[PAD_(int)];
+ int mode; char mode_[PAD_(int)];
+};
#ifdef COMPAT_43
@@ -2745,6 +2754,7 @@ int sys_statvfs (struct statvfs_args *);
int sys_fstatvfs (struct fstatvfs_args *);
int sys_fhstatvfs (struct fhstatvfs_args *);
int sys_getvfsstat (struct getvfsstat_args *);
+int sys_openat (struct openat_args *);
#endif /* !_SYS_SYSPROTO_H_ */
#undef PAD_
diff --git a/sys/sys/sysunion.h b/sys/sys/sysunion.h
index 2aaa1d8..fe50bbd 100644
--- a/sys/sys/sysunion.h
+++ b/sys/sys/sysunion.h
@@ -390,4 +390,5 @@ union sysunion {
struct fstatvfs_args fstatvfs;
struct fhstatvfs_args fhstatvfs;
struct getvfsstat_args getvfsstat;
+ struct openat_args openat;
};
[
Date Prev][
Date Next]
[
Thread Prev][
Thread Next]
[
Date Index][
Thread Index]