2009-10-11 20:11:09 +00:00
// vim:ts=8:expandtab
# include <stdlib.h>
# include <limits.h>
# include <stdio.h>
# include <string.h>
2012-03-25 18:55:55 +00:00
# include <yajl/yajl_gen.h>
2012-04-08 12:05:47 +00:00
# include <yajl/yajl_version.h>
2009-10-11 20:11:09 +00:00
# include "i3status.h"
2014-08-04 14:54:08 +00:00
# if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2009-10-11 20:11:09 +00:00
# include <err.h>
# include <sys/types.h>
# include <sys/sysctl.h>
# define TZ_ZEROC 2732
# define TZ_KELVTOC(x) (((x) - TZ_ZEROC) / 10), abs(((x) - TZ_ZEROC) % 10)
2013-03-19 18:08:35 +00:00
# define TZ_AVG(x) ((x) - TZ_ZEROC) / 10
2009-10-11 20:11:09 +00:00
# endif
2014-08-04 14:54:08 +00:00
# if defined(__DragonFly__)
# include <sys/sysctl.h>
# include <sys/types.h>
# include <sys/sensors.h>
# define MUKTOC(v) ((v - 273150000) / 1000000.0)
# endif
2012-04-29 14:59:39 +00:00
# if defined(__OpenBSD__)
# include <sys/param.h>
# include <sys/types.h>
# include <sys/sysctl.h>
# include <sys/sensors.h>
# include <errno.h>
# include <err.h>
2012-10-10 07:57:32 +00:00
# define MUKTOC(v) ((v - 273150000) / 1000000.0)
2012-04-29 14:59:39 +00:00
# endif
2013-10-06 21:18:53 +00:00
# if defined(__NetBSD__)
# include <fcntl.h>
# include <prop/proplib.h>
# include <sys/envsys.h>
# define MUKTOC(v) ((v - 273150000) / 1000000.0)
# endif
2009-10-11 20:11:09 +00:00
/*
2014-02-25 19:43:48 +00:00
* Reads the CPU temperature from / sys / class / thermal / thermal_zone % d / temp ( or
* the user provided path ) and returns the temperature in degree celcius .
2009-10-11 20:11:09 +00:00
*
*/
2012-10-10 07:57:32 +00:00
void print_cpu_temperature_info ( yajl_gen json_gen , char * buffer , int zone , const char * path , const char * format , int max_threshold ) {
2013-02-28 13:15:22 +00:00
char * outwalk = buffer ;
2011-07-24 21:17:34 +00:00
# ifdef THERMAL_ZONE
2009-10-11 20:11:09 +00:00
const char * walk ;
2013-01-13 12:23:43 +00:00
bool colorful_output = false ;
2014-02-25 19:43:48 +00:00
char * thermal_zone ;
2009-10-11 20:11:09 +00:00
2014-02-25 19:43:48 +00:00
if ( path = = NULL )
asprintf ( & thermal_zone , THERMAL_ZONE , zone ) ;
else
asprintf ( & thermal_zone , path , zone ) ;
2009-10-11 20:11:09 +00:00
2014-02-25 19:43:48 +00:00
INSTANCE ( thermal_zone ) ;
2012-02-16 23:29:29 +00:00
2009-10-11 20:11:09 +00:00
for ( walk = format ; * walk ! = ' \0 ' ; walk + + ) {
if ( * walk ! = ' % ' ) {
2012-03-25 18:55:55 +00:00
* ( outwalk + + ) = * walk ;
2009-10-11 20:11:09 +00:00
continue ;
}
if ( BEGINS_WITH ( walk + 1 , " degrees " ) ) {
# if defined(LINUX)
2013-01-28 10:37:23 +00:00
static char buf [ 16 ] ;
2009-10-11 20:11:09 +00:00
long int temp ;
2014-02-25 19:43:48 +00:00
if ( ! slurp ( thermal_zone , buf , sizeof ( buf ) ) )
2011-08-25 21:24:06 +00:00
goto error ;
2009-10-11 20:11:09 +00:00
temp = strtol ( buf , NULL , 10 ) ;
if ( temp = = LONG_MIN | | temp = = LONG_MAX | | temp < = 0 )
2012-03-25 18:55:55 +00:00
* ( outwalk + + ) = ' ? ' ;
2012-10-16 08:52:57 +00:00
else {
if ( ( temp / 1000 ) > = max_threshold ) {
START_COLOR ( " color_bad " ) ;
colorful_output = true ;
}
2012-03-25 18:55:55 +00:00
outwalk + = sprintf ( outwalk , " %ld " , ( temp / 1000 ) ) ;
2013-01-13 12:23:43 +00:00
if ( colorful_output ) {
2012-10-16 08:52:57 +00:00
END_COLOR ;
2013-01-13 12:23:43 +00:00
colorful_output = false ;
}
2012-10-16 08:52:57 +00:00
}
2014-08-04 14:54:08 +00:00
# elif defined(__DragonFly__)
struct sensor th_sensor ;
size_t th_sensorlen ;
th_sensorlen = sizeof ( th_sensor ) ;
if ( sysctlbyname ( thermal_zone , & th_sensor , & th_sensorlen , NULL , 0 ) = = - 1 ) {
perror ( " sysctlbyname " ) ;
goto error ;
}
if ( MUKTOC ( th_sensor . value ) > = max_threshold ) {
START_COLOR ( " color_bad " ) ;
colorful_output = true ;
}
outwalk + = sprintf ( outwalk , " %.2f " , MUKTOC ( th_sensor . value ) ) ;
if ( colorful_output ) {
END_COLOR ;
colorful_output = false ;
}
# elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
2009-10-11 20:11:09 +00:00
int sysctl_rslt ;
size_t sysctl_size = sizeof ( sysctl_rslt ) ;
2014-02-25 19:43:48 +00:00
if ( sysctlbyname ( thermal_zone , & sysctl_rslt , & sysctl_size , NULL , 0 ) )
2011-08-25 21:24:06 +00:00
goto error ;
2009-10-11 20:11:09 +00:00
2013-03-19 18:08:35 +00:00
if ( TZ_AVG ( sysctl_rslt ) > = max_threshold ) {
START_COLOR ( " color_bad " ) ;
colorful_output = true ;
}
2012-03-25 18:55:55 +00:00
outwalk + = sprintf ( outwalk , " %d.%d " , TZ_KELVTOC ( sysctl_rslt ) ) ;
2013-03-19 18:08:35 +00:00
if ( colorful_output ) {
END_COLOR ;
colorful_output = false ;
}
2012-04-29 14:59:39 +00:00
# elif defined(__OpenBSD__)
2013-01-28 10:37:23 +00:00
struct sensordev sensordev ;
struct sensor sensor ;
size_t sdlen , slen ;
int dev , numt , mib [ 5 ] = { CTL_HW , HW_SENSORS , 0 , 0 , 0 } ;
2012-04-29 14:59:39 +00:00
2013-01-28 10:37:23 +00:00
sdlen = sizeof ( sensordev ) ;
slen = sizeof ( sensor ) ;
2012-04-29 14:59:39 +00:00
2013-01-28 10:37:23 +00:00
for ( dev = 0 ; ; dev + + ) {
mib [ 2 ] = dev ;
if ( sysctl ( mib , 3 , & sensordev , & sdlen , NULL , 0 ) = = - 1 ) {
if ( errno = = ENXIO )
continue ;
if ( errno = = ENOENT )
break ;
goto error ;
}
/* 'path' is the node within the full path (defaults to acpitz0). */
2014-03-11 19:15:36 +00:00
if ( BEGINS_WITH ( sensordev . xname , thermal_zone ) ) {
2013-01-28 10:37:23 +00:00
mib [ 3 ] = SENSOR_TEMP ;
/* Limit to temo0, but should retrieve from a full path... */
for ( numt = 0 ; numt < 1 /*sensordev.maxnumt[SENSOR_TEMP]*/ ; numt + + ) {
mib [ 4 ] = numt ;
if ( sysctl ( mib , 5 , & sensor , & slen , NULL , 0 ) = = - 1 ) {
if ( errno ! = ENOENT ) {
warn ( " sysctl " ) ;
continue ;
}
}
if ( ( int ) MUKTOC ( sensor . value ) > = max_threshold ) {
START_COLOR ( " color_bad " ) ;
colorful_output = true ;
}
2012-10-10 07:57:32 +00:00
2013-01-28 10:37:23 +00:00
outwalk + = sprintf ( outwalk , " %.2f " , MUKTOC ( sensor . value ) ) ;
2012-10-10 07:57:32 +00:00
2013-01-28 10:37:23 +00:00
if ( colorful_output ) {
END_COLOR ;
2013-01-13 12:23:43 +00:00
colorful_output = false ;
}
2013-01-28 10:37:23 +00:00
}
}
}
2013-10-06 21:18:53 +00:00
# elif defined(__NetBSD__)
int fd , rval ;
bool err = false ;
prop_dictionary_t dict ;
prop_array_t array ;
prop_object_iterator_t iter ;
prop_object_iterator_t iter2 ;
prop_object_t obj , obj2 , obj3 ;
fd = open ( " /dev/sysmon " , O_RDONLY ) ;
if ( fd = = - 1 )
goto error ;
rval = prop_dictionary_recv_ioctl ( fd , ENVSYS_GETDICTIONARY , & dict ) ;
if ( rval = = - 1 ) {
err = true ;
goto error_netbsd1 ;
}
/* No drivers registered? */
if ( prop_dictionary_count ( dict ) = = 0 ) {
err = true ;
goto error_netbsd2 ;
}
iter = prop_dictionary_iterator ( dict ) ;
if ( iter = = NULL ) {
err = true ;
goto error_netbsd2 ;
}
/* iterate over the dictionary returned by the kernel */
while ( ( obj = prop_object_iterator_next ( iter ) ) ! = NULL ) {
2014-04-29 22:30:11 +00:00
/* skip this dict if it's not what we're looking for */
if ( ( strlen ( prop_dictionary_keysym_cstring_nocopy ( obj ) ) ! = strlen ( thermal_zone ) ) | |
( strncmp ( thermal_zone ,
prop_dictionary_keysym_cstring_nocopy ( obj ) ,
strlen ( thermal_zone ) ) ! = 0 ) )
continue ;
2013-10-06 21:18:53 +00:00
array = prop_dictionary_get_keysym ( dict , obj ) ;
if ( prop_object_type ( array ) ! = PROP_TYPE_ARRAY ) {
err = true ;
goto error_netbsd3 ;
}
2014-04-29 22:30:11 +00:00
2013-10-06 21:18:53 +00:00
iter2 = prop_array_iterator ( array ) ;
if ( ! iter2 ) {
err = true ;
goto error_netbsd3 ;
}
2014-04-29 22:30:11 +00:00
/* iterate over array of dicts specific to target sensor */
2013-10-06 21:18:53 +00:00
while ( ( obj2 = prop_object_iterator_next ( iter2 ) ) ! = NULL ) {
2014-04-29 22:30:11 +00:00
obj3 = prop_dictionary_get ( obj2 , " cur-value " ) ;
float temp = MUKTOC ( prop_number_integer_value ( obj3 ) ) ;
if ( ( int ) temp > = max_threshold ) {
START_COLOR ( " color_bad " ) ;
colorful_output = true ;
}
2013-10-06 21:18:53 +00:00
2014-04-29 22:30:11 +00:00
outwalk + = sprintf ( outwalk , " %.2f " , temp ) ;
2013-10-06 21:18:53 +00:00
2014-04-29 22:30:11 +00:00
if ( colorful_output ) {
END_COLOR ;
colorful_output = false ;
2013-10-06 21:18:53 +00:00
}
2014-04-29 22:30:11 +00:00
break ;
2013-10-06 21:18:53 +00:00
}
prop_object_iterator_release ( iter2 ) ;
}
error_netbsd3 :
prop_object_iterator_release ( iter ) ;
error_netbsd2 :
prop_object_release ( dict ) ;
error_netbsd1 :
close ( fd ) ;
if ( err ) goto error ;
2009-10-11 20:11:09 +00:00
# endif
2013-10-06 21:18:53 +00:00
2009-10-11 20:11:09 +00:00
walk + = strlen ( " degrees " ) ;
}
}
2014-02-25 19:43:48 +00:00
free ( thermal_zone ) ;
2012-03-25 18:55:55 +00:00
OUTPUT_FULL_TEXT ( buffer ) ;
2011-08-25 21:24:06 +00:00
return ;
error :
2011-07-24 21:17:34 +00:00
# endif
2014-02-25 19:43:48 +00:00
free ( thermal_zone ) ;
2012-05-09 16:56:57 +00:00
OUTPUT_FULL_TEXT ( " cant read temp " ) ;
2012-05-09 16:39:41 +00:00
( void ) fputs ( " i3status: Cannot read temperature. Verify that you have a thermal zone in /sys/class/thermal or disable the cpu_temperature module in your i3status config. \n " , stderr ) ;
2009-10-11 20:11:09 +00:00
}