Module: xenomai-gch
Branch: for-forge
Commit: e0220f4672663c6cc14eb463556cce1094111c14
URL:    
http://git.xenomai.org/?p=xenomai-gch.git;a=commit;h=e0220f4672663c6cc14eb463556cce1094111c14

Author: Gilles Chanteperdrix <gilles.chanteperd...@xenomai.org>
Date:   Thu Dec 26 22:23:10 2013 +0100

cobalt/fd: add read/write/ioctl/close syscalls

---

 include/cobalt/uapi/syscall.h |    4 +++
 kernel/cobalt/posix/Makefile  |    1 +
 kernel/cobalt/posix/fdio.c    |   70 +++++++++++++++++++++++++++++++++++++++++
 kernel/cobalt/posix/fdio.h    |   12 +++++++
 kernel/cobalt/posix/syscall.c |    9 ++++++
 lib/cobalt/rtdm.c             |   57 +++++++++++++++++++++++++++------
 6 files changed, 143 insertions(+), 10 deletions(-)

diff --git a/include/cobalt/uapi/syscall.h b/include/cobalt/uapi/syscall.h
index ba7904d..c995895 100644
--- a/include/cobalt/uapi/syscall.h
+++ b/include/cobalt/uapi/syscall.h
@@ -113,5 +113,9 @@
 #define sc_cobalt_event_destroy         92
 #define sc_cobalt_sched_setconfig_np   93
 #define sc_cobalt_sched_getconfig_np   94
+#define sc_cobalt_ioctl                        95
+#define sc_cobalt_read                 96
+#define sc_cobalt_write                        97
+#define sc_cobalt_close                        98
 
 #endif /* !_COBALT_UAPI_SYSCALL_H */
diff --git a/kernel/cobalt/posix/Makefile b/kernel/cobalt/posix/Makefile
index 40c682e..595e737 100644
--- a/kernel/cobalt/posix/Makefile
+++ b/kernel/cobalt/posix/Makefile
@@ -5,6 +5,7 @@ posix-y :=              \
        cond.o          \
        cond_attr.o     \
        event.o         \
+       fdio.o          \
        init.o          \
        monitor.o       \
        mqueue.o        \
diff --git a/kernel/cobalt/posix/fdio.c b/kernel/cobalt/posix/fdio.c
new file mode 100644
index 0000000..479401b
--- /dev/null
+++ b/kernel/cobalt/posix/fdio.c
@@ -0,0 +1,70 @@
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/err.h>
+#include <linux/ipipe.h>
+#include <cobalt/kernel/fd.h>
+#include "fdio.h"
+
+int cobalt_ioctl(int fd, unsigned int request, void __user *arg)
+{
+       struct xnfd *xnfd;
+       int err;
+       
+       xnfd = xnfd_get(fd, current->mm, 0);
+       if (IS_ERR(xnfd))
+               return PTR_ERR(xnfd);
+       
+       if (ipipe_root_p)
+               err = xnfd->ops->ioctl_nrt(xnfd, request, arg);
+       else
+               err = xnfd->ops->ioctl_rt(xnfd, request, arg);
+       
+       xnfd_put(xnfd);
+       
+       return err;
+}
+
+ssize_t cobalt_read(int fd, void __user *buf, size_t size)
+{
+       struct xnfd *xnfd;
+       ssize_t err;
+       
+       xnfd = xnfd_get(fd, current->mm, 0);
+       if (IS_ERR(xnfd))
+               return PTR_ERR(xnfd);
+       
+       if (ipipe_root_p)
+               err = xnfd->ops->read_nrt(xnfd, buf, size);
+       else
+               err = xnfd->ops->read_rt(xnfd, buf, size);
+       
+       xnfd_put(xnfd);
+       
+       return err;
+}
+
+ssize_t cobalt_write(int fd, const void __user *buf, size_t size)
+{
+       struct xnfd *xnfd;
+       ssize_t err;
+       
+       xnfd = xnfd_get(fd, current->mm, 0);
+       if (IS_ERR(xnfd))
+               return PTR_ERR(xnfd);
+       
+       if (ipipe_root_p)
+               err = xnfd->ops->write_nrt(xnfd, buf, size);
+       else
+               err = xnfd->ops->write_rt(xnfd, buf, size);
+       
+       xnfd_put(xnfd);
+       
+       return err;
+}
+
+int cobalt_close(int fd)
+{
+       return xnfd_close(fd, current->mm, 0);
+}
+
+
diff --git a/kernel/cobalt/posix/fdio.h b/kernel/cobalt/posix/fdio.h
new file mode 100644
index 0000000..a39b8c1
--- /dev/null
+++ b/kernel/cobalt/posix/fdio.h
@@ -0,0 +1,12 @@
+#ifndef FDIO_H
+#define FDIO_H
+
+int cobalt_ioctl(int fd, unsigned int request, void __user *arg);
+
+ssize_t cobalt_read(int fd, void __user *buf, size_t size);
+
+ssize_t cobalt_write(int fd, const void __user *buf, size_t size);
+
+int cobalt_close(int fd);
+
+#endif /* FDIO_H */
diff --git a/kernel/cobalt/posix/syscall.c b/kernel/cobalt/posix/syscall.c
index 3518275..4332517 100644
--- a/kernel/cobalt/posix/syscall.c
+++ b/kernel/cobalt/posix/syscall.c
@@ -38,6 +38,8 @@
 #include "clock.h"
 #include "event.h"
 #include "select.h"
