Module: xenomai-forge
Branch: next
Commit: 34c910496be0ad61285e70bd1a241f1e8ba8315d
URL:    
http://git.xenomai.org/?p=xenomai-forge.git;a=commit;h=34c910496be0ad61285e70bd1a241f1e8ba8315d

Author: Philippe Gerum <r...@xenomai.org>
Date:   Tue Sep  9 16:11:03 2014 +0200

cobalt/rtdm, lib/cobalt: alloc file descriptors on the anon inode

---

 include/cobalt/kernel/rtdm/fd.h |    3 ++
 kernel/cobalt/posix/io.c        |   82 ++++++++++++++++++++++++++++++++++-----
 kernel/cobalt/posix/io.h        |    4 +-
 kernel/cobalt/rtdm/core.c       |   11 +++---
 lib/cobalt/rtdm.c               |   51 ++++++++++--------------
 5 files changed, 104 insertions(+), 47 deletions(-)

diff --git a/include/cobalt/kernel/rtdm/fd.h b/include/cobalt/kernel/rtdm/fd.h
index 3fe353a..815ef5d 100644
--- a/include/cobalt/kernel/rtdm/fd.h
+++ b/include/cobalt/kernel/rtdm/fd.h
@@ -22,6 +22,7 @@
 
 #include <linux/types.h>
 #include <linux/socket.h>
+#include <linux/file.h>
 #include <cobalt/kernel/tree.h>
 
 struct vm_area_struct;
@@ -352,4 +353,6 @@ void rtdm_fd_cleanup(struct xnsys_ppd *p);
 
 void rtdm_fd_init(void);
 
+extern const struct file_operations rtdm_dumb_fops;
+
 #endif /* _COBALT_KERNEL_FD_H */
diff --git a/kernel/cobalt/posix/io.c b/kernel/cobalt/posix/io.c
index 891d28d..bafc5e2 100644
--- a/kernel/cobalt/posix/io.c
+++ b/kernel/cobalt/posix/io.c
@@ -18,6 +18,11 @@
  * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  */
 #include <linux/err.h>
+#include <linux/file.h>
+#include <linux/fs.h>
+#include <linux/poll.h>
+#include <linux/fdtable.h>
+#include <linux/anon_inodes.h>
 #include <cobalt/kernel/ppd.h>
 #include <xenomai/rtdm/internal.h>
 #include "process.h"
@@ -25,26 +30,85 @@
 #include "clock.h"
 #include "io.h"
 
