TheKraken
TheKraken

Reputation: 21

uname Syscall Missing Operating System String Present in uname -a Output

When I run uname -a on the command line, I get the following output:

Linux raspberrypi 5.10.63-v7l+ #1459 SMP Wed Oct 6 16:41:57 BST 2021 armv7l GNU/Linux

This is achieved by the -a parameter which is equivalent to using these parameters (there are 6) -snrvmo.

I am trying to replicate this using the uname() syscall in C. The manpage says the following about my uname() struct that is returned:

DESCRIPTION
       uname()  returns system information in the structure pointed to by buf.  The utsname struct is de‐
       fined in <sys/utsname.h>:

           struct utsname {
               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 */
           #ifdef _GNU_SOURCE
               char domainname[]; /* NIS or YP domain name */
           #endif
           };

You'll notice there is no operating system string corresponding to the the command line uname -o option. uname --help shows there is a -o parameter to display the OS and that doesn't seem to be available in the struct returned by the uname() syscall.

-o, --operating-system  
       print the operating system

So the best I can seem to do is get the following information using the syscall noting that "GNU/Linux" isn't at the end like what is given by uname -a:

Linux raspberrypi 5.10.63-v7l+ #1459 SMP Wed Oct 6 16:41:57 BST 2021 armv7l

Is there a way I can get the OS name (in this case, "GNU/Linux") in my C program like I can using uname -o?
My source code is essentially this

Upvotes: 1

Views: 278

Answers (1)

Mathieu
Mathieu

Reputation: 9659

You can read the uname code here: https://github.com/MaiZure/coreutils-8.3/blob/master/src/uname.c

In that code, is written:

  if (toprint
       & (PRINT_KERNEL_NAME | PRINT_NODENAME | PRINT_KERNEL_RELEASE
          | PRINT_KERNEL_VERSION | PRINT_MACHINE))
    {
      struct utsname name;

      if (uname (&name) == -1)
        die (EXIT_FAILURE, errno, _("cannot get system name"));

      if (toprint & PRINT_KERNEL_NAME)
        print_element (name.sysname);
      if (toprint & PRINT_NODENAME)
        print_element (name.nodename);
      if (toprint & PRINT_KERNEL_RELEASE)
        print_element (name.release);
      if (toprint & PRINT_KERNEL_VERSION)
        print_element (name.version);
      if (toprint & PRINT_MACHINE)
        print_element (name.machine);
    }

We can understand that in that word: "If have to print kernel info, or node or machine, use uname syscall".

The Operating system is printed latter:

  if (toprint & PRINT_OPERATING_SYSTEM)
    print_element (HOST_OPERATING_SYSTEM);

The HOST_OPERATING_SYSTEM is defined in gnulib

Is there a way I can get the OS name (in this case, "GNU/Linux") in my C program like I can using uname -o?

Since one compiled software can only be used by one OS, you can imagine to set it at build time.

Upvotes: 3

Related Questions