+#include "fdio.h"
+#include "timerfd.h"
 
 int cobalt_muxid;
 
@@ -137,6 +139,9 @@ static struct xnsyscall cobalt_syscalls[] = {
        SKINCALL_DEF(sc_cobalt_timer_settime, cobalt_timer_settime, primary),
        SKINCALL_DEF(sc_cobalt_timer_gettime, cobalt_timer_gettime, any),
        SKINCALL_DEF(sc_cobalt_timer_getoverrun, cobalt_timer_getoverrun, any),
+       SKINCALL_DEF(sc_cobalt_timerfd_create, cobalt_timerfd_create, any),
+       SKINCALL_DEF(sc_cobalt_timerfd_gettime, cobalt_timerfd_gettime, any),
+       SKINCALL_DEF(sc_cobalt_timerfd_settime, cobalt_timerfd_settime, any),
        SKINCALL_DEF(sc_cobalt_mutexattr_init, cobalt_mutexattr_init, any),
        SKINCALL_DEF(sc_cobalt_mutexattr_destroy, cobalt_mutexattr_destroy, 
any),
        SKINCALL_DEF(sc_cobalt_mutexattr_gettype, cobalt_mutexattr_gettype, 
any),
@@ -166,6 +171,10 @@ static struct xnsyscall cobalt_syscalls[] = {
        SKINCALL_DEF(sc_cobalt_event_sync, cobalt_event_sync, any),
        SKINCALL_DEF(sc_cobalt_sched_setconfig_np, cobalt_sched_setconfig_np, 
any),
        SKINCALL_DEF(sc_cobalt_sched_getconfig_np, cobalt_sched_getconfig_np, 
any),
+       SKINCALL_DEF(sc_cobalt_ioctl, cobalt_ioctl, conform_probing),
+       SKINCALL_DEF(sc_cobalt_read, cobalt_read, conform_probing),
+       SKINCALL_DEF(sc_cobalt_write, cobalt_write, conform_probing),
+       SKINCALL_DEF(sc_cobalt_close, cobalt_close, lostage),
 };
 
 struct xnpersonality cobalt_personality = {
diff --git a/lib/cobalt/rtdm.c b/lib/cobalt/rtdm.c
index e789d76..d253bb1 100644
--- a/lib/cobalt/rtdm.c
+++ b/lib/cobalt/rtdm.c
@@ -26,9 +26,11 @@
 #include <sys/socket.h>
 #include <rtdm/rtdm.h>
 #include <cobalt/uapi/rtdm/syscall.h>
+#include <cobalt/uapi/syscall.h>
 #include <asm/xenomai/syscall.h>
 
 extern int __rtdm_muxid;
+extern int __cobalt_muxid;
 extern int __rtdm_fd_start;
 
 static inline int set_errno(int ret)
@@ -109,6 +111,13 @@ COBALT_IMPL(int, close, (int fd))
 {
        int ret;
 
+       ret = XENOMAI_SKINCALL1(__cobalt_muxid, sc_cobalt_close, fd);
+       if (ret != -EBADF) {
+               if (ret == 0)
+                       __STD(close(fd));
+               return set_errno(ret);
+       }
+
        if (fd >= __rtdm_fd_start) {
                int oldtype;
 
@@ -131,11 +140,17 @@ COBALT_IMPL(int, ioctl, (int fd, unsigned long int 
request, ...))
 {
        va_list ap;
        void *arg;
+       int err;
 
        va_start(ap, request);
        arg = va_arg(ap, void *);
        va_end(ap);
 
+       err = XENOMAI_SKINCALL3(__cobalt_muxid,
+                               sc_cobalt_ioctl, fd, request, arg);
+       if (err != -EBADF)
+               return set_errno(err);
+
        if (fd >= __rtdm_fd_start)
                return set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
                                                   sc_rtdm_ioctl,
@@ -147,11 +162,19 @@ COBALT_IMPL(int, ioctl, (int fd, unsigned long int 
request, ...))
 
 COBALT_IMPL(ssize_t, read, (int fd, void *buf, size_t nbyte))
 {
-       if (fd >= __rtdm_fd_start) {
-               int ret, oldtype;
+       int ret, oldtype;
+       
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
 
-               pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+       ret = XENOMAI_SKINCALL3(__cobalt_muxid, sc_cobalt_read, 
+                               fd, buf, nbyte);
+
+       if (ret != -EBADF) {
+               pthread_setcanceltype(oldtype, NULL);
+               return set_errno(ret);
+       }
 
+       if (fd >= __rtdm_fd_start) {
                ret = set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
                                                  sc_rtdm_read,
                                                  fd - __rtdm_fd_start,
@@ -160,17 +183,28 @@ COBALT_IMPL(ssize_t, read, (int fd, void *buf, size_t 
nbyte))
                pthread_setcanceltype(oldtype, NULL);
 
                return ret;
-       } else
-               return __STD(read(fd, buf, nbyte));
+       }
+
+       pthread_setcanceltype(oldtype, NULL);
+               
+       return __STD(read(fd, buf, nbyte));
 }
 
 COBALT_IMPL(ssize_t, write, (int fd, const void *buf, size_t nbyte))
 {
-       if (fd >= __rtdm_fd_start) {
-               int ret, oldtype;
+       int ret, oldtype;
 
-               pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
+       pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &oldtype);
 
+       ret = XENOMAI_SKINCALL3(__cobalt_muxid, sc_cobalt_write,
+                               fd, buf, nbyte);
+
+       if (ret != -EBADF) {
+               pthread_setcanceltype(oldtype, NULL);
+               return set_errno(ret);
+       }
+       
+       if (fd >= __rtdm_fd_start) {
                ret = set_errno(XENOMAI_SKINCALL3(__rtdm_muxid,
                                                  sc_rtdm_write,
                                                  fd - __rtdm_fd_start,
@@ -179,8 +213,11 @@ COBALT_IMPL(ssize_t, write, (int fd, const void *buf, 
size_t nbyte))
                pthread_setcanceltype(oldtype, NULL);
 
                return ret;
-       } else
-               return __STD(write(fd, buf, nbyte));
+       }
+
+       pthread_setcanceltype(oldtype, NULL);
+
+       return __STD(write(fd, buf, nbyte));
 }
 
 COBALT_IMPL(ssize_t, recvmsg, (int fd, struct msghdr * msg, int flags))


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

Reply via email to