aboutsummaryrefslogtreecommitdiff
path: root/sysutils/p5-BSD-Sysctl
diff options
context:
space:
mode:
authorSteve Wills <swills@FreeBSD.org>2017-07-08 13:45:34 +0000
committerSteve Wills <swills@FreeBSD.org>2017-07-08 13:45:34 +0000
commitf2eff86cc41a722c95e84687cccf0ad0579f6ed9 (patch)
treef41a126833f686161a6e9aadce6ab1c608888aed /sysutils/p5-BSD-Sysctl
parent665f9d2f92e1cf09ad39143cdc0183b7afa6cf02 (diff)
downloadports-f2eff86cc41a722c95e84687cccf0ad0579f6ed9.tar.gz
ports-f2eff86cc41a722c95e84687cccf0ad0579f6ed9.zip
sysutils/p5-BSD-Sysctl: Support setting 64-bit sysctl values
PR: 216450 Submitted by: jtl Approved by: david@landgren.net (maintainer timeout, 5 months)
Notes
Notes: svn path=/head/; revision=445326
Diffstat (limited to 'sysutils/p5-BSD-Sysctl')
-rw-r--r--sysutils/p5-BSD-Sysctl/Makefile2
-rw-r--r--sysutils/p5-BSD-Sysctl/files/patch-Sysctl.xs319
2 files changed, 320 insertions, 1 deletions
diff --git a/sysutils/p5-BSD-Sysctl/Makefile b/sysutils/p5-BSD-Sysctl/Makefile
index 56d8b8d85bed..648797fc4279 100644
--- a/sysutils/p5-BSD-Sysctl/Makefile
+++ b/sysutils/p5-BSD-Sysctl/Makefile
@@ -3,7 +3,7 @@
PORTNAME= BSD-Sysctl
PORTVERSION= 0.11
-PORTREVISION= 1
+PORTREVISION= 2
CATEGORIES= sysutils perl5
MASTER_SITES= CPAN
PKGNAMEPREFIX= p5-
diff --git a/sysutils/p5-BSD-Sysctl/files/patch-Sysctl.xs b/sysutils/p5-BSD-Sysctl/files/patch-Sysctl.xs
new file mode 100644
index 000000000000..e16c017c1f71
--- /dev/null
+++ b/sysutils/p5-BSD-Sysctl/files/patch-Sysctl.xs
@@ -0,0 +1,319 @@
+--- Sysctl.xs.orig 2014-01-21 23:02:47 UTC
++++ Sysctl.xs
+@@ -14,6 +14,7 @@
+
+ #include <stdio.h>
+ #include <sys/types.h>
++#include <sys/cdefs.h>
+ #include <sys/sysctl.h>
+
+ #include <sys/time.h> /* struct clockinfo */
+@@ -48,78 +49,114 @@
+ #include <netinet6/raw_ip6.h>
+ #include "bsd-sysctl.h"
+
++void
++_iterator_first(HV *self)
++{
++ SV **headp;
++ int name[CTL_MAXNAME];
++ size_t len;
++
++ headp = hv_fetch(self, "head", 4, 0);
++ if (headp == NULL || *headp == NULL)
++ croak( "failed to fetch head in _iterator_first()\n" );
++
++ if (SvPOK(*headp)) {
++ /* we were given starting node */
++ len = sizeof(name);
++ if (sysctlnametomib(SvPV_nolen(*headp), name, &len) == -1)
++ croak("sysctlnametomib(head) failed in _iterator_first\n");
++ } else {
++ /* start at the top like sysctl -a */
++ name[0] = 1;
++ len = 1;
++ }
++
++ hv_store(self, "_next", 5, newSVpvn((char const *) name, len * sizeof(int)), 0);
++ hv_store(self, "_len0", 5, newSViv(len), 0);
++ hv_store(self, "_name", 5, newSVpvn("", 0), 0);
++}
++
+ int
+-_init_iterator(HV *self, int *mib, int *miblenp, int valid) {
+- SV **headp;
+- int qoid[CTL_MAXNAME];
+- u_int qoidlen;
+- SV *clen;
+- SV **clenp;
+- int cmplen;
+- int j;
++_iterator_next(HV *self)
++{
++ SV *nextp, **len0p, *namep;
++ int *next, name1[CTL_MAXNAME + 2], name2[CTL_MAXNAME + 2];
++ size_t len0, next_len, len1, len2;
+
+- qoid[0] = 0;
+- qoid[1] = 2;
+- if (valid) {
+- memcpy(qoid+2, mib, (*miblenp) * sizeof(int));
+- qoidlen = *miblenp + 2;
+- *miblenp = (CTL_MAXNAME+2) * sizeof(int);
+- clenp = hv_fetch(self, "_len", 4, 0);
+- cmplen = SvIV(*clenp);
+- }
+- else {
+- headp = hv_fetch(self, "head", 4, 0);
+- if (!(headp && *headp)) {
+- croak( "failed to get some head in _init_iterator()\n" );
+- }
+- if (SvPOK(*headp)) {
+- /* begin where asked */
+- qoidlen = sizeof(qoid);
+- if (sysctlnametomib( SvPV_nolen(*headp), qoid+2, (size_t*)&qoidlen) == -1) {
+- warn( "_init_iterator(%s): sysctlnametomib lookup failed\n",
+- SvPV_nolen(*headp)
+- );
+- return 0;
+- }
+- cmplen = qoidlen;
+- qoidlen += 2;
+- }
+- else {
+- /* begin at the beginning */
+- qoid[2] = 1;
+- cmplen = 0;
+- qoidlen = 3;
+- }
+- clen = newSViv(cmplen);
+- SvREFCNT_inc(clen);
+- hv_store(self, "_len", 4, clen, 0);
+- }
++ if (! hv_exists(self, "_len0", 5))
++ _iterator_first(self);
+
+- /*
+- printf( "next: " );
+- for (j = 0; j < qoidlen; ++j) {
+- if (j) printf("."); printf("%d", qoid[j]);
+- }
+- printf("\n");
+- */
++ len0p = hv_fetch(self, "_len0", 5, 0);
++ if (len0p == NULL || *len0p == NULL)
++ croak("hv_fetch(_len0) failed in _iterator_next\n");
++ len0 = SvIV(*len0p);
++
++ nextp = hv_delete(self, "_next", 5, 0);
++ if (nextp == NULL)
++ return 0;
++ next = (int *) SvPV(nextp, next_len);
++ next_len /= sizeof(int);
+
+- /* load the mib */
+- if (sysctl(qoid, qoidlen, mib, (size_t*)miblenp, 0, 0) == -1) {
+- return 0;
+- }
+- *miblenp /= sizeof(int);
+- if (*miblenp < cmplen) {
+- return 0 ;
+- }
++ namep = hv_delete(self, "_name", 5, 0);
++ if (namep == NULL)
++ return 0;
+
+- for (j = 0; j < cmplen; ++j) {
+- if (mib[j] != qoid[j+2]) {
+- return 0;
+- }
+- }
+- return 1;
++ /*
++ * Get next (after _next): name1 = [ 0, 2, next ]
++ */
++
++ name1[0] = 0;
++ name1[1] = 2; /* get next */
++ memcpy((name1 + 2), next, next_len * sizeof(int));
++ len1 = next_len + 2;
++
++ len2 = sizeof(name2);
++ if (sysctl(name1, len1, name2, &len2, 0, 0) < 0) {
++ if (errno == ENOENT)
++ return (0);
++
++ croak("sysctl(next) failed in _iterator_next()\n");
++ }
++ len2 /= sizeof(int);
++
++ if (len2 < len0)
++ return 0; /* shorter than first */
++ if (memcmp(name2, next, len0 * sizeof(int)) != 0)
++ return 0; /* does not match anymore */
++
++ /* at this point, name2/len2 has next iterator, update _next here */
++ hv_store(self, "_next", 5, newSVpvn((char const *) name2, len2 * sizeof(int)), 0);
++
++ /*
++ * Get name (from name2): name1 = [ 0, 1, name2 ]
++ */
++
++ name1[0] = 0;
++ name1[1] = 1; /* get name */
++ memcpy((name1 + 2), name2, len2 * sizeof(int));
++ len1 = len2 + 2;
++
++ len2 = sizeof(name2);
++ if (sysctl(name1, len1, name2, &len2, 0, 0) < 0) {
++ if (errno == ENOENT)
++ return (0);
++
++ croak("sysctl(name) failed in _iterator_next()\n");
++ }
++
++ /* at this point, name2/len2 has name, update _name here */
++ hv_store(self, "_name", 5, newSVpvn((char const *) name2, len2 - 1), 0);
++
++ return 1;
+ }
+
++/*
++ * The below two comparisons must be true for the 64-bit setting code to
++ * work correctly.
++ */
++_Static_assert(LLONG_MAX >= INT64_MAX, "compile-time assertion failed");
++_Static_assert(ULLONG_MAX >= UINT64_MAX, "compile-time assertion failed");
++
+ MODULE = BSD::Sysctl PACKAGE = BSD::Sysctl
+
+ PROTOTYPES: ENABLE
+@@ -127,67 +164,18 @@ PROTOTYPES: ENABLE
+ SV *
+ next (SV *refself)
+ INIT:
+- int mib[CTL_MAXNAME+2];
+- size_t miblen;
+- int qoid[CTL_MAXNAME+2];
+- size_t qoidlen;
+- char name[BUFSIZ];
+- size_t namelen;
+ HV *self;
+- SV **ctxp;
+- SV *ctx;
+- SV *cname;
+- int j;
+- int *p;
++ SV **namep;
+
+ CODE:
+ self = (HV *)SvRV(refself);
+- if ((ctxp = hv_fetch(self, "_ctx", 4, 0))) {
+- p = (int *)SvPVX(*ctxp);
+- miblen = *p++;
+- memcpy(mib, p, miblen * sizeof(int));
+
+- if (!_init_iterator(self, mib, (int*)&miblen, 1)) {
+- XSRETURN_UNDEF;
+- }
+- }
+- else {
+- miblen = sizeof(mib)/sizeof(mib[0]);
+- if (!_init_iterator(self, mib, (int*)&miblen, 0)) {
+- XSRETURN_UNDEF;
+- }
+- }
+-
+- qoid[0] = 0;
+- qoid[1] = 1;
+- memcpy(qoid+2, mib, miblen * sizeof(int));
+- qoidlen = miblen + 2;
+-
+- bzero(name, BUFSIZ);
+- namelen = sizeof(name);
+- j = sysctl(qoid, qoidlen, name, &namelen, 0, 0);
+- if (j || !namelen) {
+- warn("next(): sysctl name failure %d %zu %d", j, namelen, errno);
+- XSRETURN_UNDEF;
+- }
+- cname = newSVpvn(name, namelen-1);
+- SvREFCNT_inc(cname);
+- hv_store(self, "_name", 5, cname, 0);
+- RETVAL = cname;
+-
+- /* reuse qoid to build context store
+- * - the length of the mib
+- * - followed by the mib values
+- * and copy to an SV to save in the self hash
+- */
+- p = qoid;
+- memcpy(p++, (const void *)&miblen, sizeof(int));
+- memcpy(p, (const void *)mib, miblen * sizeof(int));
+-
+- ctx = newSVpvn((const char *)qoid, (miblen+1) * sizeof(int));
+- SvREFCNT_inc(ctx);
+- hv_store(self, "_ctx", 4, ctx, 0);
+-
++ if (_iterator_next(self) == 0)
++ XSRETURN_UNDEF;
++
++ namep = hv_fetch(self, "_name", 5, 0);
++ SvREFCNT_inc(*namep);
++ RETVAL = *namep;
+ OUTPUT:
+ RETVAL
+
+@@ -878,6 +866,10 @@ _mib_set(const char *arg, const char *value)
+ SV **oidp;
+ SV *oid;
+ char *oid_data;
++ int64_t int64val;
++ long long llval;
++ uint64_t uint64val;
++ unsigned long long ullval;
+ int oid_fmt;
+ int oid_len;
+ int intval;
+@@ -954,6 +946,42 @@ _mib_set(const char *arg, const char *value)
+ }
+ newval = &ulongval;
+ newsize = sizeof(ulongval);
++ break;
++
++ case FMT_64:
++ llval = strtoll(value, &endconvptr, 0);
++ if (endconvptr == value || *endconvptr != '\0' ||
++ (llval == 0 && errno == EINVAL)) {
++ warn("invalid 64-bit integer: '%s'", value);
++ XSRETURN_UNDEF;
++ }
++#if (LLONG_MAX > INT64_MAX)
++ if (llval < INT64_MIN)
++ int64val = INT64_MIN;
++ else if (llval > INT64_MAX)
++ int64val = INT64_MAX;
++ else
++#endif
++ int64val = (int64_t)llval;
++ newval = &int64val;
++ newsize = sizeof(int64val);
++ break;
++
++ case FMT_U64:
++ ullval = strtoull(value, &endconvptr, 0);
++ if (endconvptr == value || *endconvptr != '\0' ||
++ (ullval == 0 && errno == EINVAL)) {
++ warn("invalid unsigned 64-bit integer: '%s'", value);
++ XSRETURN_UNDEF;
++ }
++#if (ULLONG_MAX > UINT64_MAX)
++ if (ullval > UINT64_MAX)
++ uint64val = UINT64_MAX;
++ else
++#endif
++ uint64val = (uint64_t)ullval;
++ newval = &uint64val;
++ newsize = sizeof(uint64val);
+ break;
+ }
+