1# 2# This is not a runnable script, it is a Perl module, a collection of variables, subroutines, etc. 3# To get help about exported variables and subroutines, execute the following command: 4# 5# perldoc Uname.pm 6# 7# or see POD (Plain Old Documentation) embedded to the source... 8# 9# 10#//===----------------------------------------------------------------------===// 11#// 12#// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 13#// See https://llvm.org/LICENSE.txt for license information. 14#// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 15#// 16#//===----------------------------------------------------------------------===// 17# 18 19package Uname; 20 21use strict; 22use warnings; 23use warnings::register; 24use Exporter; 25 26use POSIX; 27use File::Glob ":glob"; 28use Net::Domain qw{}; 29 30# Following code does not work with Perl 5.6 on Linux* OS and Windows* OS: 31# 32# use if $^O eq "darwin", tools => qw{}; 33# 34# The workaround for Perl 5.6: 35# 36BEGIN { 37 if ( $^O eq "darwin" or $^O eq "linux" ) { 38 require tools; 39 import tools; 40 }; # if 41 if ( $^O eq "MSWin32" ) { 42 require Win32; 43 }; # if 44}; # BEGIN 45 46my $mswin = qr{\A(?:MSWin32|Windows_NT)\z}; 47 48my @posix = qw{ kernel_name fqdn kernel_release kernel_version machine }; 49 # Properties supported by POSIX::uname(). 50my @linux = 51 qw{ processor hardware_platform operating_system }; 52 # Properties reported by uname in Linux* OS. 53my @base = ( @posix, @linux ); 54 # Base properties. 55my @aux = 56 ( 57 qw{ host_name domain_name }, 58 map( "operating_system_$_", qw{ name release codename description } ) 59 ); 60 # Auxiliary properties. 61my @all = ( @base, @aux ); 62 # All the properties. 63my @meta = qw{ base_names all_names value }; 64 # Meta functions. 65 66our $VERSION = "0.07"; 67our @ISA = qw{ Exporter }; 68our @EXPORT = qw{}; 69our @EXPORT_OK = ( @all, @meta ); 70our %EXPORT_TAGS = 71 ( 72 base => [ @base ], 73 all => [ @all ], 74 meta => [ @meta ], 75 ); 76 77my %values; 78 # Hash of values. Some values are strings, some may be references to code which should be 79 # evaluated to get real value. This trick is implemented because call to Net::Domain::hostfqdn() 80 # is relatively slow. 81 82# Get values from POSIX::uname(). 83@values{ @posix } = POSIX::uname(); 84 85# On some systems POSIX::uname() returns "short" node name (without domain name). To be consistent 86# on all systems, we will get node name from alternative source. 87if ( $^O =~ m/cygwin/i ) { 88 # Function from Net::Domain module works well, but on Cygwin it prints to 89 # stderr "domainname: not found". So we will use environment variables for now. 90 $values{ fqdn } = lc( $ENV{ COMPUTERNAME } . "." . $ENV{ USERDNSDOMAIN } ); 91} else { 92 # On systems other than Cygwin, let us use Net::Domain::hostfqdn(), but do it only node name 93 # is really requested. 94 $values{ fqdn } = 95 sub { 96 my $fqdn = Net::Domain::hostfqdn(); # "fqdn" stands for "fully qualified domain name". 97 # On some systems POSIX::uname() and Net::Domain::hostfqdn() reports different names. 98 # Let us issue a warning if they significantly different. Names are insignificantly 99 # different if POSIX::uname() matches the beginning of Net::Domain::hostfqdn(). 100 if ( 101 $fqdn eq substr( $fqdn, 0, length( $fqdn ) ) 102 && 103 ( 104 length( $fqdn ) == length( $fqdn ) 105 || 106 substr( $fqdn, length( $fqdn ), 1 ) eq "." 107 ) 108 ) { 109 # Ok. 110 } else { 111 warnings::warnif( 112 "POSIX::uname() and Net::Domain::hostfqdn() reported different names: " . 113 "\"$values{ fqdn }\" and \"$fqdn\" respectively\n" 114 ); 115 }; # if 116 return $fqdn; 117 }; # sub 118}; # if 119 120if ( $^O =~ $mswin ) { 121 if ( 122 $values{ machine } =~ m{\A(?:x86|[56]86)\z} 123 and 124 exists( $ENV{ PROCESSOR_ARCHITECTURE } ) and $ENV{ PROCESSOR_ARCHITECTURE } eq "x86" 125 and 126 exists( $ENV{ PROCESSOR_ARCHITEW6432 } ) 127 ) { 128 if ( $ENV{ PROCESSOR_ARCHITEW6432 } eq "AMD64" ) { 129 $values{ machine } = "x86_64"; 130 }; # if 131 }; # if 132}; # if 133 134# Some values are not returned by POSIX::uname(), let us compute them. 135 136# processor. 137$values{ processor } = $values{ machine }; 138 139# hardware_platform. 140if ( 0 ) { 141} elsif ( $^O eq "linux" or $^O eq "freebsd" or $^O eq "netbsd" ) { 142 if ( 0 ) { 143 } elsif ( $values{ machine } =~ m{\Ai[3456]86\z} ) { 144 $values{ hardware_platform } = "i386"; 145 } elsif ( $values{ machine } =~ m{\A(x86_64|amd64)\z} ) { 146 $values{ hardware_platform } = "x86_64"; 147 } elsif ( $values{ machine } =~ m{\Aarmv7\D*\z} ) { 148 $values{ hardware_platform } = "arm"; 149 } elsif ( $values{ machine } =~ m{\Appc64le\z} ) { 150 $values{ hardware_platform } = "ppc64le"; 151 } elsif ( $values{ machine } =~ m{\Appc64\z} ) { 152 $values{ hardware_platform } = "ppc64"; 153 } elsif ( $values{ machine } =~ m{\Aaarch64\z} ) { 154 $values{ hardware_platform } = "aarch64"; 155 } elsif ( $values{ machine } =~ m{\Amips64\z} ) { 156 $values{ hardware_platform } = "mips64"; 157 } elsif ( $values{ machine } =~ m{\Amips\z} ) { 158 $values{ hardware_platform } = "mips"; 159 } elsif ( $values{ machine } =~ m{\Ariscv64\z} ) { 160 $values{ hardware_platform } = "riscv64"; 161 } else { 162 die "Unsupported machine (\"$values{ machine }\") returned by POSIX::uname(); stopped"; 163 }; # if 164} elsif ( $^O eq "darwin" ) { 165 if ( 0 ) { 166 } elsif ( $values{ machine } eq "x86" or $values{ machine } eq "i386" ) { 167 $values{ hardware_platform } = 168 sub { 169 my $platform = "i386"; 170 # Some OSes on Intel(R) 64 still reports "i386" machine. Verify it by using 171 # the value returned by 'sysctl -n hw.optional.x86_64'. On Intel(R) 64-bit systems the 172 # value == 1; on 32-bit systems the 'hw.optional.x86_64' property either does not exist 173 # or the value == 0. The path variable does not contain a path to sysctl when 174 # started by crontab. 175 my $sysctl = ( which( "sysctl" ) or "/usr/sbin/sysctl" ); 176 my $output; 177 debug( "Executing $sysctl..." ); 178 execute( [ $sysctl, "-n", "hw.optional.x86_64" ], -stdout => \$output, -stderr => undef ); 179 chomp( $output ); 180 if ( 0 ) { 181 } elsif ( "$output" eq "" or "$output" eq "0" ) { 182 $platform = "i386"; 183 } elsif ( "$output" eq "1" ) { 184 $platform = "x86_64"; 185 } else { 186 die "Unsupported value (\"$output\") returned by \"$sysctl -n hw.optional.x86_64\"; stopped"; 187 }; # if 188 return $platform; 189 }; # sub { 190 } elsif ( $values{ machine } eq "x86_64" ) { 191 # Some OS X* versions report "x86_64". 192 $values{ hardware_platform } = "x86_64"; 193 } else { 194 die "Unsupported machine (\"$values{ machine }\") returned by POSIX::uname(); stopped"; 195 }; # if 196} elsif ( $^O =~ $mswin ) { 197 if ( 0 ) { 198 } elsif ( $values{ machine } =~ m{\A(?:x86|[56]86)\z} ) { 199 $values{ hardware_platform } = "i386"; 200 } elsif ( $values{ machine } eq "x86_64" or $values{ machine } eq "amd64" ) { 201 # ActivePerl for IA-32 architecture returns "x86_64", while ActivePerl for Intel(R) 64 returns "amd64". 202 $values{ hardware_platform } = "x86_64"; 203 } else { 204 die "Unsupported machine (\"$values{ machine }\") returned by POSIX::uname(); stopped"; 205 }; # if 206} elsif ( $^O eq "cygwin" ) { 207 if ( 0 ) { 208 } elsif ( $values{ machine } =~ m{\Ai[3456]86\z} ) { 209 $values{ hardware_platform } = "i386"; 210 } elsif ( $values{ machine } eq "x86_64" ) { 211 $values{ hardware_platform } = "x86_64"; 212 } else { 213 die "Unsupported machine (\"$values{ machine }\") returned by POSIX::uname(); stopped"; 214 }; # if 215} else { 216 die "Unsupported OS (\"$^O\"); stopped"; 217}; # if 218 219# operating_system. 220if ( 0 ) { 221} elsif ( $values{ kernel_name } eq "Linux" ) { 222 $values{ operating_system } = "GNU/Linux"; 223 my $release; # Name of chosen "*-release" file. 224 my $bulk; # Content of release file. 225 # On Ubuntu, lsb-release is quite informative, e. g.: 226 # DISTRIB_ID=Ubuntu 227 # DISTRIB_RELEASE=9.04 228 # DISTRIB_CODENAME=jaunty 229 # DISTRIB_DESCRIPTION="Ubuntu 9.04" 230 # Try lsb-release first. But on some older systems lsb-release is not informative. 231 # It may contain just one line: 232 # LSB_VERSION="1.3" 233 $release = "/etc/lsb-release"; 234 if ( -e $release ) { 235 $bulk = read_file( $release ); 236 } else { 237 $bulk = ""; 238 }; # if 239 if ( $bulk =~ m{^DISTRIB_} ) { 240 # Ok, this lsb-release is informative. 241 $bulk =~ m{^DISTRIB_ID\s*=\s*(.*?)\s*$}m 242 or runtime_error( "$release: There is no DISTRIB_ID:", $bulk, "(eof)" ); 243 $values{ operating_system_name } = $1; 244 $bulk =~ m{^DISTRIB_RELEASE\s*=\s*(.*?)\s*$}m 245 or runtime_error( "$release: There is no DISTRIB_RELEASE:", $bulk, "(eof)" ); 246 $values{ operating_system_release } = $1; 247 $bulk =~ m{^DISTRIB_CODENAME\s*=\s*(.*?)\s*$}m 248 or runtime_error( "$release: There is no DISTRIB_CODENAME:", $bulk, "(eof)" ); 249 $values{ operating_system_codename } = $1; 250 $bulk =~ m{^DISTRIB_DESCRIPTION\s*="?\s*(.*?)"?\s*$}m 251 or runtime_error( "$release: There is no DISTRIB_DESCRIPTION:", $bulk, "(eof)" ); 252 $values{ operating_system_description } = $1; 253 } else { 254 # Oops. lsb-release is missed or not informative. Try other *-release files. 255 $release = "/etc/system-release"; 256 if ( not -e $release ) { # Use /etc/system-release" if such file exists. 257 # Otherwise try other "/etc/*-release" files, but ignore "/etc/lsb-release". 258 my @releases = grep( $_ ne "/etc/lsb-release", bsd_glob( "/etc/*-release" ) ); 259 # On some Fedora systems there are two files: fedora-release and redhat-release 260 # with identical content. If fedora-release present, ignore redjat-release. 261 if ( grep( $_ eq "/etc/fedora-release", @releases ) ) { 262 @releases = grep( $_ ne "/etc/redhat-release", @releases ); 263 }; # if 264 if ( @releases == 1 ) { 265 $release = $releases[ 0 ]; 266 } else { 267 if ( @releases == 0 ) { 268 # No *-release files found, try debian_version. 269 $release = "/etc/debian_version"; 270 if ( not -e $release ) { 271 $release = undef; 272 warning( "No release files found in \"/etc/\" directory." ); 273 }; # if 274 } else { 275 $release = undef; 276 warning( "More than one release files found in \"/etc/\" directory:", @releases ); 277 }; # if 278 }; # if 279 }; # if 280 if ( defined( $release ) ) { 281 $bulk = read_file( $release ); 282 if ( $release =~ m{system|redhat|fedora} ) { 283 # Red Hat or Fedora. Parse the first line of file. 284 # Typical values of *-release (one of): 285 # Red Hat Enterprise Linux* OS Server release 5.2 (Tikanga) 286 # Red Hat Enterprise Linux* OS AS release 3 (Taroon Update 4) 287 # Fedora release 10 (Cambridge) 288 $bulk =~ m{\A(.*)$}m 289 or runtime_error( "$release: Cannot find the first line:", $bulk, "(eof)" ); 290 my $first_line = $1; 291 $values{ operating_system_description } = $first_line; 292 $first_line =~ m{\A(.*?)\s+release\s+(.*?)(?:\s+\((.*?)(?:\s+Update\s+(.*?))?\))?\s*$} 293 or runtime_error( "$release:1: Cannot parse line:", $first_line ); 294 $values{ operating_system_name } = $1; 295 $values{ operating_system_release } = $2 . ( defined( $4 ) ? ".$4" : "" ); 296 $values{ operating_system_codename } = $3; 297 } elsif ( $release =~ m{SuSE} ) { 298 # Typical SuSE-release: 299 # SUSE Linux* OS Enterprise Server 10 (x86_64) 300 # VERSION = 10 301 # PATCHLEVEL = 2 302 $bulk =~ m{\A(.*)$}m 303 or runtime_error( "$release: Cannot find the first line:", $bulk, "(eof)" ); 304 my $first_line = $1; 305 $values{ operating_system_description } = $first_line; 306 $first_line =~ m{^(.*?)\s*(\d+)\s*\(.*?\)\s*$} 307 or runtime_error( "$release:1: Cannot parse line:", $first_line ); 308 $values{ operating_system_name } = $1; 309 $bulk =~ m{^VERSION\s*=\s*(.*)\s*$}m 310 or runtime_error( "$release: There is no VERSION:", $bulk, "(eof)" ); 311 $values{ operating_system_release } = $1; 312 if ( $bulk =~ m{^PATCHLEVEL\s*=\s*(.*)\s*$}m ) { 313 $values{ operating_system_release } .= ".$1"; 314 }; # if 315 } elsif ( $release =~ m{debian_version} ) { 316 # Debian. The file debian_version contains just version number, nothing more: 317 # 4.0 318 my $name = "Debian"; 319 $bulk =~ m{\A(.*)$}m 320 or runtime_error( "$release: Cannot find the first line:", $bulk, "(eof)" ); 321 my $version = $1; 322 $values{ operating_system_name } = $name; 323 $values{ operating_system_release } = $version; 324 $values{ operating_system_codename } = "unknown"; 325 $values{ operating_system_description } = sprintf( "%s %s", $name, $version ); 326 }; # if 327 }; # if 328 }; # if 329 if ( not defined( $values{ operating_system_name } ) ) { 330 $values{ operating_system_name } = "GNU/Linux"; 331 }; # if 332} elsif ( $values{ kernel_name } eq "Darwin" ) { 333 my %codenames = ( 334 10.4 => "Tiger", 335 10.5 => "Leopard", 336 10.6 => "Snow Leopard", 337 ); 338 my $darwin; 339 my $get_os_info = 340 sub { 341 my ( $name ) = @_; 342 if ( not defined $darwin ) { 343 $darwin->{ operating_system } = "Darwin"; 344 # sw_vers prints OS X* version to stdout: 345 # ProductName: OS X* 346 # ProductVersion: 10.4.11 347 # BuildVersion: 8S2167 348 # It does not print codename, so we code OS X* codenames here. 349 my $sw_vers = which( "sw_vers" ) || "/usr/bin/sw_vers"; 350 my $output; 351 debug( "Executing $sw_vers..." ); 352 execute( [ $sw_vers ], -stdout => \$output, -stderr => undef ); 353 $output =~ m{^ProductName:\s*(.*)\s*$}m 354 or runtime_error( "There is no ProductName in sw_vers output:", $output, "(eof)" ); 355 my $name = $1; 356 $output =~ m{^ProductVersion:\s*(.*)\s*$}m 357 or runtime_error( "There is no ProductVersion in sw_vers output:", $output, "(eof)" ); 358 my $release = $1; 359 # Sometimes release reported as "10.4.11" (3 components), sometimes as "10.6". 360 # Handle both variants. 361 $release =~ m{^(\d+.\d+)(?:\.\d+)?(?=\s|$)} 362 or runtime_error( "Cannot parse OS X* version: $release" ); 363 my $version = $1; 364 my $codename = ( $codenames{ $version } or "unknown" ); 365 $darwin->{ operating_system_name } = $name; 366 $darwin->{ operating_system_release } = $release; 367 $darwin->{ operating_system_codename } = $codename; 368 $darwin->{ operating_system_description } = sprintf( "%s %s (%s)", $name, $release, $codename ); 369 }; # if 370 return $darwin->{ $name }; 371 }; # sub 372 $values{ operating_system } = sub { $get_os_info->( "operating_system" ); }; 373 $values{ operating_system_name } = sub { $get_os_info->( "operating_system_name" ); }; 374 $values{ operating_system_release } = sub { $get_os_info->( "operating_system_release" ); }; 375 $values{ operating_system_codename } = sub { $get_os_info->( "operating_system_codename" ); }; 376 $values{ operating_system_description } = sub { $get_os_info->( "operating_system_description" ); }; 377} elsif ( $values{ kernel_name } =~ m{\AWindows[ _]NT\z} ) { 378 $values{ operating_system } = "MS Windows"; 379 # my @os_name = Win32::GetOSName(); 380 # $values{ operating_system_release } = $os_name[ 0 ]; 381 # $values{ operating_system_update } = $os_name[ 1 ]; 382} elsif ( $values{ kernel_name } =~ m{\ACYGWIN_NT-} ) { 383 $values{ operating_system } = "MS Windows"; 384} elsif ( $values{ kernel_name } =~ m{\AFreeBSD} ) { 385 $values{ operating_system } = "FreeBSD"; 386} elsif ( $values{ kernel_name } =~ m{\ANetBSD} ) { 387 $values{ operating_system } = "NetBSD"; 388} else { 389 die "Unsupported kernel_name (\"$values{ kernel_name }\") returned by POSIX::uname(); stopped"; 390}; # if 391 392# host_name and domain_name 393$values{ host_name } = 394 sub { 395 my $fqdn = value( "fqdn" ); 396 $fqdn =~ m{\A([^.]*)(?:\.(.*))?\z}; 397 my $host_name = $1; 398 if ( not defined( $host_name ) or $host_name eq "" ) { 399 die "Unexpected error: undefined or empty host name; stopped"; 400 }; # if 401 return $host_name; 402 }; 403$values{ domain_name } = 404 sub { 405 my $fqdn = value( "fqdn" ); 406 $fqdn =~ m{\A([^.]*)(?:\.(.*))?\z}; 407 my $domain_name = $2; 408 if ( not defined( $domain_name ) or $domain_name eq "" ) { 409 die "Unexpected error: undefined or empty domain name; stopped"; 410 }; # if 411 return $domain_name; 412 }; 413 414# Replace undefined values with "unknown". 415foreach my $name ( @all ) { 416 if ( not defined( $values{ $name } ) ) { 417 $values{ $name } = "unknown"; 418 }; # if 419}; # foreach $name 420 421# Export functions reporting properties. 422foreach my $name ( @all ) { 423 no strict "refs"; 424 *$name = sub { return value( $name ); }; 425}; # foreach $name 426 427# This function returns base names. 428sub base_names { 429 return @base; 430}; # sub base_names 431 432# This function returns all the names. 433sub all_names { 434 return @all; 435}; # sub all_names 436 437# This function returns value by the specified name. 438sub value($) { 439 my $name = shift( @_ ); 440 if ( ref( $values{ $name } ) ) { 441 my $value = $values{ $name }->(); 442 $values{ $name } = $value; 443 }; # if 444 return $values{ $name }; 445}; # sub value 446 447return 1; 448 449__END__ 450 451=pod 452 453=head1 NAME 454 455B<Uname.pm> -- A few subroutines to get system information usually provided by 456C</bin/uname> and C<POSIX::uname()>. 457 458=head1 SYNOPSIS 459 460 use Uname; 461 462 # Base property functions. 463 $kernel_name = Uname::kernel_name(); 464 $fqdn = Uname::fqdn(); 465 $kernel_release = Uname::kernel_release(); 466 $kernel_version = Uname::kernel_version(); 467 $machine = Uname::machine(); 468 $processor = Uname::processor(); 469 $hardware_platform = Uname::hardware_platform(); 470 $operating_system = Uname::operating_system(); 471 472 # Auxiliary property functions. 473 $host_name = Uname::host_name(); 474 $domain_name = Uname::domain_name(); 475 $os_name = Uname::operating_system_name(); 476 $os_release = Uname::operating_system_release(); 477 $os_codename = Uname::operating_system_codename(); 478 $os_description = Uname::operating_system_description(); 479 480 # Meta functions. 481 @base_names = Uname::base_names(); 482 @all_names = Uname::all_names(); 483 $kernel_name = Uname::value( "kernel_name" ); 484 485=head1 DESCRIPTION 486 487B<Uname.pm> resembles functionality found in C<POSIX::uname()> function or in C<uname> program. 488However, both C<POSIX::uname()> and C</bin/uname> have some disadvantages: 489 490=over 491 492=item * 493 494C<uname> may be not available in some environments, for example, in Windows* OS 495(C<uname> may be found in some third-party software packages, like MKS Toolkit or Cygwin, but it is 496not a part of OS). 497 498=item * 499 500There are many different versions of C<uname>. For example, C<uname> on OS X* does not 501recognize options C<-i>, C<-o>, and any long options. 502 503=item * 504 505Different versions of C<uname> may report the same property differently. For example, 506C<uname> on Linux* OS reports machine as C<i686>, while C<uname> on OS X* reports the same machine as 507C<x86>. 508 509=item * 510 511C<POSIX::uname()> returns list of values. I cannot recall what is the fourth element of the list. 512 513=back 514 515=head2 Base Functions 516 517Base property functions provide the information as C<uname> program. 518 519=over 520 521=item B<kernel_name()> 522 523Returns the kernel name, as reported by C<POSIX::uname()>. 524 525=item B<fqdn()> 526 527Returns the FQDN, fully qualified domain name. On some systems C<POSIX::uname()> reports short node 528name (with no domain name), on others C<POSIX::uname()> reports full node name. This 529function strive to return FQDN always (by refining C<POSIX::uname()> with 530C<Net::Domain::hostfqdn()>). 531 532=item B<kernel_release()> 533 534Returns the kernel release string, as reported by C<POSIX::uname()>. Usually the string consists of 535several numbers, separated by dots and dashes, but may also include some non-numeric substrings like 536"smp". 537 538=item B<kernel_version()> 539 540Returns the kernel version string, as reported by C<POSIX::uname()>. It is B<not> several 541dot-separated numbers but much longer string describing the kernel. 542For example, on Linux* OS it includes build date. 543If you look for something identifying the kernel, look at L<kernel_release>. 544 545=item B<machine()> 546 547Returns the machine hardware name, as reported by POSIX::uname(). Not reliable. Different OSes may 548report the same machine hardware name differently. For example, Linux* OS reports C<i686>, while OS X* 549reports C<x86> on the same machine. 550 551=item B<processor()> 552 553Returns the processor type. Not reliable. Usually the same as C<machine>. 554 555=item B<hardware_platform()> 556 557One of: C<i386> or C<x86_64>. 558 559=item B<operating_system()> 560 561One of: C<GNU/Linux>, C<OS X*>, or C<MS Windows>. 562 563=back 564 565=head2 Auxiliary Functions 566 567Auxiliary functions extends base functions with information not reported by C<uname> program. 568 569Auxiliary functions collect information from different sources. For example, on OS X*, they may 570call C<sw_vers> program to find out OS release; on Linux* OS they may parse C</etc/redhat-release> file, 571etc. 572 573=over 574 575=item B<host_name()> 576 577Returns host name (FQDN with dropped domain part). 578 579=item B<domain_name()> 580 581Returns domain name (FQDN with dropped host part). 582 583=item B<operating_system_name> 584 585Name of operating system or name of Linux* OS distribution, like "Fedora" or 586"Red Hat Enterprise Linux* OS Server". 587 588=item B<operating_system_release> 589 590Release (version) of operating system or Linux* OS distribution. Usually it is a series of 591dot-separated numbers. 592 593=item B<operating_system_codename> 594 595Codename of operating system release or Linux* OS distribution. For example, Fedora 10 is "Cambridge" 596while OS X* 10.4 is "Tiger". 597 598=item B<operating_system_description> 599 600Longer string. Usually it includes all the operating system properting mentioned above -- name, 601release, codename in parentheses. 602 603=back 604 605=head2 Meta Functions 606 607=over 608 609=item B<base_names()> 610 611This function returns the list of base property names. 612 613=item B<all_names()> 614 615This function returns the list of all property names. 616 617=item B<value(> I<name> B<)> 618 619This function returns the value of the property specified by I<name>. 620 621=back 622 623=head1 EXAMPLES 624 625 use Uname; 626 627 print( Uname::string(), "\n" ); 628 629 foreach my $name ( Uname::all_names() ) { 630 print( "$name=\"" . Uname::value( $name ) . "\"\n" ); 631 }; # foreach $name 632 633=head1 SEE ALSO 634 635L<POSIX::uname>, L<uname>. 636 637=cut 638 639# end of file # 640 641