Print this page
sysinfo emulation

@@ -35,10 +35,11 @@
 #include <sys/inttypes.h>
 #include <sys/lwp.h>
 #include <sys/syscall.h>
 #include <sys/systm.h>
 #include <sys/utsname.h>
+#include <sys/systeminfo.h>
 #include <sys/zone.h>
 #include <sys/stat.h>
 #include <sys/mntent.h>
 #include <sys/ctfs.h>
 #include <sys/priv.h>

@@ -643,10 +644,62 @@
                 return (EFAULT);
 
         return (0);
 }
 
+int
+s10_sysinfo(sysret_t *rv, int command, char *buf, long count)
+{
+        char *value;
+        int err, len;
+
+        /*
+         * We must interpose on the sysinfo(2) commands SI_RELEASE and
+         * SI_VERSION; all others get passed to the native sysinfo(2)
+         * command.
+         */
+        switch (command) {
+                case SI_RELEASE:
+                        value = S10_UTS_RELEASE;
+                        break;
+
+                case SI_VERSION:
+                        value = S10_UTS_VERSION;
+                        break;
+
+                default:
+                        /*
+                         * The default action is to pass the command to the
+                         * native sysinfo(2) syscall.
+                         */
+                        if ((err = __systemcall(rv, SYS_systeminfo + 1024,
+                            command, buf, count)) != 0)
+                                return (err);
+
+                        return (0);
+        }
+
+        len = strlen(value) + 1;
+        if (count > 0) {
+                if (s10_uucopystr(value, buf, count) != 0)
+                        return (EFAULT);
+
+                /* Assure NULL termination of buf as s10_uucopystr() doesn't. */
+                if (len > count && s10_uucopy("\0", buf + (count - 1), 1) != 0)
+                        return (EFAULT);
+        }
+
+        /*
+         * On success, sysinfo(2) returns the size of buffer required to hold
+         * the complete value plus its terminating NULL byte.
+         */
+        rv->sys_rval1 = len;
+        rv->sys_rval2 = 0;
+        S10_TRUSS_POINT_3(rv, SYS_systeminfo, 0, command, buf, count);
+        return (0);
+}
+
 /*
  * If the emul_global_zone flag is set then emulate some aspects of the
  * zone system call.  In particular, emulate the global zone ID on the
  * ZONE_LOOKUP subcommand and emulate some of the global zone attributes
  * on the ZONE_GETATTR subcommand.  If the flag is not set or we're performing

@@ -1129,11 +1182,11 @@
         NOSYS,                                  /* 134 */
         EMULATE(s10_uname, 1 | RV_DEFAULT),     /* 135 */
         NOSYS,                                  /* 136 */
         NOSYS,                                  /* 137 */
         NOSYS,                                  /* 138 */
-        NOSYS,                                  /* 139 */
+        EMULATE(s10_sysinfo, 3 | RV_DEFAULT),   /* 139 */
         NOSYS,                                  /* 140 */
         NOSYS,                                  /* 141 */
         NOSYS,                                  /* 142 */
         NOSYS,                                  /* 143 */
         NOSYS,                                  /* 144 */