tech-kern archive

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

passing plist dictionaries to syscalls



Elad Efrat <elad <at> NetBSD.org> writes:
> For a long time I've been thinking about implementing a proplib-based
> syscall -- I call it "opencomm" -- and only now got around to it.
> 
> It's like prop_dictionary_sendrecv_ioctl(), only that:
>    - it doesn't require a file-descriptor/command
>    - it takes a syscall slot

I have experimental code using a syscall that takes a proplib object as
argument.

Usage from userland is like:

if (prop_dictionary_pack_pref(obj, &pref) != 0)
        adios("can't create plistref");
if (mysyscall(&pref) == -1)
        adios("nysyscall");

And from the kernel side:

int
sys_mysyscall(lwp_t *l, const struct sys_mysyscall_args *uap, register_t 
*retval)
{
        /* {
                syscallarg(struct plistref) pref;
        } */
        prop_dictionary_t obj;

        error = prop_dictionary_copyin(SCARG(uap, pref), &obj);
        if (error)
                return (error);
        ....
}

I've amended the interface provided by prop_kern.c as follows.  I guess
changes along the same lines could be made for the copyout path.

Index: prop_kern.c
===================================================================
RCS file: /cvsroot/src/common/lib/libprop/prop_kern.c,v
retrieving revision 1.9
diff -u -r1.9 prop_kern.c
--- prop_kern.c 28 Apr 2008 20:22:53 -0000      1.9
+++ prop_kern.c 28 Apr 2009 19:43:32 -0000
@@ -1,7 +1,7 @@
 /*     $NetBSD: prop_kern.c,v 1.9 2008/04/28 20:22:53 martin Exp $     */
 
 /*-
- * Copyright (c) 2006 The NetBSD Foundation, Inc.
+ * Copyright (c) 2006, 2008 The NetBSD Foundation, Inc.
  * All rights reserved.
  *
  * This code is derived from software contributed to The NetBSD Foundation
@@ -70,6 +70,30 @@
        return (0);
 }
 
+/*
+ * prop_array_pack_pref --
+ *     Pack an array into a plistref for sending to the kernel.
+ */
+int
+prop_array_pack_pref(prop_array_t array, struct plistref *prefp)
+{
+       char *buf;
+
+       return _prop_object_pack_pref(array, prefp, &buf);
+}
+
+/*
+ * prop_dictionary_pack_pref --
+ *     Pack an dictionary into a plistref for sending to the kernel.
+ */
+int
+prop_dictionary_pack_pref(prop_dictionary_t dict, struct plistref *prefp)
+{
+       char *buf;
+
+       return _prop_object_pack_pref(dict, prefp, &buf);
+}
+
 static int
 _prop_object_send_ioctl(prop_object_t obj, int fd, unsigned long cmd)
 {
@@ -231,16 +255,13 @@
 unsigned int prop_object_copyin_limit = 65536;
 
 static int
-_prop_object_copyin_ioctl(const struct plistref *pref, const prop_type_t type,
-                         const u_long cmd, prop_object_t *objp)
+_prop_object_copyin(const struct plistref *pref, const prop_type_t type,
+                         prop_object_t *objp)
 {
        prop_object_t obj = NULL;
        char *buf;
        int error;
 
-       if ((cmd & IOC_IN) == 0)
-               return (EFAULT);
-
        /*
         * Allocate an extra byte so we can guarantee NUL-termination.
         *
@@ -277,6 +298,40 @@
        return (error);
 }
 
+
+static int
+_prop_object_copyin_ioctl(const struct plistref *pref, const prop_type_t type,
+                         const u_long cmd, prop_object_t *objp)
+{
+       if ((cmd & IOC_IN) == 0)
+               return (EFAULT);
+
+       return _prop_object_copyin(pref, type, objp);
+}
+
+/*
+ * prop_array_copyin --
+ *     Copy in an array passed as a syscall arg.
+ */
+int
+prop_array_copyin(const struct plistref *pref, prop_array_t *arrayp)
+{
+       return (_prop_object_copyin(pref, PROP_TYPE_ARRAY,
+                                         (prop_object_t *)arrayp));
+}
+
+/*
+ * prop_dictionary_copyin --
+ *     Copy in a dictionary passed as a syscall arg.
+ */
+int
+prop_dictionary_copyin(const struct plistref *pref, prop_dictionary_t *dictp)
+{
+       return (_prop_object_copyin(pref, PROP_TYPE_DICTIONARY,
+                                         (prop_object_t *)dictp));
+}
+
+
 /*
  * prop_array_copyin_ioctl --
  *     Copy in an array send with an ioctl.

--chris




Home | Main Index | Thread Index | Old Index