nativeUname function

Uname nativeUname()

Calls the native uname() function.

Implementation

Uname nativeUname() {
  // allocate a memory buffer for struct utsname - size value derived from this source
  // https://man7.org/linux/man-pages/man2/uname.2.html
  const len = 6 * 257; // maxium size
  const enumElements = 5;

  Pointer<Int8> data = calloc<Int8>(len);

  try {
    if (uname(data) != 0) {
      throw Exception('Calling uname() failed.');
    }

    // calculate _UTSNAME_LENGTH
    var utslen = 0;
    label:
    for (int i = 0; i < len; ++i) {
      if (data[i] == 0) {
        for (int j = i + 1; j < len; ++j) {
          if (data[j] != 0) {
            utslen = j;
            break label;
          }
        }
      }
    }

    var values = <String>[];

    // extract these 5 strings from the memory
    //
    // char sysname[];    /* Operating system name (e.g., "Linux") */
    // char nodename[];   /* Name within "some implementation-defined network" */
    // char release[];    /* Operating system release (e.g., "2.6.28") */
    // char version[];    /* Operating system version */
    // char machine[];    /* Hardware identifier */
    for (int i = 0; i < enumElements; ++i) {
      var start = utslen * i;
      StringBuffer buf = StringBuffer();
      for (int i = start; i < len; ++i) {
        if (data[i] == 0) {
          break;
        }
        buf.write(String.fromCharCode(data[i]));
      }
      values.add(buf.toString());
    }
    return Uname(values[0], values[1], values[2], values[3], values[4]);
  } finally {
    malloc.free(data);
  }
}