File Coverage

blib/lib/System/Info/Darwin.pm
Criterion Covered Total %
statement 54 56 96.4
branch 12 16 75.0
condition 14 25 56.0
subroutine 6 6 100.0
pod 1 1 100.0
total 87 104 83.6


line stmt bran cond sub pod time code
1             package System::Info::Darwin;
2              
3 3     3   326158 use strict;
  3         5  
  3         135  
4 3     3   17 use warnings;
  3         5  
  3         223  
5              
6 3     3   18 use base "System::Info::BSD";
  3         5  
  3         3889  
7              
8             our $VERSION = "0.056";
9              
10             =head1 NAME
11              
12             System::Info::Darwin - Object for specific Darwin info.
13              
14             =head1 DESCRIPTION
15              
16             =head2 $si->prepare_sysinfo
17              
18             Use os-specific tools to find out more about the system.
19              
20             =cut
21              
22             sub prepare_sysinfo {
23 4     4 1 9 my $self = shift;
24 4         20 $self->System::Info::Base::prepare_sysinfo ();
25              
26 4         11 $self->{__os} .= " (Mac OS X)";
27              
28 4         15 my $scl = __get_sysctl ();
29              
30 4 50       24 my $system_profiler = __get_system_profiler () or
31             return $self->SUPER::prepare_sysinfo ();
32              
33 4         47 $self->{__system_profiler} = $system_profiler;
34 4 50       22 if (my $kv = $system_profiler->{"system version"}) {
35 0         0 $self->{__os} =~ s{\)$}{ - $kv)};
36             }
37              
38             # This is physical processors (sockets) which os not returned anywhere for Apple Silicon (implied 1)
39 4   100     21 my $ncpu = $system_profiler->{"number of cpus"} || 1;
40 4 100       24 $system_profiler->{"total number of cores"} and
41             $ncpu .= " [$system_profiler->{'total number of cores'} cores]";
42              
43             # Confusingly, System::Info uses "cpu_type" for architecture and Apple uses
44             # "CPU Type" as the CPU model name. They are not the same thing.
45             $self->{__cpu} = $system_profiler->{chip} ||
46 4   66     51 $system_profiler->{"cpu type"};
47             $self->{__cpu} .= " ($system_profiler->{'cpu speed'})"
48 4 100       20 if $system_profiler->{"cpu speed"};
49 4         15 $self->{__cpu_type} = $system_profiler->{arch};
50 4         38 $self->{__cpu_count} = $ncpu;
51             # _ncore reports hyperthreads for other platforms, so it would be
52             # hw.logicalcpu (or hw.logicalcpu_max which is the same unless the system
53             # has disabled cores).
54             # Alternative hw.ncpu is deprecated, keeping for ancient systems.
55 4   33     39 $self->{_ncore} = $scl->{"hw.logicalcpu"} || $scl->{"hw.ncpu"};
56 4   33     36 $self->{_phys_core} = $scl->{"hw.physicalcpu"} || $scl->{"hw.ncpu"};
57              
58 4   50     9 my $osv = do {
59             local $^W = 0;
60             `sw_vers -productVersion 2>/dev/null`;
61             } || "";
62 4         31780 chomp ($self->{__osvers} = $osv);
63              
64 4         41 $self->{__memsize} = $scl->{"hw.memsize"};
65              
66 4         2071 return $self;
67             } # prepare_sysinfo
68              
69             # System::Info::BSD.pm only uses hw
70             sub __get_sysctl {
71 4 50   4   328 my $sysctl_cmd = -x "/sbin/sysctl" ? "/sbin/sysctl" : "sysctl";
72 4         10 chomp (my @sysctl = do {
73 4         21 local $^W = 0;
74 4         38 `$sysctl_cmd -a 2>/dev/null`;
75             });
76 4         336191 my %sysctl = map { split m/\s*[:=]\s*/, $_, 2 } grep m/[:=]/ => @sysctl;
  3864         18025  
77 4         780 return \%sysctl;
78             } # __get_sysctl
79              
80             sub __get_system_profiler {
81 4 50   4   8 my $system_profiler_output = do {
82 4         51 local $^W = 0;
83 4         38 `/usr/sbin/system_profiler -detailLevel mini SPHardwareDataType SPSoftwareDataType 2>&1`;
84             } or return;
85              
86             # From RT#97441
87             # In Yosemite the system_profiler started emitting these warnings:
88             # 2015-07-24 06:54:06.842 system_profiler[59780:1318389] platformPluginDictionary: Can\'t get X86PlatformPlugin, return value 0
89             # They seem to be harmless, but annoying.
90             # Clean them out, but then warn about others from system_profiler.
91 4         164 $system_profiler_output =~ s/^\d{4}-\d\d-\d\d .+ system_profiler\[.+?\] platformPluginDictionary: Can't get X86PlatformPlugin, return value 0$//mg;
92 4         26 warn "Unexpected warning from system_profiler:\n$1\n"
93             while $system_profiler_output =~ /^(.+system_profiler.+)/mg;
94              
95 4         11 my %system_profiler;
96 4         360 $system_profiler{lc $1} = $2
97             while $system_profiler_output =~ m/^\s*([\w ]+):\s+(.+)$/gm;
98              
99             # convert newer output from Intel core duo
100 4         50 my %keymap = (
101             "processor name" => "cpu type",
102             "processor speed" => "cpu speed",
103             "model name" => "machine name",
104             "model identifier" => "machine model",
105             "number of processors" => "number of cpus",
106             "total number of cores" => "total number of cores",
107             );
108 4         24 for my $newkey (keys %keymap) {
109 24         45 my $oldkey = $keymap{$newkey};
110             exists $system_profiler{$newkey} and
111 24 100       80 $system_profiler{$oldkey} = delete $system_profiler{$newkey};
112             }
113              
114 4   66     33 chomp ($system_profiler{"cpu type"} ||= `uname -m`);
115 4   100     39 $system_profiler{"cpu speed"} ||= 0; # Mac M1 does not show CPU speed
116 4         22 $system_profiler{"cpu speed"} =~
117 0         0 s/(0(?:\.\d+)?)\s*GHz/sprintf "%d MHz", $1 * 1000/e;
118 4   50     16 $system_profiler{"cpu type"} ||= "Unknown";
119             $system_profiler{"cpu type"} =~ s/\s*\([\d.]+\)//
120 4 100       49 if $system_profiler{"cpu speed"};
121 4   33     47 chomp ($system_profiler{arch} ||= `uname -m`);
122 4   50     67 $system_profiler{arch} ||= "Unknown";
123 4         29 return \%system_profiler;
124             } # __get_system_profiler
125              
126             1;
127              
128             __END__