Author: marius
Date: Sat Mar  2 17:39:11 2013
New Revision: 247656
URL: http://svnweb.freebsd.org/changeset/base/247656

Log:
  MFC: r246689, r246696
  
  Make SYSCTL_{LONG,QUAD,ULONG,UQUAD}(9) work as advertised and also handle
  constant values.
  
  Reviewed by:  kib

Modified:
  stable/9/sys/kern/kern_sysctl.c
Directory Properties:
  stable/9/sys/   (props changed)

Modified: stable/9/sys/kern/kern_sysctl.c
==============================================================================
--- stable/9/sys/kern/kern_sysctl.c     Sat Mar  2 17:36:31 2013        
(r247655)
+++ stable/9/sys/kern/kern_sysctl.c     Sat Mar  2 17:39:11 2013        
(r247656)
@@ -1036,7 +1036,10 @@ sysctl_msec_to_ticks(SYSCTL_HANDLER_ARGS
 
 
 /*
- * Handle a long, signed or unsigned.  arg1 points to it.
+ * Handle a long, signed or unsigned.
+ * Two cases:
+ *     a variable:  point arg1 at it.
+ *     a constant:  pass it in arg2.
  */
 
 int
@@ -1051,9 +1054,10 @@ sysctl_handle_long(SYSCTL_HANDLER_ARGS)
        /*
         * Attempt to get a coherent snapshot by making a copy of the data.
         */
-       if (!arg1)
-               return (EINVAL);
-       tmplong = *(long *)arg1;
+       if (arg1)
+               tmplong = *(long *)arg1;
+       else
+               tmplong = arg2;
 #ifdef SCTL_MASK32
        if (req->flags & SCTL_MASK32) {
                tmpint = tmplong;
@@ -1065,18 +1069,24 @@ sysctl_handle_long(SYSCTL_HANDLER_ARGS)
        if (error || !req->newptr)
                return (error);
 
+       if (!arg1)
+               error = EPERM;
 #ifdef SCTL_MASK32
-       if (req->flags & SCTL_MASK32) {
+       else if (req->flags & SCTL_MASK32) {
                error = SYSCTL_IN(req, &tmpint, sizeof(int));
                *(long *)arg1 = (long)tmpint;
-       } else
+       }
 #endif
+       else
                error = SYSCTL_IN(req, arg1, sizeof(long));
        return (error);
 }
 
 /*
- * Handle a 64 bit int, signed or unsigned.  arg1 points to it.
+ * Handle a 64 bit int, signed or unsigned.
+ * Two cases:
+ *     a variable:  point arg1 at it.
+ *     a constant:  pass it in arg2.
  */
 int
 sysctl_handle_64(SYSCTL_HANDLER_ARGS)
@@ -1087,15 +1097,19 @@ sysctl_handle_64(SYSCTL_HANDLER_ARGS)
        /*
         * Attempt to get a coherent snapshot by making a copy of the data.
         */
-       if (!arg1)
-               return (EINVAL);
-       tmpout = *(uint64_t *)arg1;
+       if (arg1)
+               tmpout = *(uint64_t *)arg1;
+       else
+               tmpout = arg2;
        error = SYSCTL_OUT(req, &tmpout, sizeof(uint64_t));
 
        if (error || !req->newptr)
                return (error);
 
-       error = SYSCTL_IN(req, arg1, sizeof(uint64_t));
+       if (!arg1)
+               error = EPERM;
+       else
+               error = SYSCTL_IN(req, arg1, sizeof(uint64_t));
        return (error);
 }
 
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to