1313
1414#define FF_CPUINFO_PATH "/proc/cpuinfo"
1515
16- static double parseHwmonDir ( FFstrbuf * dir , FFstrbuf * buffer )
16+ static double parseTZDir ( int dfd , FFstrbuf * buffer )
1717{
18- //https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
19- uint32_t dirLength = dir -> length ;
20- ffStrbufAppendS (dir , "temp1_input" );
18+ if (!ffReadFileBufferRelative (dfd , "temp" , buffer ))
19+ return FF_CPU_TEMP_UNSET ;
2120
22- if (!ffReadFileBuffer (dir -> chars , buffer ))
23- {
24- // Some badly implemented system put temp file in /hwmonN/device
25- ffStrbufSubstrBefore (dir , dirLength );
26- ffStrbufAppendS (dir , "device/" );
27- dirLength = dir -> length ;
28- ffStrbufAppendS (dir , "temp1_input" );
29-
30- if (!ffReadFileBuffer (dir -> chars , buffer ))
31- return FF_CPU_TEMP_UNSET ;
32- }
21+ double value = ffStrbufToDouble (buffer , FF_CPU_TEMP_UNSET );// millidegree Celsius
22+ if (value == FF_CPU_TEMP_UNSET )
23+ return FF_CPU_TEMP_UNSET ;
3324
34- ffStrbufSubstrBefore (dir , dirLength );
25+ if (!ffReadFileBufferRelative (dfd , "type" , buffer ) || ffStrbufStartsWithS (buffer , "cpu" ))
26+ return FF_CPU_TEMP_UNSET ;
3527
36- double value = ffStrbufToDouble (buffer , FF_CPU_TEMP_UNSET );// millidegree Celsius
28+ return value / 1000. ;
29+ }
30+
31+ static double parseHwmonDir (int dfd , FFstrbuf * buffer )
32+ {
33+ //https://www.kernel.org/doc/Documentation/hwmon/sysfs-interface
34+ if (!ffReadFileBufferRelative (dfd , "temp1_input" , buffer ))
35+ return FF_CPU_TEMP_UNSET ;
3736
37+ double value = ffStrbufToDouble (buffer , FF_CPU_TEMP_UNSET );// millidegree Celsius
3838 if (value == FF_CPU_TEMP_UNSET )
3939 return FF_CPU_TEMP_UNSET ;
4040
41- ffStrbufAppendS (dir , "name" );
42- if (!ffReadFileBuffer (dir -> chars , buffer ))
41+ if (!ffReadFileBufferRelative (dfd , "temp1_label" , buffer ))
4342 return FF_CPU_TEMP_UNSET ;
4443
4544 ffStrbufTrimRightSpace (buffer );
@@ -49,55 +48,86 @@ static double parseHwmonDir(FFstrbuf* dir, FFstrbuf* buffer)
4948 #if __x86_64__ || __i386__
5049 ffStrbufEqualS (buffer , "k10temp" ) || // AMD
5150 ffStrbufEqualS (buffer , "fam15h_power" ) || // AMD
52- ffStrbufEqualS (buffer , "coretemp" ) // Intel
53- #else
54- ffStrbufEqualS (buffer , "temp" ) // Asahi
51+ ffStrbufEqualS (buffer , "coretemp" ) || // Intel
5552 #endif
53+ false
5654 ) return value / 1000. ;
5755
5856 return FF_CPU_TEMP_UNSET ;
5957}
6058
61- static double detectTZTemp (FFstrbuf * buffer )
62- {
63- if (ffReadFileBuffer ("/sys/class/thermal/thermal_zone0/temp" , buffer ))
64- {
65- double value = ffStrbufToDouble (buffer , FF_CPU_TEMP_UNSET );// millidegree Celsius
66- return value != FF_CPU_TEMP_UNSET ? value / 1000. : FF_CPU_TEMP_UNSET ;
67- }
68- return FF_CPU_TEMP_UNSET ;
69- }
70-
7159static double detectCPUTemp (void )
7260{
73- FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA (64 );
74- ffStrbufAppendS (& baseDir , "/sys/class/hwmon/" );
75-
7661 FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate ();
62+ {
63+ FF_AUTO_CLOSE_DIR DIR * dirp = opendir ("/sys/class/hwmon/" );
64+ if (dirp )
65+ {
66+ int dfd = dirfd (dirp );
67+ struct dirent * entry ;
68+ while ((entry = readdir (dirp )) != NULL )
69+ {
70+ if (entry -> d_name [0 ] == '.' )
71+ continue ;
7772
78- uint32_t baseDirLength = baseDir .length ;
79-
80- FF_AUTO_CLOSE_DIR DIR * dirp = opendir (baseDir .chars );
81- if (dirp == NULL )
82- return FF_CPU_TEMP_UNSET ;
73+ FF_AUTO_CLOSE_FD int subfd = openat (dfd , entry -> d_name , O_RDONLY | O_DIRECTORY | O_CLOEXEC );
74+ if (subfd < 0 )
75+ continue ;
8376
84- struct dirent * entry ;
85- while ((entry = readdir (dirp )) != NULL )
77+ double result = parseHwmonDir (subfd , & buffer );
78+ if (result != FF_CPU_TEMP_UNSET )
79+ return result ;
80+ }
81+ }
82+ }
8683 {
87- if (entry -> d_name [0 ] == '.' )
88- continue ;
84+ FF_AUTO_CLOSE_DIR DIR * dirp = opendir ("/sys/class/thermal/" );
85+ if (dirp )
86+ {
87+ int dfd = dirfd (dirp );
88+ struct dirent * entry ;
89+ while ((entry = readdir (dirp )) != NULL )
90+ {
91+ if (entry -> d_name [0 ] == '.' )
92+ continue ;
93+ if (!ffStrStartsWith (entry -> d_name , "thermal_zone" ))
94+ continue ;
95+
96+ FF_AUTO_CLOSE_FD int subfd = openat (dfd , entry -> d_name , O_RDONLY | O_DIRECTORY | O_CLOEXEC );
97+ if (subfd < 0 )
98+ continue ;
8999
90- ffStrbufAppendS (& baseDir , entry -> d_name );
91- ffStrbufAppendC (& baseDir , '/' );
100+ double result = parseTZDir (subfd , & buffer );
101+ if (result != FF_CPU_TEMP_UNSET )
102+ return result ;
103+ }
104+ }
105+ }
106+ {
107+ FF_AUTO_CLOSE_DIR DIR * dirp = opendir ("/sys/devices/platform/" );
108+ if (dirp )
109+ {
110+ int dfd = dirfd (dirp );
111+ struct dirent * entry ;
112+ while ((entry = readdir (dirp )) != NULL )
113+ {
114+ if (entry -> d_name [0 ] == '.' )
115+ continue ;
116+ if (!ffStrStartsWith (entry -> d_name , "cputemp." ))
117+ continue ;
92118
93- double result = parseHwmonDir ( & baseDir , & buffer );
94- if ( result != FF_CPU_TEMP_UNSET )
95- return result ;
119+ FF_AUTO_CLOSE_FD int subfd = openat ( dfd , entry -> d_name , O_RDONLY | O_DIRECTORY | O_CLOEXEC );
120+ if ( subfd < 0 )
121+ continue ;
96122
97- ffStrbufSubstrBefore (& baseDir , baseDirLength );
123+ double result = parseHwmonDir (subfd , & buffer );
124+ if (result != FF_CPU_TEMP_UNSET )
125+ return result ;
126+ }
127+ }
98128 }
99129
100- return detectTZTemp ( & buffer ) ;
130+ return FF_CPU_TEMP_UNSET ;
101131}
102132
103133#ifdef __ANDROID__
0 commit comments