15
15
// To view the GNU Lesser General Public License visit
16
16
// http://www.gnu.org/copyleft/lesser.html
17
17
// or write to the Free Software Foundation, Inc.,
18
// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
// There is a reason that having a file called "cpp.h" that includes config.h
21
// and some of the C++ header files. That reason is because there are #defines
22
// that alter the behiour of the standard C and C++ headers. In this case
23
// we need to use the "small files" environment on some unix systems. That
24
// can't be done if we include "cpp.h"
27
// copied directly from cpp.h
28
#if defined(_WIN32) && !defined(__CYGWIN32__)
30
#if defined(_WIN64) && defined(_M_X64)
31
#define HOSTTYPE "windows_x86_64"
32
#define HOSTTYPEALT "windows_intelx86"
34
#define HOSTTYPE "windows_intelx86"
37
#include "version.h" // version numbers from autoconf
40
#if !defined(_WIN32) || defined(__CYGWIN32__)
43
// Access to binary files in /proc filesystem doesn't work in the 64bit
44
// files environment on some systems. None of the functions here need
45
// 64bit file functions, so we'll undefine _FILE_OFFSET_BITS and _LARGE_FILES.
46
#undef _FILE_OFFSET_BITS
107
141
#include <machine/cpuconf.h>
144
// The following is intended to be true both on Linux
145
// and Debian GNU/kFreeBSD (see trac #521)
147
#define LINUX_LIKE_SYSTEM defined(__linux__) || defined(__GNU__) || defined(__GLIBC__)
110
149
// functions to get name/addr of local host
112
151
// Converts a int ip address to a string representation (i.e. "66.218.71.198")
451
490
strlcpy(host.p_model, model_buf, sizeof(host.p_model));
493
#endif // LINUX_LIKE_SYSTEM
495
#if defined(__i386__) || defined(__amd64__)
496
#include <sys/types.h>
497
#include <sys/cdefs.h>
498
#include <machine/cpufunc.h>
500
void use_cpuid(HOST_INFO& host) {
502
int hasMMX, hasSSE, hasSSE2, hasSSE3, has3DNow, has3DNowExt = 0;
503
char capabilities[256];
511
hasMMX = (p[3] & (1 << 23 )) >> 23; // 0x0800000
512
hasSSE = (p[3] & (1 << 25 )) >> 25; // 0x2000000
513
hasSSE2 = (p[3] & (1 << 26 )) >> 26; // 0x4000000
514
hasSSE3 = (p[2] & (1 << 0 )) >> 0;
517
do_cpuid(0x80000000, p);
518
if (p[0]>=0x80000001) {
519
do_cpuid(0x80000001, p);
520
hasMMX |= (p[3] & (1 << 23 )) >> 23; // 0x0800000
521
has3DNow = (p[3] & (1 << 31 )) >> 31; //0x80000000
522
has3DNowExt = (p[3] & (1 << 30 )) >> 30;
525
capabilities[0] = '\0';
526
if (hasSSE) strncat(capabilities, "sse ", 4);
527
if (hasSSE2) strncat(capabilities, "sse2 ", 5);
528
if (hasSSE3) strncat(capabilities, "sse3 ", 5);
529
if (has3DNow) strncat(capabilities, "3dnow ", 6);
530
if (has3DNowExt) strncat(capabilities, "3dnowext ", 9);
531
if (hasMMX) strncat(capabilities, "mmx ", 4);
532
strip_whitespace(capabilities);
533
snprintf(host.p_model, sizeof(host.p_model), "%s [] [%s]", host.p_model, capabilities);
457
539
static void get_cpu_info_maxosx(HOST_INFO& host) {
458
540
int p_model_size = sizeof(host.p_model);
542
#if defined(__i386__) || defined(__x86_64__)
461
543
char brand_string[256];
462
544
int family, stepping, model;
522
604
get_filesystem_info(d_total, d_free);
524
606
///////////// p_vendor, p_model, p_features /////////////////
607
#if LINUX_LIKE_SYSTEM
526
608
parse_cpuinfo_linux(*this);
527
609
#elif defined( __APPLE__)
531
613
get_cpu_info_maxosx(*this);
532
614
#elif defined(__EMX__)
533
615
CPU_INFO_t cpuInfo;
534
strcpy( p_vendor, cpuInfo.vendor.company);
535
strcpy( p_model, cpuInfo.name.fromID);
616
strlcpy( p_vendor, cpuInfo.vendor.company, sizeof(p_vendor));
617
strlcpy( p_model, cpuInfo.name.fromID, sizeof(p_model));
536
618
#elif defined(HAVE_SYS_SYSCTL_H)
560
642
CPU_TYPE_TO_TEXT( (cpu_type& 0xffffffff), cpu_type_name);
561
643
strncpy( p_model, "Alpha ", sizeof( p_model));
562
644
strncat( p_model, cpu_type_name, (sizeof( p_model)- strlen( p_model)- 1));
645
p_model[sizeof(p_model)-1]=0;
563
646
#elif defined(HAVE_SYS_SYSTEMINFO_H)
564
647
sysinfo(SI_PLATFORM, p_vendor, sizeof(p_vendor));
565
648
sysinfo(SI_ISALIST, p_model, sizeof(p_model));
575
658
#error Need to specify a method to get p_vendor, p_model
661
#if defined(__FreeBSD__)
662
#if defined(__i386__) || defined(__amd64__)
578
667
///////////// p_ncpus /////////////////
580
669
// sysconf not working on OS2
581
#if defined(_SC_NPROCESSORS_ONLN) && !defined(__EMX__)
670
#if defined(_SC_NPROCESSORS_ONLN) && !defined(__EMX__) && !defined(__APPLE__)
582
671
p_ncpus = sysconf(_SC_NPROCESSORS_ONLN);
583
672
#elif defined(HAVE_SYS_SYSCTL_H) && defined(CTL_HW) && defined(HW_NCPU)
584
673
// Get number of CPUs
624
713
// 4-byte value, even if passed an 8-byte buffer, and limits the returned
625
714
// value to 2GB when the actual RAM size is > 2GB. The Gestalt selector
626
715
// gestaltPhysicalRAMSizeInMegabytes is available starting with OS 10.3.0.
628
717
if (Gestalt(gestaltPhysicalRAMSizeInMegabytes, &mem_size)) {
629
718
msg_printf(NULL, MSG_INTERNAL_ERROR,
630
719
"Couldn't determine physical RAM size"
642
731
getsysinfo( GSI_PHYSMEM, (caddr_t) &mem_size, sizeof( mem_size));
643
732
m_nbytes = 1024.* (double)mem_size;
733
#elif defined(HW_PHYSMEM)
738
len = sizeof(mem_size);
739
sysctl(mib, 2, &mem_size, &len, NULL, 0);
741
#elif defined(__FreeBSD__)
742
unsigned int mem_size;
745
len = sizeof(mem_size);
746
sysctl(mib, 2, &mem_size, &len, NULL, 0);
645
749
#error Need to specify a method to get memory size
763
867
return stat(device, &sbuf) || (sbuf.st_atime < t);
766
inline bool all_tty_idle(time_t t, char *device, char first_char, int num_tty) {
870
static const struct dir_dev {
879
// add other ifdefs here as necessary.
883
std::vector<std::string> get_tty_list() {
884
// Create a list of all terminal devices on the system.
888
std::vector<std::string> tty_list;
891
DIRREF dev=dir_open(tty_patterns[i].dir);
895
done=dir_scan(devname,dev,1024);
896
// does it match our tty pattern? If so, add it to the tty list.
897
if (!done && (strstr(devname,tty_patterns[i].dev) == devname)) {
898
// don't add anything starting with .
899
if (devname[0] != '.') {
900
sprintf(fullname,"%s/%s",tty_patterns[i].dir,devname);
901
tty_list.push_back(fullname);
907
} while (tty_patterns[i].dir != NULL);
912
inline bool all_tty_idle(time_t t) {
913
static std::vector<std::string> tty_list;
767
914
struct stat sbuf;
768
char *tty_index = device + strlen(device) - 1;
769
*tty_index = first_char;
770
for (int i = 0; i < num_tty; i++, (*tty_index)++) {
771
if (stat(device, &sbuf)) {
772
// error looking at device; don't try any more
774
} else if (sbuf.st_atime >= t) {
917
if (tty_list.size()==0) tty_list=get_tty_list();
918
for (i=0; i<tty_list.size(); i++) {
920
if (!stat(tty_list[i].c_str(), &sbuf)) {
921
// printf("%s %d %d\n",tty_list[i].c_str(),sbuf.st_atime,t);
922
if (sbuf.st_atime >= t) {
797
946
#if !defined(HAVE_SETUTENT) || !defined(HAVE_GETUTENT)
798
static FILE *ufp = NULL;
799
static struct utmp ut;
947
static FILE *ufp = NULL;
948
static struct utmp ut;
801
// get next user login record
802
// (this is defined on everything except BSD)
804
struct utmp *getutent() {
950
// get next user login record
951
// (this is defined on everything except BSD)
953
struct utmp *getutent() {
806
955
#if defined(UTMP_LOCATION)
807
if ((ufp = fopen(UTMP_LOCATION, "r")) == NULL) {
956
if ((ufp = fopen(UTMP_LOCATION, "r")) == NULL) {
808
957
#elif defined(UTMP_FILE)
809
if ((ufp = fopen(UTMP_FILE, "r")) == NULL) {
958
if ((ufp = fopen(UTMP_FILE, "r")) == NULL) {
810
959
#elif defined(_PATH_UTMP)
811
if ((ufp = fopen(_PATH_UTMP, "r")) == NULL) {
960
if ((ufp = fopen(_PATH_UTMP, "r")) == NULL) {
813
if ((ufp = fopen("/etc/utmp", "r")) == NULL) {
815
return((struct utmp *)NULL);
819
if (fread((char *)&ut, sizeof(ut), 1, ufp) != 1) {
820
return((struct utmp *)NULL);
822
} while (ut.ut_name[0] == 0);
827
if (ufp != NULL) rewind(ufp);
831
// scan list of logged-in users, and see if they're all idle
833
inline bool all_logins_idle(time_t t) {
837
while ((u = getutent()) != NULL) {
838
if (!user_idle(t, u)) {
962
if ((ufp = fopen("/etc/utmp", "r")) == NULL) {
964
return((struct utmp *)NULL);
968
if (fread((char *)&ut, sizeof(ut), 1, ufp) != 1) {
969
return((struct utmp *)NULL);
971
} while (ut.ut_name[0] == 0);
976
if (ufp != NULL) rewind(ufp);
980
// scan list of logged-in users, and see if they're all idle
982
inline bool all_logins_idle(time_t t) {
986
while ((u = getutent()) != NULL) {
987
if (!user_idle(t, u)) {
993
#endif // HAVE_UTMP_H
849
998
bool check_all_logins, double idle_time_to_run, double *actual_idle_time
851
1000
double idleTime = 0;
853
1002
if (gEventHandle) {
854
idleTime = NXIdleTime(gEventHandle);
1003
idleTime = NXIdleTime(gEventHandle);
856
1005
// Initialize Mac OS X idle time measurement / idle detection
857
1006
// Do this here because NXOpenEventStatus() may not be available
868
1017
#else // ! __APPLE__
1019
#if LINUX_LIKE_SYSTEM
1020
bool interrupts_idle(time_t t) {
1021
static FILE *ifp = NULL;
1022
static long irq_count[256];
1023
static time_t last_irq = time(NULL);
1030
if ((ifp = fopen("/proc/interrupts", "r")) == NULL) {
1035
while (fgets(line, sizeof(line), ifp)) {
1036
// Check for mouse, keyboard and PS/2 devices.
1037
if (strcasestr(line, "mouse") != NULL ||
1038
strcasestr(line, "keyboard") != NULL ||
1039
strcasestr(line, "i8042") != NULL) {
1040
// If any IRQ count changed, update last_irq.
1041
if (sscanf(line, "%d: %ld", &i, &ccount) == 2 &&
1042
irq_count[i] != ccount) {
1043
last_irq = time(NULL);
1044
irq_count[i] = ccount;
1048
return last_irq < t;
870
1052
bool HOST_INFO::users_idle(bool check_all_logins, double idle_time_to_run) {
871
1053
time_t idle_time = time(0) - (long) (60 * idle_time_to_run);
873
1056
if (check_all_logins) {
875
1057
if (!all_logins_idle(idle_time)) return false;
877
if (!all_tty_idle(idle_time, "/dev/tty1", '1', 7)) return false;
1061
if (!all_tty_idle(idle_time)) return false;
1063
#if LINUX_LIKE_SYSTEM
1064
// Check /proc/interrupts to detect keyboard or mouse activity.
1065
if (!interrupts_idle(idle_time)) return false;
1067
// We should find out which of the following are actually relevant
1068
// on which systems (if any)
879
1070
if (!device_idle(idle_time, "/dev/mouse")) return false;
880
1071
// solaris, linux
1072
if (!device_idle(idle_time, "/dev/input/mice")) return false;
881
1073
if (!device_idle(idle_time, "/dev/kbd")) return false;
886
1079
#endif // ! __APPLE__
888
const char *BOINC_RCSID_2cf92d205b = "$Id: hostinfo_unix.C 14470 2008-01-06 08:10:13Z charlief $";
1081
const char *BOINC_RCSID_2cf92d205b = "$Id: hostinfo_unix.C 15275 2008-05-22 18:45:55Z romw $";