All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ulrich Drepper <drepper@redhat.com>
To: linux-kernel@vger.kernel.org
Cc: akpm@linux-foundation.org, davidel@xmailserver.org,
	torvalds@linux-foundation.org
Subject: [PATCH v2] eventfd, signalfd, timerfd, epoll_create w/flags
Date: Sun, 27 Apr 2008 23:15:20 -0400	[thread overview]
Message-ID: <200804280315.m3S3FKsw028335@devserv.devel.redhat.com> (raw)

This is the same patch with only epoll_create2 as the new syscall name,
as per Davide's request.

Again, it applies on top of the socket patch.
 

 arch/x86/ia32/ia32entry.S          |    3 +++
 arch/x86/kernel/syscall_table_32.S |    3 +++
 b/include/asm-x86/unistd_64.h      |    6 ++++++
 b/include/linux/syscalls.h         |    3 +++
 fs/anon_inodes.c                   |    9 +++++----
 fs/compat.c                        |   14 ++++++++++----
 fs/eventfd.c                       |   19 +++++++++++++++++--
 fs/eventpoll.c                     |   19 +++++++++++++++++--
 fs/signalfd.c                      |   19 +++++++++++++++++--
 fs/timerfd.c                       |   13 ++++++++++---
 include/asm-x86/unistd_32.h        |    3 +++
 include/linux/anon_inodes.h        |    2 +-
 include/linux/eventfd.h            |    2 ++
 include/linux/eventpoll.h          |    2 ++
 include/linux/signalfd.h           |    3 +++
 include/linux/timerfd.h            |    4 +++-
 16 files changed, 105 insertions(+), 19 deletions(-)


Signed-off-by: Ulrich Drepper <drepper@redhat.com>

diff -u b/include/asm-x86/unistd_64.h b/include/asm-x86/unistd_64.h
--- b/include/asm-x86/unistd_64.h
+++ b/include/asm-x86/unistd_64.h
@@ -641,6 +641,12 @@
 __SYSCALL(__NR_timerfd_gettime, sys_timerfd_gettime)
 #define __NR_paccept				288
 __SYSCALL(__NR_paccept, sys_paccept)
+#define __NR_signalfd4				289
+__SYSCALL(__NR_signalfd4, sys_signalfd4)
+#define __NR_eventfd2				290
+__SYSCALL(__NR_eventfd2, sys_eventfd2)
+#define __NR_epoll_create2			291
+__SYSCALL(__NR_epoll_create2, sys_epoll_create2)
 
 
 #ifndef __NO_STUBS
diff -u b/include/linux/syscalls.h b/include/linux/syscalls.h
--- b/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -428,6 +428,7 @@
 asmlinkage long sys_select(int n, fd_set __user *inp, fd_set __user *outp,
 			fd_set __user *exp, struct timeval __user *tvp);
 asmlinkage long sys_epoll_create(int size);
+asmlinkage long sys_epoll_create2(int size, int flags);
 asmlinkage long sys_epoll_ctl(int epfd, int op, int fd,
 				struct epoll_event __user *event);
 asmlinkage long sys_epoll_wait(int epfd, struct epoll_event __user *events,
@@ -608,12 +609,14 @@
 				    size_t len);
 asmlinkage long sys_getcpu(unsigned __user *cpu, unsigned __user *node, struct getcpu_cache __user *cache);
 asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask);
+asmlinkage long sys_signalfd4(int ufd, sigset_t __user *user_mask, size_t sizemask, int flags);
 asmlinkage long sys_timerfd_create(int clockid, int flags);
 asmlinkage long sys_timerfd_settime(int ufd, int flags,
 				    const struct itimerspec __user *utmr,
 				    struct itimerspec __user *otmr);
 asmlinkage long sys_timerfd_gettime(int ufd, struct itimerspec __user *otmr);
 asmlinkage long sys_eventfd(unsigned int count);
+asmlinkage long sys_eventfd2(unsigned int count, int flags);
 asmlinkage long sys_fallocate(int fd, int mode, loff_t offset, loff_t len);
 
 int kernel_execve(const char *filename, char *const argv[], char *const envp[]);
