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