Bug #1435

openat(2)

Added by nthery over 5 years ago. Updated over 5 years ago.

Status:ClosedStart date:
Priority:NormalDue date:
Assignee:-% Done:

0%

Category:-
Target version:-

Description

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;
};

History

#1 Updated by dillon over 5 years ago

: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

Hmm. The linux folks came up with something interesting. I like the
concept, go for it.

There is a whole category of 'at' system calls that could be added.

-Matt

#2 Updated by joerg over 5 years ago

On Wed, Jul 22, 2009 at 03:51:19PM -0700, Matthew Dillon wrote:
> Hmm. The linux folks came up with something interesting. I like the
> concept, go for it.

Just for the archive, I think it was Sun :)

Joerg

#3 Updated by dillon over 5 years ago

:On Wed, Jul 22, 2009 at 03:51:19PM -0700, Matthew Dillon wrote:
:> Hmm. The linux folks came up with something interesting. I like the
:> concept, go for it.
:
:Just for the archive, I think it was Sun :)
:
:Joerg

Ok, we'll give Sun the kudos :-). It is a good idea.

-Matt
Matthew Dillon
<>

#4 Updated by nthery over 5 years ago

2009/7/23 Matthew Dillon <>:

> Hmm. The linux folks came up with something interesting. I like the
> concept, go for it.

Okay. Thanks.

> There is a whole category of 'at' system calls that could be added.

They're in my todo list. :-)

I think there's a bug in the patch I emailed: Shouldn't I vget() the
vnode of the fd passed to openat() to prevent races?

#5 Updated by dillon over 5 years ago

:They're in my todo list. :-)
:
:I think there's a bug in the patch I emailed: Shouldn't I vget() the
:vnode of the fd passed to openat() to prevent races?

No, I don't think you need to. The call to holdvnode() refs the fp
and that prevents fp->f_nchandle from being ripped out from under you.
You aren't actually using the vnode pointer. The nlookup code
does via the nchandle, but it handles its own refs.

-Matt
Matthew Dillon
<>

#6 Updated by hasso over 5 years ago

Matthew Dillon wrote:
> Hmm. The linux folks came up with something interesting. I like
> the concept, go for it.
>
> There is a whole category of 'at' system calls that could be added.

These 'at' system calls are POSIX.1 nowadays:

http://www.opengroup.org/onlinepubs/9699919799/functions/open.html
http://www.opengroup.org/onlinepubs/9699919799/functions/chmod.html
http://www.opengroup.org/onlinepubs/9699919799/functions/mknod.html
etc

#7 Updated by nthery over 5 years ago

2009/7/25 Hasso Tepper (via DragonFly issue tracker)
<>:
> These 'at' system calls are POSIX.1 nowadays:
>
> http://www.opengroup.org/onlinepubs/9699919799/functions/open.html
> http://www.opengroup.org/onlinepubs/9699919799/functions/chmod.html
> http://www.opengroup.org/onlinepubs/9699919799/functions/mknod.html

Thanks for the links. I discovered while stealing the man page from
FreeBSD a mention of fd opened for searching but I didn't understand
what that meant. Now this is clearer. I'll try to implement O_SEARCH
to be compliant.

#8 Updated by nthery over 5 years ago

Committed to master.

Also available in: Atom PDF