--- a/arch/x86/ia32/ia32entry.S
+++ b/arch/x86/ia32/ia32entry.S
@@ -731,4 +731,7 @@ ia32_sys_call_table:
 	.quad sys32_fallocate
 	.quad compat_sys_timerfd_settime	/* 325 */
 	.quad compat_sys_timerfd_gettime
+	.quad compat_sys_signalfd4
+	.quad sys_eventfd2
+	.quad sys_epoll_create2
 ia32_syscall_end:
--- a/arch/x86/kernel/syscall_table_32.S
+++ b/arch/x86/kernel/syscall_table_32.S
@@ -326,3 +326,6 @@ ENTRY(sys_call_table)
 	.long sys_fallocate
 	.long sys_timerfd_settime	/* 325 */
 	.long sys_timerfd_gettime
+	.long sys_signalfd4
+	.long sys_eventfd2
+	.long sys_epoll_create2
--- a/fs/anon_inodes.c
+++ b/fs/anon_inodes.c
@@ -61,8 +61,9 @@ static struct dentry_operations anon_inodefs_dentry_operations = {
  * @dpinode: [out]   pointer to the inode
  * @pfile:   [out]   pointer to the file struct
  * @name:    [in]    name of the "class" of the new file
- * @fops     [in]    file operations for the new file
- * @priv     [in]    private data for the new file (will be file's private_data)
+ * @fops:    [in]    file operations for the new file
+ * @priv:    [in]    private data for the new file (will be file's private_data)
+ * @flags:   [in]    flags
  *
  * Creates a new file by hooking it on a single inode. This is useful for files
  * that do not need to have a full-fledged inode in order to operate correctly.
@@ -72,7 +73,7 @@ static struct dentry_operations anon_inodefs_dentry_operations = {
  */
 int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
 		     const char *name, const struct file_operations *fops,
-		     void *priv)
+		     void *priv, int flags)
 {
 	struct qstr this;
 	struct dentry *dentry;
@@ -82,7 +83,7 @@ int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
 	if (IS_ERR(anon_inode_inode))
 		return -ENODEV;
 
-	error = get_unused_fd();
+	error = get_unused_fd_flags(flags);
 	if (error < 0)
 		return error;
 	fd = error;
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -2130,9 +2130,9 @@ asmlinkage long compat_sys_epoll_pwait(int epfd,
 
 #ifdef CONFIG_SIGNALFD
 
-asmlinkage long compat_sys_signalfd(int ufd,
-				    const compat_sigset_t __user *sigmask,
-				    compat_size_t sigsetsize)
+asmlinkage long compat_sys_signalfd4(int ufd,
+				     const compat_sigset_t __user *sigmask,
+				     compat_size_t sigsetsize, int flags)
 {
 	compat_sigset_t ss32;
 	sigset_t tmp;
@@ -2147,9 +2147,15 @@ asmlinkage long compat_sys_signalfd(int ufd,
 	if (copy_to_user(ksigmask, &tmp, sizeof(sigset_t)))
 		return -EFAULT;
 
-	return sys_signalfd(ufd, ksigmask, sizeof(sigset_t));
+	return sys_signalfd(ufd, ksigmask, sizeof(sigset_t), flags);
 }
 
+asmlinkage long compat_sys_signalfd(int ufd,
+				    const compat_sigset_t __user *sigmask,
+				    compat_size_t sigsetsize)
+{
+	return compat_sys_signalfd4(ufd, sigmask, sigsetsize, 0);
+}
 #endif /* CONFIG_SIGNALFD */
 
 #ifdef CONFIG_TIMERFD
--- a/fs/eventfd.c
+++ b/fs/eventfd.c
@@ -198,12 +198,22 @@ struct file *eventfd_fget(int fd)
 	return file;
 }
 
-asmlinkage long sys_eventfd(unsigned int count)
+asmlinkage long sys_eventfd2(unsigned int count, int flags)
 {
 	int error, fd;
 	struct eventfd_ctx *ctx;
 	struct file *file;
 	struct inode *inode;
+	int fflags = 0;
+
+	if (flags) {
+		if ((flags & EFD_CLOEXEC) != 0) {
+			fflags |= O_CLOEXEC;
+			flags &= ~EFD_CLOEXEC;
+		}
+		if (flags)
+			return -EINVAL;
+	}
 
 	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
 	if (!ctx)
@@ -217,7 +227,7 @@ asmlinkage long sys_eventfd(unsigned int count)
 	 * anon_inode_getfd() will install the fd.
 	 */
 	error = anon_inode_getfd(&fd, &inode, &file, "[eventfd]",
-				 &eventfd_fops, ctx);
+				 &eventfd_fops, ctx, fflags);
 	if (!error)
 		return fd;
 
@@ -225,3 +235,8 @@ asmlinkage long sys_eventfd(unsigned int count)
 	return error;
 }
 
+asmlinkage long sys_eventfd(unsigned int count)
+{
+	return sys_eventfd2(count, 0);
+}
+
--- a/fs/eventpoll.c
+++ b/fs/eventpoll.c
@@ -1067,12 +1067,22 @@ retry:
  * RB tree. With the current implementation, the "size" parameter is ignored
  * (besides sanity checks).
  */
-asmlinkage long sys_epoll_create(int size)
+asmlinkage long sys_epoll_create2(int size, int flags)
 {
 	int error, fd = -1;
 	struct eventpoll *ep;
 	struct inode *inode;
 	struct file *file;
+	int fflags = 0;
+
+	if (flags) {
+		if ((flags & EPOLL_CLOEXEC) != 0) {
+			fflags |= O_CLOEXEC;
+			flags &= ~EPOLL_CLOEXEC;
+		}
+		if (flags)
+			return -EINVAL;
+	}
 
 	DNPRINTK(3, (KERN_INFO "[%p] eventpoll: sys_epoll_create(%d)\n",
 		     current, size));
@@ -1090,7 +1100,7 @@ asmlinkage long sys_epoll_create(int size)
 	 * a file structure, and inode and a free file descriptor.
 	 */
 	error = anon_inode_getfd(&fd, &inode, &file, "[eventpoll]",
-				 &eventpoll_fops, ep);
+				 &eventpoll_fops, ep, fflags);
 	if (error)
 		goto error_free;
 
@@ -1107,6 +1117,11 @@ error_return:
 	return error;
 }
 
+asmlinkage long sys_epoll_create(int size)
+{
+	return sys_epoll_create2(size, 0);
+}
+
 /*
  * The following function implements the controller interface for
  * the eventpoll file that enables the insertion/removal/change of
--- a/fs/signalfd.c
+++ b/fs/signalfd.c
@@ -205,13 +205,24 @@ static const struct file_operations signalfd_fops = {
 	.read		= signalfd_read,
 };
 
-asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask)
+asmlinkage long sys_signalfd4(int ufd, sigset_t __user *user_mask,
+			      size_t sizemask, int flags)
 {
 	int error;
 	sigset_t sigmask;
 	struct signalfd_ctx *ctx;
 	struct file *file;
 	struct inode *inode;
+	int fflags = 0;
+
+	if (flags) {
+		if ((flags & SFD_CLOEXEC) != 0 && ufd == -1) {
+			fflags |= O_CLOEXEC;
+			flags &= ~SFD_CLOEXEC;
+		}
+		if (flags)
+			return -EINVAL;
+	}
 
 	if (sizemask != sizeof(sigset_t) ||
 	    copy_from_user(&sigmask, user_mask, sizeof(sigmask)))
@@ -231,7 +242,7 @@ asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemas
 		 * anon_inode_getfd() will install the fd.
 		 */
 		error = anon_inode_getfd(&ufd, &inode, &file, "[signalfd]",
-					 &signalfd_fops, ctx);
+					 &signalfd_fops, ctx, fflags);
 		if (error)
 			goto err_fdalloc;
 	} else {
@@ -258,3 +269,7 @@ err_fdalloc:
 	return error;
 }
 
