uname(3): Add env override capability
authorJohn Marino <draco@marino.st>
Tue, 16 Feb 2016 11:26:51 +0000 (12:26 +0100)
committerJohn Marino <draco@marino.st>
Tue, 16 Feb 2016 11:39:28 +0000 (12:39 +0100)
The uname(1) program has honored UNAME_[x] overrides since DragonFly's
beginning, but libc's uname never did.  Make it recognize the following
environment variables:
  UNAME_m
  UNAME_r
  UNAME_s
  UNAME_v
These variables cause uname() to return the specified values instead of
what was built into libc.  This capability, which has been in FreeBSD for
more than a decade, is required for package builders that need to define
the jail environment different from the host (prime example: Python)

lib/libc/gen/uname.3
lib/libc/gen/uname.c

index b43a3a6..5fb12fd 100644 (file)
@@ -27,9 +27,8 @@
 .\"
 .\"    @(#)uname.3     8.1 (Berkeley) 1/4/94
 .\" $FreeBSD: src/lib/libc/gen/uname.3,v 1.6.2.4 2001/12/14 18:33:51 ru Exp $
-.\" $DragonFly: src/lib/libc/gen/uname.3,v 1.3 2006/05/26 19:39:36 swildner Exp $
 .\"
-.Dd January 4, 1994
+.Dd February 16, 2016
 .Dt UNAME 3
 .Os
 .Sh NAME
@@ -67,6 +66,33 @@ Machine hardware platform.
 .El
 .Sh RETURN VALUES
 .Rv -std uname
+.Sh ENVIRONMENT
+.Bl -tag -width ".Ev UNAME_s"
+.It Ev UNAME_s
+If the environment variable
+.Ev UNAME_s
+is set, it will override the
+.Va sysname
+member.
+.It Ev UNAME_r
+If the environment variable
+.Ev UNAME_r
+is set, it will override the
+.Va release
+member.
+.It Ev UNAME_v
+If the environment variable
+.Ev UNAME_v
+is set, it will override the
+.Va version
+member.
+.It Ev UNAME_m
+If the environment variable
+.Ev UNAME_m
+is set, it will override the
+.Va machine
+member.
+.El
 .Sh ERRORS
 The
 .Fn uname
index 68f909f..bbde2e5 100644 (file)
  *
  * @(#)uname.c 8.1 (Berkeley) 1/4/94
  * $FreeBSD: src/lib/libc/gen/uname.c,v 1.7 1999/08/27 23:59:06 peter Exp $
- * $DragonFly: src/lib/libc/gen/uname.c,v 1.5 2007/01/19 07:23:40 dillon Exp $
  */
 
 #include <sys/param.h>
 #include <sys/sysctl.h>
 #include <sys/utsname.h>
+#include <stdlib.h>
+#include <string.h>
 #include <errno.h>
 
 int
@@ -46,17 +47,21 @@ uname(struct utsname *name)
 
        rval = 0;
 
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_OSTYPE;
-       len = sizeof(name->sysname);
-       oerrno = errno;
-       if (sysctl(mib, 2, &name->sysname, &len, NULL, 0) == -1) {
-               if(errno == ENOMEM)
-                       errno = oerrno;
-               else
-                       rval = -1;
+       if ((p = getenv("UNAME_s"))) {
+               strlcpy(name->sysname, p, sizeof(name->sysname));
+       } else {
+               mib[0] = CTL_KERN;
+               mib[1] = KERN_OSTYPE;
+               len = sizeof(name->sysname);
+               oerrno = errno;
+               if (sysctl(mib, 2, &name->sysname, &len, NULL, 0) == -1) {
+                       if(errno == ENOMEM)
+                               errno = oerrno;
+                       else
+                               rval = -1;
+               }
+               name->sysname[sizeof(name->sysname) - 1] = '\0';
        }
-       name->sysname[sizeof(name->sysname) - 1] = '\0';
 
        mib[0] = CTL_KERN;
        mib[1] = KERN_HOSTNAME;
@@ -70,50 +75,63 @@ uname(struct utsname *name)
        }
        name->nodename[sizeof(name->nodename) - 1] = '\0';
 
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_OSRELEASE;
-       len = sizeof(name->release);
-       oerrno = errno;
-       if (sysctl(mib, 2, &name->release, &len, NULL, 0) == -1) {
-               if(errno == ENOMEM)
-                       errno = oerrno;
-               else
-                       rval = -1;
+       if ((p = getenv("UNAME_r"))) {
+               strlcpy(name->release, p, sizeof(name->release));
+       } else {
+               mib[0] = CTL_KERN;
+               mib[1] = KERN_OSRELEASE;
+               len = sizeof(name->release);
+               oerrno = errno;
+               if (sysctl(mib, 2, &name->release, &len, NULL, 0) == -1) {
+                       if(errno == ENOMEM)
+                               errno = oerrno;
+                       else
+                               rval = -1;
+               }
+               name->release[sizeof(name->release) - 1] = '\0';
        }
-       name->release[sizeof(name->release) - 1] = '\0';
 
-       /* The version may have newlines in it, turn them into spaces. */
-       mib[0] = CTL_KERN;
-       mib[1] = KERN_VERSION;
-       len = sizeof(name->version);
-       oerrno = errno;
-       if (sysctl(mib, 2, &name->version, &len, NULL, 0) == -1) {
-               if (errno == ENOMEM)
-                       errno = oerrno;
-               else
-                       rval = -1;
-       }
-       name->version[sizeof(name->version) - 1] = '\0';
-       for (p = name->version; len--; ++p) {
-               if (*p == '\n' || *p == '\t') {
-                       if (len > 1)
-                               *p = ' ';
+       if ((p = getenv("UNAME_v"))) {
+               strlcpy(name->version, p, sizeof(name->version));
+       } else {
+               /* The version may contain newlines, turn them into spaces. */
+               mib[0] = CTL_KERN;
+               mib[1] = KERN_VERSION;
+               len = sizeof(name->version);
+               oerrno = errno;
+               if (sysctl(mib, 2, &name->version, &len, NULL, 0) == -1) {
+                       if (errno == ENOMEM)
+                               errno = oerrno;
                        else
-                               *p = '\0';
+                               rval = -1;
+               }
+               name->version[sizeof(name->version) - 1] = '\0';
+               for (p = name->version; len--; ++p) {
+                       if (*p == '\n' || *p == '\t') {
+                               if (len > 1)
+                                       *p = ' ';
+                               else
+                                       *p = '\0';
+                       }
                }
        }
 
-       oerrno = errno;
-       mib[1] = HW_MACHINE;
-       mib[0] = CTL_HW;
-       len = sizeof(name->machine);
-       if (sysctl(mib, 2, &name->machine, &len, NULL, 0) == -1) {
-               if (errno == ENOMEM) {
-                       errno = oerrno;
-               } else {
-                       rval = -1;
+       if ((p = getenv("UNAME_m"))) {
+               strlcpy(name->machine, p, sizeof(name->machine));
+       }
+       else {
+               oerrno = errno;
+               mib[1] = HW_MACHINE;
+               mib[0] = CTL_HW;
+               len = sizeof(name->machine);
+               if (sysctl(mib, 2, &name->machine, &len, NULL, 0) == -1) {
+                       if (errno == ENOMEM) {
+                               errno = oerrno;
+                       } else {
+                               rval = -1;
+                       }
                }
+               name->machine[sizeof(name->machine) - 1] = '\0';
        }
-       name->machine[sizeof(name->machine) - 1] = '\0';
        return (rval);
 }