+static inline void warn_user(const char *name)
+{
+#ifdef CONFIG_XENO_OPT_DEBUG_USER
+       printk(XENO_WARN "%s[%d] called regular %s() with RTDM file/socket\n",
+              current->comm, current->pid, name + 5);
+#endif
+}
+
+static ssize_t dumb_read(struct file *file, char  __user *buf,
+                        size_t count, loff_t __user *ppos)
+{
+       warn_user(__func__);
+       return -EINVAL;
+}
+
+static ssize_t dumb_write(struct file *file,  const char __user *buf,
+                         size_t count, loff_t __user *ppos)
+{
+       warn_user(__func__);
+       return -EINVAL;
+}
+
+static unsigned int dumb_poll(struct file *file, poll_table *pt)
+{
+       warn_user(__func__);
+       return -EINVAL;
+}
+
+static long dumb_ioctl(struct file *file, unsigned int cmd,
+                      unsigned long arg)
+{
+       warn_user(__func__);
+       return -EINVAL;
+}
+
+const struct file_operations rtdm_dumb_fops = {
+       .read           = dumb_read,
+       .write          = dumb_write,
+       .poll           = dumb_poll,
+       .unlocked_ioctl = dumb_ioctl,
+};
+
 COBALT_SYSCALL(open, lostage,
-              int, (int fd, const char __user *u_path, int oflag))
+              int, (const char __user *u_path, int oflag))
 {
-       char krnl_path[RTDM_MAX_DEVNAME_LEN + 1];
+       char path[RTDM_MAX_DEVNAME_LEN + 1];
+       struct xnsys_ppd *ppd;
+       int ufd, ret;
 
-       if (unlikely(__xn_safe_strncpy_from_user(krnl_path, u_path,
-                                                sizeof(krnl_path) - 1) < 0))
+       if (__xn_safe_strncpy_from_user(path, u_path, sizeof(path)-1) < 0)
                return -EFAULT;
 
-       krnl_path[sizeof(krnl_path) - 1] = '\0';
+       path[sizeof(path)-1] = '\0';
+       ppd = cobalt_ppd_get(0);
+       ufd = anon_inode_getfd("[rtdm-named]", &rtdm_dumb_fops, ppd, oflag);
+
+       ret = __rt_dev_open(ppd, ufd, path, oflag);
+       if (ret < 0)
+               __close_fd(current->files, ufd);
 
-       return __rt_dev_open(cobalt_ppd_get(0), fd, krnl_path, oflag);
+       return ret;
 }
 
 COBALT_SYSCALL(socket, lostage,
-              int, (int fd, int protocol_family,
+              int, (int protocol_family,
                     int socket_type, int protocol))
 {
-       return __rt_dev_socket(cobalt_ppd_get(0), fd,
-                       protocol_family, socket_type, protocol);
+       struct xnsys_ppd *ppd;
+       int ufd, ret;
+
+       ppd = cobalt_ppd_get(0);
+       ufd = anon_inode_getfd("[rtdm-proto]", &rtdm_dumb_fops, ppd, O_RDWR);
+
+       ret = __rt_dev_socket(cobalt_ppd_get(0), ufd,
+                             protocol_family, socket_type, protocol);
+       if (ret < 0)
+               __close_fd(current->files, ufd);
+
+       return ret;
 }
 
 COBALT_SYSCALL(close, lostage, int, (int fd))
diff --git a/kernel/cobalt/posix/io.h b/kernel/cobalt/posix/io.h
index f8fdc82..9ddbfee 100644
--- a/kernel/cobalt/posix/io.h
+++ b/kernel/cobalt/posix/io.h
@@ -23,10 +23,10 @@
 #include <xenomai/posix/syscall.h>
 
 COBALT_SYSCALL_DECL(open, int,
-                   (int fd, const char __user *u_path, int oflag));
+                   (const char __user *u_path, int oflag));
 
 COBALT_SYSCALL_DECL(socket, int,
-                   (int fd, int protocol_family,
+                   (int protocol_family,
                     int socket_type, int protocol));
 
 COBALT_SYSCALL_DECL(close, int, (int fd));
diff --git a/kernel/cobalt/rtdm/core.c b/kernel/cobalt/rtdm/core.c
index 0793b19..18cf0c6 100644
--- a/kernel/cobalt/rtdm/core.c
+++ b/kernel/cobalt/rtdm/core.c
@@ -147,8 +147,8 @@ fail:
 
 int __rt_dev_open(struct xnsys_ppd *p, int ufd, const char *path, int oflag)
 {
-       struct rtdm_device *device;
        struct rtdm_dev_context *context;
+       struct rtdm_device *device;
        int ret, minor;
 
        /* skip common /dev prefix */
@@ -156,13 +156,13 @@ int __rt_dev_open(struct xnsys_ppd *p, int ufd, const 
char *path, int oflag)
                path += 5;
 
        device = __rtdm_get_named_device(path, &minor);
-       ret = -ENODEV;
-       if (!device)
-               goto err_out;
+       if (device == NULL)
+               return -ENODEV;
 
        ret = create_instance(p, ufd, device, &context);
        if (ret < 0)
                goto cleanup_out;
+
        ufd = ret;
        context->fd.minor = minor;
 
@@ -173,7 +173,7 @@ int __rt_dev_open(struct xnsys_ppd *p, int ufd, const char 
*path, int oflag)
        if (!XENO_ASSERT(COBALT, !spltest()))
                splnone();
 
-       if (unlikely(ret < 0))
+       if (ret < 0)
                goto cleanup_out;
 
        trace_cobalt_fd_created(&context->fd, ufd);
@@ -183,7 +183,6 @@ int __rt_dev_open(struct xnsys_ppd *p, int ufd, const char 
*path, int oflag)
 cleanup_out:
        cleanup_instance(device, context);
 
-err_out:
        return ret;
 }
 EXPORT_SYMBOL_GPL(__rt_dev_open);
diff --git a/lib/cobalt/rtdm.c b/lib/cobalt/rtdm.c
index ee02429..b3310ef 100644
--- a/lib/cobalt/rtdm.c
+++ b/lib/cobalt/rtdm.c
@@ -41,53 +41,44 @@ static inline int set_errno(int ret)
 
 COBALT_IMPL(int, open, (const char *path, int oflag, ...))
 {
-       int ret, fd, oldtype;
+       int fd, oldtype;
        va_list ap;
 
-       fd = __STD(open("/dev/null", O_RDONLY));
-       if (fd < 0)
-               return fd;
        /*
         * Don't dereference path, as it might be invalid. Leave it to
         * the kernel service.
         */
        pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
-       ret = XENOMAI_SYSCALL3( sc_cobalt_open, fd, path, oflag);
+       fd = XENOMAI_SYSCALL2( sc_cobalt_open, path, oflag);
        pthread_setcanceltype(oldtype, NULL);
-       if (ret == fd)
-               return fd;
+       if (fd < 0) {
+               if (fd != -ENODEV && fd != -ENOSYS)
+                       return set_errno(fd);
 
-       __STD(close(fd));
-
-       if (ret != -ENODEV && ret != -ENOSYS)
-               return set_errno(ret);
-
-       va_start(ap, oflag);
-       ret = __STD(open(path, oflag, va_arg(ap, mode_t)));
-       va_end(ap);
+               va_start(ap, oflag);
+               fd = __STD(open(path, oflag, va_arg(ap, mode_t)));
+               va_end(ap);
+       }
 
-       return ret;
+       return fd;
 }
 
 COBALT_IMPL(int, socket, (int protocol_family, int socket_type, int protocol))
 {
-       int ret, fd;
-
-       fd = __STD(open("/dev/null", O_RDONLY));
-       if (fd < 0)
-               return fd;
-
-       ret = XENOMAI_SYSCALL4(sc_cobalt_socket, fd,
-                              protocol_family, socket_type, protocol);
-       if (ret == fd)
-               return fd;
+       int s;
 
-       __STD(close(fd));
+       s = XENOMAI_SYSCALL3(sc_cobalt_socket, protocol_family,
+                            socket_type, protocol);
+       if (s < 0) {
+               if (s != -EAFNOSUPPORT &&
+                   s != -EPROTONOSUPPORT &&
+                   s != -ENOSYS)
+                       return set_errno(s);
 
-       if (ret != -EAFNOSUPPORT && ret != -EPROTONOSUPPORT && ret != -ENOSYS)
-               return set_errno(ret);
+               s = __STD(socket(protocol_family, socket_type, protocol));
+       }
 
-       return __STD(socket(protocol_family, socket_type, protocol));
+       return s;
 }
 
 COBALT_IMPL(int, close, (int fd))


_______________________________________________
Xenomai-git mailing list
Xenomai-git@xenomai.org
http://www.xenomai.org/mailman/listinfo/xenomai-git

Reply via email to