+asmlinkage long sys_signalfd(int ufd, sigset_t __user *user_mask, size_t sizemask)
+{
+	return sys_signalfd4(ufd, user_mask, sizemask, 0);
+}
--- a/fs/timerfd.c
+++ b/fs/timerfd.c
@@ -184,9 +184,16 @@ asmlinkage long sys_timerfd_create(int clockid, int flags)
 	struct timerfd_ctx *ctx;
 	struct file *file;
 	struct inode *inode;
+	int fflags = 0;
 
-	if (flags)
-		return -EINVAL;
+	if (flags) {
+		if ((flags & TFD_CLOEXEC) != 0) {
+			fflags |= O_CLOEXEC;
+			flags &= ~TFD_CLOEXEC;
+		}
+		if (flags)
+			return -EINVAL;
+	}
 	if (clockid != CLOCK_MONOTONIC &&
 	    clockid != CLOCK_REALTIME)
 		return -EINVAL;
@@ -200,7 +207,7 @@ asmlinkage long sys_timerfd_create(int clockid, int flags)
 	hrtimer_init(&ctx->tmr, clockid, HRTIMER_MODE_ABS);
 
 	error = anon_inode_getfd(&ufd, &inode, &file, "[timerfd]",
-				 &timerfd_fops, ctx);
+				 &timerfd_fops, ctx, fflags);
 	if (error) {
 		kfree(ctx);
 		return error;
--- a/include/asm-x86/unistd_32.h
+++ b/include/asm-x86/unistd_32.h
@@ -332,6 +332,9 @@
 #define __NR_fallocate		324
 #define __NR_timerfd_settime	325
 #define __NR_timerfd_gettime	326
+#define __NR_signalfd4		327
+#define __NR_eventfd2		328
+#define __NR_epoll_create2	329
 
 #ifdef __KERNEL__
 
--- a/include/linux/anon_inodes.h
+++ b/include/linux/anon_inodes.h
@@ -10,7 +10,7 @@
 
 int anon_inode_getfd(int *pfd, struct inode **pinode, struct file **pfile,
 		     const char *name, const struct file_operations *fops,
-		     void *priv);
+		     void *priv, int flags);
 
 #endif /* _LINUX_ANON_INODES_H */
 
