[GNU Manual] [POSIX requirement] [Linux man] [FreeBSD man]
Summary
uname - print system information
Lines of code: 377
Principal syscall: uname()
Support syscalls: None
Options: 22 (9 short and 13 long)
Spirtually linked to uname introduced in System V (1985)
Added to Shellutils in November 1992 [First version]
Number of revisions: 102 [Code Evolution]
decode_switches()
- Parses switches to settoprint
print_element()
- Prints the input data
die()
- Exit with mandatory non-zero error and message to stderrerror()
- Outputs error message to standard error with possible process terminationsysctl()
- Access kernel data at runtimesysctrlbyname()
- Access kernel data by field at runtimesysinfo()
- Gets system info strings (SunOS)
Setup
uname has several layers of initialization prior to main()
.
First, uname starts with a two-line file which sets the mode to UNAME_UNAME (similar to 'arch'). This means we'll process all options during parsing.
Second, the preprocessor determines which machine-dependent headers to include so that uname knows which functions to call for the non-portable features. The major variants mentioned are BSD, and Mach (Apple).
main() initializes the following:
toprint
- Integer bitfield of printing optionsname
- Contains the return value ofuname()
syscall
Parsing
Parsing is simple: What information should we collect and print. This is done by OR-masking the toprint
integer to reflect data. Each option reflects a bit. Invoking -a asserts all bits via UINT_MAX
.
Parsing failures
Parsing can only fail if an unknown option is used
This failure result in a short error message followed by the usage instructions.
Execution
The first step is to get the system information via the uname()
syscall. This returns a utsname structure containing most of the data that we need. These data are portable across POSIX compliant systems.
Now mask the bitfield for each of the fields we're interested in and print via puts()
. The fields should appear one after the next on a single line. Now me move to the non-portable information.
Non-portable fields
Two fields that require architecture specific techniques are the processor type and the hardware platform.
ProcessorWe try three ways to get the processor architecture until success:
- A
sysinfo()
syscall. This three argument variant is specific to Sun/Oracle Unix. - A
sysctl()
syscall. Specific for BSD-based systems. - A
sysctrlbyname()
for systems based on the Mach kernel (Apple). Apparentlysysctl()
isn't enough.
Platform information follows the same as the processor, except no work-around needed for Mach. First, we attempt
sysinfo()
, then we attempt sysctl()
.
Operating System
The final check is to pull the operating system information from HOST_OPERATING_SYSTEM, which should have been generated in your system's config.h
.
These non-portable checks cannot fail, they simply result in an output of 'unknown'
Failure case: If the uname()
syscall fails, the uname utility cannot complete