+#!-bsd
+(eval-when (:compile-toplevel :load-toplevel :execute)
+ (error "The :BSD feature is missing, we shouldn't be doing this code."))
+
+(define-alien-routine ("sysctl" %sysctl) int
+ (name (* int))
+ (namelen unsigned-int)
+ (oldp (* t))
+ (oldlenp (* sb!unix:size-t))
+ (newp (* t))
+ (newlen sb!unix:size-t))
+
+(defun sysctl (type &rest name)
+ #!+sb-doc
+ "Retrieves an integer or string value with the given name."
+ (let ((name-len (length name)))
+ (when (> name-len ctl-maxname)
+ (error "sysctl name ~S is too long" name))
+ (with-alien ((name-array (array int #.ctl-maxname))
+ (result-len sb!unix:size-t))
+ (dotimes (off name-len)
+ (setf (deref name-array off) (elt name off)))
+ (ecase type
+ (:int
+ (with-alien ((result int))
+ (setf result-len (alien-size int :bytes))
+ (unless (minusp (%sysctl (cast name-array (* int)) name-len
+ (addr result) (addr result-len) nil 0))
+ result)))
+ (:str
+ (unless (minusp (%sysctl (cast name-array (* int)) name-len
+ nil (addr result-len) nil 0))
+ (with-alien ((result (* char) (make-alien char result-len)))
+ (if (minusp (%sysctl (cast name-array (* int)) name-len
+ result (addr result-len) nil 0))
+ (free-alien result)
+ (sb!unix::newcharstar-string result)))))))))