Changeset View
Standalone View
lib/libsysctl/libsysctl.h
Property | Old Value | New Value |
---|---|---|
svn:eol-style | null | native \ No newline at end of property |
svn:keywords | null | FreeBSD=%H \ No newline at end of property |
svn:mime-type | null | text/plain \ No newline at end of property |
/*- | |||||
* SPDX-License-Identifier: BSD-2-Clause-FreeBSD | |||||
* | |||||
* Copyright (c) 2018-2019 Alfonso Sabato Siciliano | |||||
* | |||||
* Redistribution and use in source and binary forms, with or without | |||||
* modification, are permitted provided that the following conditions | |||||
* are met: | |||||
* 1. Redistributions of source code must retain the above copyright | |||||
* notice, this list of conditions and the following disclaimer. | |||||
* 2. Redistributions in binary form must reproduce the above copyright | |||||
* notice, this list of conditions and the following disclaimer in the | |||||
* documentation and/or other materials provided with the distribution. | |||||
* | |||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND | |||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE | |||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | |||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE | |||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL | |||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS | |||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) | |||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY | |||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||||
* SUCH DAMAGE. | |||||
*/ | |||||
#ifndef _LIBSYSCTL_H | |||||
#define _LIBSYSCTL_H | |||||
#include <sys/types.h> | |||||
#include <sys/queue.h> | |||||
#include <sys/sysctl.h> | |||||
#define LIBSYSCTL_VERSION 1 | |||||
#define LIBSYSCTL_IDMAXLEVEL (CTL_MAXNAME - 2) | |||||
/* | |||||
* functions to wrap 'undocumented kern_sysctl.c API', | |||||
* return: 0 for success, negative value for failure. | |||||
*/ | |||||
int | |||||
brooks: I'd find the headers a lot easier to read if you included variable names in the function… | |||||
Done Inline Actionsfixed: added variable names in the function prototypes. asiciliano: fixed: added variable names in the function prototypes. | |||||
libsysctl_nametoid(const char *name, size_t namelen, int *id, size_t *idlevel); | |||||
int libsysctl_name(int *id, size_t idlevel, char *name, size_t *namelen); | |||||
int libsysctl_desc(int *id, size_t idlevel, char *desc, size_t *desclen); | |||||
int libsysctl_label(int *id, size_t idlevel, char *label, size_t *labellen); | |||||
#define LIBSYSCTL_NAMELEN(id, idlevel, size) \ | |||||
libsysctl_name(id, idlevel, NULL, size) | |||||
#define LIBSYSCTL_DESCLEN(id, idlevel, size) \ | |||||
libsysctl_desc(id, idlevel, NULL, size) | |||||
#define LIBSYSCTL_LABELLEN(id, idlevel, size) \ | |||||
libsysctl_label(id, idlevel, NULL, size) | |||||
int libsysctl_info(int *id, size_t idlevel, void *info, size_t *infolen); | |||||
#define LIBSYSCTL_INFOKIND(info) (*((unsigned int *)info)) | |||||
#define LIBSYSCTL_INFOTYPE(info) (*((unsigned int *)info) & CTLTYPE) | |||||
#define LIBSYSCTL_INFOFLAGS(info) (*((unsigned int *)info) & 0xfffffff0) | |||||
#define LIBSYSCTL_INFOFMT(info) ((char *)info + sizeof(unsigned int)) | |||||
/* kernel returns only next leaf, next node requires extra computation */ | |||||
int | |||||
libsysctl_nextnode(int *id, size_t idlevel, int *idnext, size_t *idnextlevel); | |||||
int | |||||
libsysctl_nextleaf(int *id, size_t idlevel, int *idnext, size_t *idnextlevel); | |||||
/* | |||||
* functions related to "struct libsysctl_object" | |||||
* params: id and idlevel to identify a mib entry | |||||
* return: NULL for failure, pointer to allocated memory for success. | |||||
*/ | |||||
/* 'struct libsysctl_object': userspace mib entry definition */ | |||||
Not Done Inline ActionsWhile this layout (pairing length and pointer) makes the structure easy to read, it's somewhat expensive on architectures where pointers are larger and have stronger alignment constraints than size_t. E.g. on 128-bit CHERI this layout would waste an extra 32-bytes on padding which could add up if you have a lot of these. brooks: While this layout (pairing length and pointer) makes the structure easy to read, it's somewhat… | |||||
Done Inline Actions(Thanks you, very important suggestion). asiciliano: (Thanks you, very important suggestion).
Fixed, delete: namelen, desclen, labellen, fmtlen. | |||||
SLIST_HEAD(libsysctl_object_list, libsysctl_object); | |||||
struct libsysctl_object { | |||||
SLIST_ENTRY(libsysctl_object) object_link; | |||||
int *id; | |||||
size_t idlevel; /* between 1 and LIBSYSCTL_IDMAXLEVEL */ | |||||
char *name; | |||||
char *desc; | |||||
char *label; /* aggregation label */ | |||||
uint8_t type; /* defined in <sys/sysctl.h> */ | |||||
uint32_t flags; /* defined in <sys/sysctl.h> */ | |||||
Not Done Inline ActionsI'd say children here. brooks: I'd say `children` here. | |||||
Done Inline ActionsFixed, change: "childs" -> "children" asiciliano: Fixed, change: "childs" -> "children"
(I left the UK 3 years ago, it' s time to refresh my… | |||||
char *fmt; /* format string */ | |||||
/* children is set by libsysctl_tree() */ | |||||
struct libsysctl_object_list *children; | |||||
}; | |||||
/* | |||||
* OR_FLAGS: object fields to set, | |||||
* .id and .idlevel are always set | |||||
* .children is default for libsysctl_tree() | |||||
*/ | |||||
#define LIBSYSCTL_FNAME 0x01 /* .name */ | |||||
#define LIBSYSCTL_FDESC 0x02 /* .desc */ | |||||
#define LIBSYSCTL_FLABEL 0x04 /* .label */ | |||||
#define LIBSYSCTL_FTYPE 0x08 /* .type */ | |||||
#define LIBSYSCTL_FFLAGS 0x10 /* .flags */ | |||||
#define LIBSYSCTL_FFMT 0x20 /* .fmt */ | |||||
#define LIBSYSCTL_FALL /* all */ \ | |||||
LIBSYSCTL_FNAME | LIBSYSCTL_FDESC \ | |||||
| LIBSYSCTL_FLABEL | LIBSYSCTL_FTYPE \ | |||||
| LIBSYSCTL_FFLAGS | LIBSYSCTL_FFMT | |||||
/* object functions */ | |||||
struct libsysctl_object * | |||||
libsysctl_object(int *id, size_t idlevel, unsigned int flags); | |||||
void | |||||
libsysctl_freeobject(struct libsysctl_object *object); | |||||
/* list functions */ | |||||
#define LIBSYSCTL_MAXDEPTH (CTL_MAXNAME - 3) | |||||
typedef int libsysctl_filterfunc_t (struct libsysctl_object *object); | |||||
struct libsysctl_object_list * | |||||
libsysctl_filterlist(libsysctl_filterfunc_t *filterfunc, unsigned int flags); | |||||
#define LIBSYSCTL_LIST(flags) libsysctl_filterlist(NULL, flags) | |||||
struct libsysctl_object_list * | |||||
libsysctl_grouplist(int *id, size_t idlevel, unsigned int flags, | |||||
unsigned int max_depth); | |||||
void | |||||
libsysctl_freelist(struct libsysctl_object_list *list); | |||||
/* tree fuctions */ | |||||
struct libsysctl_object * | |||||
libsysctl_tree(int *id, size_t idlevel, unsigned int flags, | |||||
unsigned int max_depth); | |||||
void | |||||
libsysctl_freetree(struct libsysctl_object *object_root); | |||||
/* | |||||
dabUnsubmitted Not Done Inline ActionsThese are very thin wrappers around sysctl() and I don't think provide significant value. Why define them? At first I thought maybe the GET was going to address the common case where the value length is not known and you have to round-trip twice, first to get the length and then a second time to get the actual value, but that isn't the case. I think that would provide value. I would just delete these as they are currently defined. dab: These are very thin wrappers around sysctl() and I don't think provide significant value. Why… | |||||
asicilianoAuthorUnsubmitted Done Inline ActionsThank you for your comment,
I think you mean: LIBSYSCTL_VALUELEN(id, idlevel, size) sysctl(id, idlevel, NULL, size, NULL, 0) , if you wish I could add it, anyway it's right: these are very thin wrappers. asiciliano: Thank you for your comment,
OK I 'll delete _GETVALUE(), _SETVALUE() and update the manual.
>… | |||||
* Macros to get/set value, | |||||
* libsysctl is not designed to get/set 'kernel state', use sysctl(3): | |||||
* | |||||
* sysctl(obj->id, obj->idlevel, oldp, oldplen, newp, newplen); | |||||
* | |||||
* anyway some macro is defined: | |||||
dabUnsubmitted Not Done Inline Actionsnit: s/macro is/macros are/ dab: nit: s/macro is/macros are/ | |||||
asicilianoAuthorUnsubmitted Done Inline Actionsanswer up asiciliano: answer up | |||||
*/ | |||||
#define LIBSYSCTL_GETVALUE(id, idlevel, oldvalue, oldvaluelen) \ | |||||
sysctl(id, idlevel, oldvalue, oldvaluelen, NULL, 0) | |||||
#define LIBSYSCTL_SETVALUE(id, idlevel, newvalue, newvaluelen) \ | |||||
sysctl(id, idlevel, NULL, 0, newvalue, newvaluelen) | |||||
#endif /* _LIBSYSCTL_H */ |
I'd find the headers a lot easier to read if you included variable names in the function prototypes.