--- a/include/linux/eventfd.h
+++ b/include/linux/eventfd.h
@@ -8,6 +8,8 @@
 #ifndef _LINUX_EVENTFD_H
 #define _LINUX_EVENTFD_H
 
+/* Flags for eventfd2.  */
+#define EFD_CLOEXEC (1 << 0)
 
 #ifdef __KERNEL__
 
--- a/include/linux/eventpoll.h
+++ b/include/linux/eventpoll.h
@@ -16,6 +16,8 @@
 
 #include <linux/types.h>
 
+/* Flags for epoll_create2.  */
+#define EPOLL_CLOEXEC (1 << 0)
 
 /* Valid opcodes to issue to sys_epoll_ctl() */
 #define EPOLL_CTL_ADD 1
--- a/include/linux/signalfd.h
+++ b/include/linux/signalfd.h
@@ -9,6 +9,9 @@
 #define _LINUX_SIGNALFD_H
 
 
+/* Flags for signalfd4.  */
+#define SFD_CLOEXEC (1 << 0)
+
 struct signalfd_siginfo {
 	__u32 ssi_signo;
 	__s32 ssi_errno;
--- a/include/linux/timerfd.h
+++ b/include/linux/timerfd.h
@@ -8,9 +8,11 @@
 #ifndef _LINUX_TIMERFD_H
 #define _LINUX_TIMERFD_H
 
-
+/* Flags for timerfd_settime.  */
 #define TFD_TIMER_ABSTIME (1 << 0)
 
+/* Flags for timerfd_create.  */
+#define TFD_CLOEXEC (1 << 0)
 
 
 #endif /* _LINUX_TIMERFD_H */

             reply	other threads:[~2008-04-28  3:15 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-04-28  3:15 Ulrich Drepper [this message]
2008-04-28  5:11 ` [PATCH v2] eventfd, signalfd, timerfd, epoll_create w/flags Davide Libenzi
2008-04-28  5:43   ` Ulrich Drepper
2008-04-28  6:06     ` Davide Libenzi

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200804280315.m3S3FKsw028335@devserv.devel.redhat.com \
    --to=drepper@redhat.com \
    --cc=akpm@linux-foundation.org \
    --cc=davidel@xmailserver.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.