[patch 05/22] pollfs: pollable signal compat code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Compat handlers for the pollable signal operations. Later the0 compat operations
can operate on a per call basis.

Signed-off-by: Davi E. M. Arnaut <[email protected]>

---
 fs/pollfs/signal.c |   85 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 85 insertions(+)

Index: linux-2.6/fs/pollfs/signal.c
===================================================================
--- linux-2.6.orig/fs/pollfs/signal.c
+++ linux-2.6/fs/pollfs/signal.c
@@ -16,6 +16,7 @@
 #include <linux/poll.h>
 #include <linux/pollfs_fs.h>
 #include <linux/signal.h>
+#include <linux/compat.h>
 
 struct pfs_signal {
 	sigset_t set;
@@ -48,6 +49,24 @@ static ssize_t read(struct pfs_signal *e
 	return 0;
 }
 
+#ifdef CONFIG_COMPAT
+static ssize_t compat_read(struct pfs_signal *evs,
+			   struct compat_siginfo __user *infoup)
+{
+	int signo;
+	siginfo_t info;
+
+	signo = dequeue_signal_lock(evs->task, &evs->set, &info);
+	if (!signo)
+		return -EAGAIN;
+
+	if (copy_siginfo_to_user32(infoup, &info))
+		return -EFAULT;
+
+	return 0;
+}
+#endif
+
 static ssize_t write(struct pfs_signal *evs, const sigset_t __user *uset)
 {
 	sigset_t set;
@@ -65,6 +84,28 @@ static ssize_t write(struct pfs_signal *
 	return 0;
 }
 
+#ifdef CONFIG_COMPAT
+static ssize_t compat_write(struct pfs_signal *evs,
+			    const compat_sigset_t __user *uset)
+{
+	sigset_t set;
+	compat_sigset_t cset;
+
+	if (copy_from_user(&cset, uset, sizeof(compat_sigset_t)))
+		return -EFAULT;
+
+	sigset_from_compat(&set, &cset);
+	sigset_adjust(&set);
+
+	spin_lock_irq(&evs->lock);
+	sigemptyset(&evs->set);
+	sigorsets(&evs->set, &evs->set, &set);
+	spin_unlock_irq(&evs->lock);
+
+	return 0;
+}
+#endif
+
 static int poll(struct pfs_signal *evs)
 {
 	int ret = 0;
@@ -142,3 +183,47 @@ asmlinkage long sys_plsignal(const sigse
 
 	return error;
 }
+
+#ifdef CONFIG_COMPAT
+static const struct pfs_operations compat_signal_ops = {
+	/* .read        = PFS_READ(compat_read, struct pfs_signal, struct compat_siginfo), */
+	.write		= PFS_WRITE(compat_write, struct pfs_signal, compat_sigset_t),
+	.poll		= PFS_POLL(poll, struct pfs_signal),
+	.release	= PFS_RELEASE(release, struct pfs_signal),
+	/* .rsize       = sizeof(compat_siginfo_t), */
+	.wsize		= sizeof(sigset_t)
+};
+
+asmlinkage long compat_plsignal(const compat_sigset_t __user *uset)
+{
+	long error;
+	compat_sigset_t cset;
+	struct pfs_signal *evs;
+
+	if (copy_from_user(&cset, uset, sizeof(compat_sigset_t)))
+		return -EFAULT;
+
+	evs = kmalloc(sizeof(*evs), GFP_KERNEL);
+	if (!evs)
+		return -ENOMEM;
+
+	spin_lock_init(&evs->lock);
+
+	evs->task = current;
+	get_task_struct(current);
+
+	sigset_from_compat(&evs->set, &cset);
+	sigset_adjust(&evs->set);
+
+	evs->file.data = evs;
+	evs->file.fops = &compat_signal_ops;
+	evs->file.wait = &evs->task->sigwait;
+
+	error = pfs_open(&evs->file);
+
+	if (error < 0)
+		release(evs);
+
+	return error;
+}
+#endif

--
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux