Here is a proposed "final" patch for the streams hooks.  I think that it 
takes into account all suggestions.  I put the prototype in linux/sys.h.

This is for stock 2.4.19, and has been tested.

-- Dave
--- arch/i386/kernel/entry.S.orig       2002-08-02 19:39:42.000000000 -0500
+++ arch/i386/kernel/entry.S    2002-10-08 15:43:08.000000000 -0500
@@ -584,8 +584,8 @@
        .long SYMBOL_NAME(sys_capset)           /* 185 */
        .long SYMBOL_NAME(sys_sigaltstack)
        .long SYMBOL_NAME(sys_sendfile)
-       .long SYMBOL_NAME(sys_ni_syscall)               /* streams1 */
-       .long SYMBOL_NAME(sys_ni_syscall)               /* streams2 */
+       .long SYMBOL_NAME(sys_getpmsg)          /* streams1 */
+       .long SYMBOL_NAME(sys_putpmsg)          /* streams2 */
        .long SYMBOL_NAME(sys_vfork)            /* 190 */
        .long SYMBOL_NAME(sys_getrlimit)
        .long SYMBOL_NAME(sys_mmap2)
--- kernel/sys.c.orig   2002-08-02 19:39:46.000000000 -0500
+++ kernel/sys.c        2002-10-10 15:00:45.000000000 -0500
@@ -167,6 +167,49 @@
        return notifier_chain_unregister(&reboot_notifier_list, nb);
 }
 
+static int (*do_putpmsg) (int, void *, void *, int, int) = NULL;
+static int (*do_getpmsg) (int, void *, void *, int, int) = NULL;
+
+static DECLARE_RWSEM(streams_call_sem);
+
+long asmlinkage
+sys_putpmsg(int fd, void *ctlptr, void *datptr, int band, int flags)
+{
+       int ret = -ENOSYS;
+       down_read(&streams_call_sem);   /* should return int, but doesn't */
+       if (do_putpmsg)
+               ret = (*do_putpmsg) (fd, ctlptr, datptr, band, flags);
+       up_read(&streams_call_sem);
+       return ret;
+}
+
+long asmlinkage
+sys_getpmsg(int fd, void *ctlptr, void *datptr, int band, int flags)
+{
+       int ret = -ENOSYS;
+       down_read(&streams_call_sem);   /* should return int, but doesn't */
+       if (do_getpmsg)
+               ret = (*do_getpmsg) (fd, ctlptr, datptr, band, flags);
+       up_read(&streams_call_sem);
+       return ret;
+}
+
+int
+register_streams_calls(int (*putpmsg) (int, void *, void *, int, int),
+                      int (*getpmsg) (int, void *, void *, int, int))
+{
+       int ret = -EBUSY;
+       down_write(&streams_call_sem);  /* should return int, but doesn't */
+       if (   (putpmsg == NULL || do_putpmsg == NULL)
+           && (getpmsg == NULL || do_getpmsg == NULL)) {
+               do_putpmsg = putpmsg;
+               do_getpmsg = getpmsg;
+               ret = 0;
+       }
+       up_write(&streams_call_sem);
+       return ret;
+}
+
 asmlinkage long sys_ni_syscall(void)
 {
        return -ENOSYS;
@@ -1286,3 +1329,4 @@
 EXPORT_SYMBOL(unregister_reboot_notifier);
 EXPORT_SYMBOL(in_group_p);
 EXPORT_SYMBOL(in_egroup_p);
+EXPORT_SYMBOL_GPL(register_streams_calls);
--- include/linux/sys.h.orig    2002-10-11 08:59:10.000000000 -0500
+++ include/linux/sys.h 2002-10-11 09:15:04.000000000 -0500
@@ -27,4 +27,16 @@
  * These are system calls that haven't been implemented yet
  * but have an entry in the table for future expansion..
  */
+
+/*
+ * These are registration routines for system calls that are
+ * implemented by loadable modules outside of the kernel
+ * source tree.
+ */
+#if !defined(__ASSEMBLY__)
+extern int
+register_streams_calls(int (*putpmsg) (int, void *, void *, int, int),
+                      int (*getpmsg) (int, void *, void *, int, int)) ;
+
+#endif                 /* __ASSEMBLY__ */
 #endif

Reply via email to