int SYSTEM_SWAP_SIZE(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { /* * FreeBSD 7.0 i386 */ #ifdef XSWDEV_VERSION /* defined in <vm/vm_param.h> */ char swapdev[64], mode[64]; int mib[16], *mib_dev; size_t sz, mib_sz; struct xswdev xsw; zbx_uint64_t total = 0, used = 0; assert(result); init_result(result); if (num_param(param) > 2) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, swapdev, sizeof(swapdev))) return SYSINFO_RET_FAIL; if (0 != get_param(param, 2, mode, sizeof(mode))) *mode = '\0'; sz = sizeof(mib) / sizeof(mib[0]); if (-1 == sysctlnametomib("vm.swap_info", mib, &sz)) return FAIL; mib_sz = sz + 1; mib_dev = &(mib[sz]); *mib_dev = 0; sz = sizeof(xsw); while (-1 != sysctl(mib, mib_sz, &xsw, &sz, NULL, 0)) { if ('\0' == *swapdev || 0 == strcmp(swapdev, "all") /* default parameter */ || 0 == strcmp(swapdev, devname(xsw.xsw_dev, S_IFCHR))) { total += (zbx_uint64_t)xsw.xsw_nblks; used += (zbx_uint64_t)xsw.xsw_used; } (*mib_dev)++; } if ('\0' == *mode || 0 == strcmp(mode, "free")) /* default parameter */ { SET_UI64_RESULT(result, (total - used) * getpagesize()); } else if (0 == strcmp(mode, "total")) { SET_UI64_RESULT(result, total * getpagesize()); } else if (0 == strcmp(mode, "used")) { SET_UI64_RESULT(result, used * getpagesize()); } else if (0 == strcmp(mode, "pfree")) { SET_DBL_RESULT(result, total ? ((double)(total - used) * 100.0 / (double)total) : 0.0); } else if (0 == strcmp(mode, "pused")) { SET_DBL_RESULT(result, total ? ((double)used * 100.0 / (double)total) : 0.0); } else return SYSINFO_RET_FAIL; return SYSINFO_RET_OK; #else return SYSINFO_RET_FAIL; #endif }
static int vma_iterate_bsd (vma_iterate_callback_fn callback, void *data) { /* Documentation: http://man.netbsd.org/man/sysctl+7 */ unsigned int entry_size = /* If we wanted to have the path of each entry, we would need sizeof (struct kinfo_vmentry). But we need only the non-string parts of each entry. */ offsetof (struct kinfo_vmentry, kve_path); int info_path[] = { CTL_VM, VM_PROC, VM_PROC_MAP, getpid (), entry_size }; size_t len; size_t pagesize; size_t memneed; void *auxmap; unsigned long auxmap_start; unsigned long auxmap_end; char *mem; char *p; char *p_end; len = 0; if (sysctl (info_path, 5, NULL, &len, NULL, 0) < 0) return -1; /* Allow for small variations over time. In a multithreaded program new VMAs can be allocated at any moment. */ len = 2 * len + 10 * entry_size; /* But the system call rejects lengths > 1 MB. */ if (len > 0x100000) len = 0x100000; /* And the system call causes a kernel panic if the length is not a multiple of entry_size. */ len = (len / entry_size) * entry_size; /* Allocate memneed bytes of memory. We cannot use alloca here, because not much stack space is guaranteed. We also cannot use malloc here, because a malloc() call may call mmap() and thus pre-allocate available memory. So use mmap(), and ignore the resulting VMA. */ pagesize = getpagesize (); memneed = len; memneed = ((memneed - 1) / pagesize + 1) * pagesize; auxmap = (void *) mmap ((void *) 0, memneed, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if (auxmap == (void *) -1) return -1; auxmap_start = (unsigned long) auxmap; auxmap_end = auxmap_start + memneed; mem = (char *) auxmap; if (sysctl (info_path, 5, mem, &len, NULL, 0) < 0 || len > 0x100000 - entry_size) { /* sysctl failed, or the list of VMAs is possibly truncated. */ munmap (auxmap, memneed); return -1; } p = mem; p_end = mem + len; while (p < p_end) { struct kinfo_vmentry *kve = (struct kinfo_vmentry *) p; unsigned long start = kve->kve_start; unsigned long end = kve->kve_end; unsigned int flags = 0; if (kve->kve_protection & KVME_PROT_READ) flags |= VMA_PROT_READ; if (kve->kve_protection & KVME_PROT_WRITE) flags |= VMA_PROT_WRITE; if (kve->kve_protection & KVME_PROT_EXEC) flags |= VMA_PROT_EXECUTE; if (start <= auxmap_start && auxmap_end - 1 <= end - 1) { /* Consider [start,end-1] \ [auxmap_start,auxmap_end-1] = [start,auxmap_start-1] u [auxmap_end,end-1]. */ if (start < auxmap_start) if (callback (data, start, auxmap_start, flags)) break; if (auxmap_end - 1 < end - 1) if (callback (data, auxmap_end, end, flags)) break; } else { if (callback (data, start, end, flags)) break; } p += entry_size; } munmap (auxmap, memneed); return 0; }
bool CommandLine::Parse(int argc, TCHAR *argv[]) { if (argc<1) { return false; } // Split the program name into path and filename string path, name; DiskFile::SplitFilename(native_char_array_to_utf8_string(argv[0]), path, name); argc--; argv++; // Strip ".exe" from the end if (name.size() > 4 && 0 == stricmp(".exe", name.substr(name.length()-4).c_str())) { name = name.substr(0, name.length()-4); } // Check the resulting program name if (0 == stricmp("par2create", name.c_str())) { operation = opCreate; } else if (0 == stricmp("par2verify", name.c_str())) { operation = opVerify; } else if (0 == stricmp("par2repair", name.c_str())) { operation = opRepair; } // Have we determined what operation we want? if (operation == opNone) { if (argc<2) { cerr << "Not enough command line arguments." << endl; return false; } switch (tolower(argv[0][0])) { case 'c': if (argv[0][1] == 0 || 0 == stricmp(native_char_array_to_utf8_char_array(argv[0]), "create")) operation = opCreate; break; case 'v': if (argv[0][1] == 0 || 0 == stricmp(native_char_array_to_utf8_char_array(argv[0]), "verify")) operation = opVerify; break; case 'r': if (argv[0][1] == 0 || 0 == stricmp(native_char_array_to_utf8_char_array(argv[0]), "repair")) operation = opRepair; break; } if (operation == opNone) { cerr << "Invalid operation specified: " << argv[0] << endl; return false; } argc--; argv++; } bool options = true; #if defined(WIN32) || defined(__APPLE__) std::set<string, less_stri> accepted_filenames; #else std::set<string> accepted_filenames; #endif while (argc>0) { if (argv[0][0]) { if (options && argv[0][0] != '-') options = false; if (options) { switch (tolower(argv[0][1])) { case 'b': // Set the block count { if (operation != opCreate) { cerr << "Cannot specify block count unless creating." << endl; return false; } if (blockcount > 0) { cerr << "Cannot specify block count twice." << endl; return false; } else if (blocksize > 0) { cerr << "Cannot specify both block count and block size." << endl; return false; } TCHAR *p = &argv[0][2]; while (blockcount <= 3276 && *p && isdigit(*p)) { blockcount = blockcount * 10 + (*p - '0'); p++; } if (0 == blockcount || blockcount > 32768 || *p) { cerr << "Invalid block count option: " << argv[0] << endl; return false; } } break; case 's': // Set the block size { if (operation != opCreate) { cerr << "Cannot specify block size unless creating." << endl; return false; } if (blocksize > 0) { cerr << "Cannot specify block size twice." << endl; return false; } else if (blockcount > 0) { cerr << "Cannot specify both block count and block size." << endl; return false; } TCHAR *p = &argv[0][2]; while (blocksize <= 429496729 && *p && isdigit(*p)) { blocksize = blocksize * 10 + (*p - '0'); p++; } if (*p || blocksize == 0) { cerr << "Invalid block size option: " << argv[0] << endl; return false; } if (blocksize & 3) { cerr << "Block size must be a multiple of 4." << endl; return false; } } break; case 'r': // Set the amount of redundancy required { if (operation != opCreate) { cerr << "Cannot specify redundancy unless creating." << endl; return false; } if (redundancyset) { cerr << "Cannot specify redundancy twice." << endl; return false; } else if (recoveryblockcountset) { cerr << "Cannot specify both redundancy and recovery block count." << endl; return false; } TCHAR *p = &argv[0][2]; #if 1 redundancy = (float) _tcstod(p, &p); #else while (redundancy <= 10 && *p && isdigit(*p)) { redundancy = redundancy * 10 + (*p - '0'); p++; } #endif if (redundancy > 100.0f || *p) { cerr << "Invalid redundancy option: " << argv[0] << endl; return false; } if (redundancy == 0.0f && recoveryfilecount > 0) { cerr << "Cannot set redundancy to 0 and file count > 0" << endl; return false; } redundancyset = true; } break; case 'c': // Set the number of recovery blocks to create { if (operation != opCreate) { cerr << "Cannot specify recovery block count unless creating." << endl; return false; } if (recoveryblockcountset) { cerr << "Cannot specify recovery block count twice." << endl; return false; } else if (redundancyset) { cerr << "Cannot specify both recovery block count and redundancy." << endl; return false; } TCHAR *p = &argv[0][2]; while (recoveryblockcount <= 32768 && *p && isdigit(*p)) { recoveryblockcount = recoveryblockcount * 10 + (*p - '0'); p++; } if (recoveryblockcount > 32768 || *p) { cerr << "Invalid recoveryblockcount option: " << argv[0] << endl; return false; } if (recoveryblockcount == 0 && recoveryfilecount > 0) { cerr << "Cannot set recoveryblockcount to 0 and file count > 0" << endl; return false; } recoveryblockcountset = true; } break; case 'f': // Specify the First block recovery number { if (operation != opCreate) { cerr << "Cannot specify first block number unless creating." << endl; return false; } if (firstblock > 0) { cerr << "Cannot specify first block twice." << endl; return false; } TCHAR *p = &argv[0][2]; while (firstblock <= 3276 && *p && isdigit(*p)) { firstblock = firstblock * 10 + (*p - '0'); p++; } if (firstblock > 32768 || *p) { cerr << "Invalid first block option: " << argv[0] << endl; return false; } } break; case 'u': // Specify uniformly sized recovery files { if (operation != opCreate) { cerr << "Cannot specify uniform files unless creating." << endl; return false; } if (argv[0][2]) { cerr << "Invalid option: " << argv[0] << endl; return false; } if (recoveryfilescheme != scUnknown) { cerr << "Cannot specify two recovery file size schemes." << endl; return false; } recoveryfilescheme = scUniform; } break; case 'l': // Limit the size of the recovery files { if (operation != opCreate) { cerr << "Cannot specify limit files unless creating." << endl; return false; } if (argv[0][2]) { cerr << "Invalid option: " << argv[0] << endl; return false; } if (recoveryfilescheme != scUnknown) { cerr << "Cannot specify two recovery file size schemes." << endl; return false; } if (recoveryfilecount > 0) { cerr << "Cannot specify limited size and number of files at the same time." << endl; return false; } recoveryfilescheme = scLimited; } break; case 'n': // Specify the number of recovery files { if (operation != opCreate) { cerr << "Cannot specify recovery file count unless creating." << endl; return false; } if (recoveryfilecount > 0) { cerr << "Cannot specify recovery file count twice." << endl; return false; } if (redundancyset && redundancy == 0) { cerr << "Cannot set file count when redundancy is set to 0." << endl; return false; } if (recoveryblockcountset && recoveryblockcount == 0) { cerr << "Cannot set file count when recovery block count is set to 0." << endl; return false; } if (recoveryfilescheme == scLimited) { cerr << "Cannot specify limited size and number of files at the same time." << endl; return false; } TCHAR *p = &argv[0][2]; while (*p && isdigit(*p)) { recoveryfilecount = recoveryfilecount * 10 + (*p - '0'); p++; } if (recoveryfilecount == 0 || *p) { cerr << "Invalid recovery file count option: " << argv[0] << endl; return false; } } break; case 'm': // Specify how much memory to use for output buffers { if (memorylimit > 0) { cerr << "Cannot specify memory limit twice." << endl; return false; } TCHAR *p = &argv[0][2]; while (*p && isdigit(*p)) { memorylimit = memorylimit * 10 + (*p - '0'); p++; } if (memorylimit == 0 || *p) { cerr << "Invalid memory limit option: " << argv[0] << endl; return false; } } break; case 'v': { switch (noiselevel) { case nlUnknown: { if (argv[0][2] == 'v') noiselevel = nlDebug; else noiselevel = nlNoisy; } break; case nlNoisy: case nlDebug: noiselevel = nlDebug; break; default: cerr << "Cannot use both -v and -q." << endl; return false; break; } } break; case 'q': { switch (noiselevel) { case nlUnknown: { if (argv[0][2] == 'q') noiselevel = nlSilent; else noiselevel = nlQuiet; } break; case nlQuiet: case nlSilent: noiselevel = nlSilent; break; default: cerr << "Cannot use both -v and -q." << endl; return false; break; } } break; case 'd': { base_directory = DiskFile::GetCanonicalPathname(native_char_array_to_utf8_string(2 + argv[0])); if (base_directory.empty()) { cerr << "base directory for hierarchy support must specify a folder" << endl; return false; } else if (operation == opCreate && !is_existing_folder(base_directory)) { cerr << "the base directory (" << base_directory << ") for hierarchy support must specify an accessible and existing folder" << endl; return false; } if (base_directory[base_directory.length()-1] != OS_SEPARATOR) base_directory += OS_SEPARATOR; break; } #if WANT_CONCURRENT case 't': { switch (argv[0][2]) { case '-': concurrent_processing_level = ALL_SERIAL; break; case '0': concurrent_processing_level = CHECKSUM_SERIALLY_BUT_PROCESS_CONCURRENTLY; break; case '+': concurrent_processing_level = ALL_CONCURRENT; break; default: cerr << "Expected -t+ (use multiple cores) or -t0 (checksum serially, process concurrently) or -t- (use single core)." << endl; return false; } } break; case 'p': // Set the number of threads { TCHAR *p = &argv[0][2]; while (numthreads <= 3276 && *p && isdigit(*p)) { numthreads = numthreads * 10 + (*p - '0'); p++; } if (numthreads > 32768 || *p) { cerr << "Invalid number of threads option: " << argv[0] << endl; return false; } } break; #endif case '0': create_dummy_par_files = true; break; case '-': { argc--; argv++; options = false; continue; } break; default: { cerr << "Invalid option specified: " << argv[0] << endl; return false; } } } else { list<string> *filenames; // If the argument includes wildcard characters, // search the disk for matching files if (_tcschr/*strchr*/(argv[0], '*') || _tcschr/*strchr*/(argv[0], '?')) { string path; string name; DiskFile::SplitFilename(native_char_array_to_utf8_string(argv[0]), path, name); filenames = DiskFile::FindFiles(path, name); } else if (is_existing_folder(native_char_array_to_utf8_string(argv[0]))) { filenames = build_file_list_in(native_char_array_to_utf8_string(argv[0]).c_str()); } else { filenames = new list<string>; filenames->push_back(native_char_array_to_utf8_string(argv[0])); } for (list<string>::iterator fn = filenames->begin(); fn != filenames->end(); ++fn) { // Convert filename from command line into a full path + filename string filename = DiskFile::GetCanonicalPathname(*fn); // filename can be empty if the realpath() API in GetCanonicalPathname() returns NULL if (filename.empty()) filename = *fn; // If this is the first file on the command line, then it // is the main PAR2 file. if (parfilename.length() == 0) { // If we are verifying or repairing, the PAR2 file must // already exist if (operation != opCreate) { // Find the last '.' in the filename string::size_type where = filename.find_last_of('.'); if (where != string::npos) { // Get what follows the last '.' string tail = filename.substr(where+1); if (0 == stricmp(tail.c_str(), "par2")) { parfilename = filename; version = verPar2; } else if (0 == stricmp(tail.c_str(), "par") || (tail.size() == 3 && tolower(tail[0]) == 'p' && isdigit(tail[1]) && isdigit(tail[2]))) { parfilename = filename; version = verPar1; } } // If we haven't figured out which version of PAR file we // are using from the file extension, then presumable the // files filename was actually the name of a data file. if (version == verUnknown) { // Check for the existence of a PAR2 of PAR file. if (DiskFile::FileExists(filename + ".par2")) { version = verPar2; parfilename = filename + ".par2"; } else if (DiskFile::FileExists(filename + ".PAR2")) { version = verPar2; parfilename = filename + ".PAR2"; } else if (DiskFile::FileExists(filename + ".par")) { version = verPar1; parfilename = filename + ".par"; } else if (DiskFile::FileExists(filename + ".PAR")) { version = verPar1; parfilename = filename + ".PAR"; } } else { // Does the specified PAR or PAR2 file exist if (!DiskFile::FileExists(filename)) { version = verUnknown; } } if (version == verUnknown) { cerr << "The recovery file does not exist: " << filename << endl; return false; } } else { // We are creating a new file version = verPar2; parfilename = filename; } } else { // Originally, all specified files were supposed to exist, or the program // would stop with an error message. This was not practical, for example in // a directory with files appearing and disappearing (an active download directory). // So the new rule is: when a specified file doesn't exist, it is silently skipped. if (!DiskFile::FileExists(filename)) { cout << "Ignoring non-existent source file: " << filename << endl; } else { u64 filesize = DiskFile::GetFileSize(filename); // Ignore all 0 byte files and duplicate file names if (filesize == 0) cout << "Skipping 0 byte file: " << filename << endl; else if (accepted_filenames.end() != accepted_filenames.find(filename)) cout << "Skipping duplicate filename: " << filename << endl; else /* if (accepted_filenames.end() == accepted_filenames.find(filename)) */ { accepted_filenames.insert(filename); extrafiles.push_back(ExtraFile(filename, filesize)); // track the total size of the source files and how // big the largest one is. totalsourcesize += filesize; if (largestsourcesize < filesize) largestsourcesize = filesize; } // if } // if } // if } // for delete filenames; } } argc--; argv++; } if (parfilename.length() == 0) { cerr << "You must specify a Recovery file." << endl; return false; } // Default noise level if (noiselevel == nlUnknown) { noiselevel = nlNormal; } // If we a creating, check the other parameters if (operation == opCreate) { // If no recovery file size scheme is specified then use Variable if (recoveryfilescheme == scUnknown) { recoveryfilescheme = scVariable; } // If neither block count not block size is specified if (blockcount == 0 && blocksize == 0) { // Use a block count of 2000 blockcount = 2000; } // If we are creating, the source files must be given. if (extrafiles.size() == 0) { // Does the par filename include the ".par2" on the end? if (parfilename.length() > 5 && 0 == stricmp(parfilename.substr(parfilename.length()-5, 5).c_str(), ".par2")) { // Yes it does. cerr << "You must specify a list of files when creating." << endl; return false; } else { // No it does not. // In that case check to see if the file exists, and if it does // assume that you wish to create par2 files for it. u64 filesize = 0; if (DiskFile::FileExists(parfilename) && (filesize = DiskFile::GetFileSize(parfilename)) > 0) { extrafiles.push_back(ExtraFile(parfilename, filesize)); // track the total size of the source files and how // big the largest one is. totalsourcesize += filesize; if (largestsourcesize < filesize) largestsourcesize = filesize; } else { // The file does not exist or it is empty. cerr << "You must specify a list of files when creating." << endl; return false; } } } // Strip the ".par2" from the end of the filename of the main PAR2 file. if (parfilename.length() > 5 && 0 == stricmp(parfilename.substr(parfilename.length()-5, 5).c_str(), ".par2")) { parfilename = parfilename.substr(0, parfilename.length()-5); } // Assume a redundancy of 5% if neither redundancy or recoveryblockcount were set. if (!redundancyset && !recoveryblockcountset) { redundancy = 5; } } // Assume a memory limit of 16MB if not specified. if (memorylimit == 0) { #if defined(WIN32) || defined(WIN64) u64 TotalPhysicalMemory = 0; HMODULE hLib = ::LoadLibraryA("kernel32.dll"); if (NULL != hLib) { BOOL (WINAPI *pfn)(LPMEMORYSTATUSEX) = (BOOL (WINAPI*)(LPMEMORYSTATUSEX))::GetProcAddress(hLib, "GlobalMemoryStatusEx"); if (NULL != pfn) { MEMORYSTATUSEX mse; mse.dwLength = sizeof(mse); if (pfn(&mse)) { TotalPhysicalMemory = mse.ullTotalPhys; } } ::FreeLibrary(hLib); } if (TotalPhysicalMemory == 0) { MEMORYSTATUS ms; ::ZeroMemory(&ms, sizeof(ms)); ::GlobalMemoryStatus(&ms); TotalPhysicalMemory = ms.dwTotalPhys; } if (TotalPhysicalMemory == 0) { // Assume 128MB TotalPhysicalMemory = 128 * 1048576; } // Half of total physical memory memorylimit = (size_t)(TotalPhysicalMemory / 1048576 / 2); #elif __APPLE__ int name[2] = {CTL_HW, HW_USERMEM}; int usermem_bytes; size_t size = sizeof(usermem_bytes); sysctl( name, 2, &usermem_bytes, &size, NULL, 0 ); memorylimit = usermem_bytes / (2048 * 1024); #else #if WANT_CONCURRENT // Assume 128MB (otherwise processing is slower) memorylimit = 64; #else memorylimit = 16; #endif #endif } memorylimit *= 1048576; return true; }
void update_cpu_usage() { #ifdef OLDCPU int mib[2] = { CTL_KERN, KERN_CPTIME }; long used, total; long cp_time[CPUSTATES]; size_t len = sizeof(cp_time); #else size_t size; unsigned int i; #endif /* add check for !info.cpu_usage since that mem is freed on a SIGUSR1 */ if ((cpu_setup == 0) || (!info.cpu_usage)) { get_cpu_count(); cpu_setup = 1; } #ifdef OLDCPU if (sysctl(mib, 2, &cp_time, &len, NULL, 0) < 0) { NORM_ERR("Cannot get kern.cp_time"); } fresh.load[0] = cp_time[CP_USER]; fresh.load[1] = cp_time[CP_NICE]; fresh.load[2] = cp_time[CP_SYS]; fresh.load[3] = cp_time[CP_IDLE]; fresh.load[4] = cp_time[CP_IDLE]; used = fresh.load[0] + fresh.load[1] + fresh.load[2]; total = fresh.load[0] + fresh.load[1] + fresh.load[2] + fresh.load[3]; if ((total - oldtotal) != 0) { info.cpu_usage[0] = ((double) (used - oldused)) / (double) (total - oldtotal); } else { info.cpu_usage[0] = 0; } oldused = used; oldtotal = total; #else if (info.cpu_count > 1) { size = CPUSTATES * sizeof(int64_t); for (i = 0; i < info.cpu_count; i++) { int cp_time_mib[] = { CTL_KERN, KERN_CPTIME2, i }; if (sysctl(cp_time_mib, 3, &(fresh[i * CPUSTATES]), &size, NULL, 0) < 0) { NORM_ERR("sysctl kern.cp_time2 failed"); } } } else { int cp_time_mib[] = { CTL_KERN, KERN_CPTIME }; long cp_time_tmp[CPUSTATES]; size = sizeof(cp_time_tmp); if (sysctl(cp_time_mib, 2, cp_time_tmp, &size, NULL, 0) < 0) { NORM_ERR("sysctl kern.cp_time failed"); } for (i = 0; i < CPUSTATES; i++) { fresh[i] = (int64_t) cp_time_tmp[i]; } } /* XXX Do sg with this int64_t => long => double ? float hell. */ for (i = 0; i < info.cpu_count; i++) { int64_t used, total; int at = i * CPUSTATES; used = fresh[at + CP_USER] + fresh[at + CP_NICE] + fresh[at + CP_SYS]; total = used + fresh[at + CP_IDLE]; if ((total - oldtotal[i]) != 0) { info.cpu_usage[i] = ((double) (used - oldused[i])) / (double) (total - oldtotal[i]); } else { info.cpu_usage[i] = 0; } oldused[i] = used; oldtotal[i] = total; } #endif }
inline void proc_find_top(struct process **cpu, struct process **mem) { struct kinfo_proc2 *p; int n_processes; int i, j = 0; struct process *processes; int mib[2]; u_int total_pages; int64_t usermem; int pagesize = getpagesize(); /* we get total pages count again to be sure it is up to date */ mib[0] = CTL_HW; mib[1] = HW_USERMEM64; size_t size = sizeof(usermem); if (sysctl(mib, 2, &usermem, &size, NULL, 0) == -1) { NORM_ERR("error reading usermem"); } /* translate bytes into page count */ total_pages = usermem / pagesize; int max_size = sizeof(struct kinfo_proc2); p = kvm_getproc2(kd, KERN_PROC_ALL, 0, max_size, &n_processes); processes = malloc(n_processes * sizeof(struct process)); for (i = 0; i < n_processes; i++) { if (!((p[i].p_flag & P_SYSTEM)) && p[i].p_comm != NULL) { processes[j].pid = p[i].p_pid; processes[j].name = strndup(p[i].p_comm, text_buffer_size); processes[j].amount = 100.0 * p[i].p_pctcpu / FSCALE; j++; } } qsort(processes, j - 1, sizeof(struct process), comparemem); for (i = 0; i < 10; i++) { struct process *tmp, *ttmp; tmp = malloc(sizeof(struct process)); tmp->pid = processes[i].pid; tmp->amount = processes[i].amount; tmp->name = strndup(processes[i].name, text_buffer_size); ttmp = mem[i]; mem[i] = tmp; if (ttmp != NULL) { free(ttmp->name); free(ttmp); } } qsort(processes, j - 1, sizeof(struct process), comparecpu); for (i = 0; i < 10; i++) { struct process *tmp, *ttmp; tmp = malloc(sizeof(struct process)); tmp->pid = processes[i].pid; tmp->amount = processes[i].amount; tmp->name = strndup(processes[i].name, text_buffer_size); ttmp = cpu[i]; cpu[i] = tmp; if (ttmp != NULL) { free(ttmp->name); free(ttmp); } } for (i = 0; i < j; i++) { free(processes[i].name); } free(processes); }
int PROC_NUM(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { char procname[MAX_STRING_LEN], buffer[MAX_STRING_LEN], proccomm[MAX_STRING_LEN], *args; int zbx_proc_stat, count, i, proc_ok, stat_ok, comm_ok, mib[4], mibs; int proccount = 0; size_t sz; struct kinfo_proc *proc = NULL; struct passwd *usrinfo; if (num_param(param) > 4) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, procname, sizeof(procname))) *procname = '\0'; else if (strlen(procname) > ZBX_COMMLEN) procname[ZBX_COMMLEN] = '\0'; if (0 != get_param(param, 2, buffer, sizeof(buffer))) *buffer = '\0'; if (*buffer != '\0') { usrinfo = getpwnam(buffer); if (usrinfo == NULL) /* incorrect user name */ return SYSINFO_RET_FAIL; } else usrinfo = NULL; if (0 != get_param(param, 3, buffer, sizeof(buffer))) *buffer = '\0'; if (*buffer != '\0') { if (0 == strcmp(buffer, "run")) zbx_proc_stat = ZBX_PROC_STAT_RUN; else if (0 == strcmp(buffer, "sleep")) zbx_proc_stat = ZBX_PROC_STAT_SLEEP; else if (0 == strcmp(buffer, "zomb")) zbx_proc_stat = ZBX_PROC_STAT_ZOMB; else if (0 == strcmp(buffer, "all")) zbx_proc_stat = ZBX_PROC_STAT_ALL; else return SYSINFO_RET_FAIL; } else zbx_proc_stat = ZBX_PROC_STAT_ALL; if (0 != get_param(param, 4, proccomm, sizeof(proccomm))) *proccomm = '\0'; mib[0] = CTL_KERN; mib[1] = KERN_PROC; if (NULL != usrinfo) { mib[2] = KERN_PROC_UID; mib[3] = usrinfo->pw_uid; mibs = 4; } else { mib[2] = KERN_PROC_ALL; mib[3] = 0; mibs = 3; } sz = 0; if (0 != sysctl(mib, mibs, NULL, &sz, NULL, 0)) return SYSINFO_RET_FAIL; proc = (struct kinfo_proc *)zbx_malloc(proc, sz); if (0 != sysctl(mib, mibs, proc, &sz, NULL, 0)) { zbx_free(proc); return SYSINFO_RET_FAIL; } count = sz / sizeof(struct kinfo_proc); for (i = 0; i < count; i++) { #if(__FreeBSD_version > 500000) if (proc[i].ki_flag & P_KTHREAD) /* skip a system thread */ continue; #endif proc_ok = 0; stat_ok = 0; comm_ok = 0; if (*procname == '\0' || 0 == strcmp(procname, proc[i].ZBX_PROC_COMM)) proc_ok = 1; if (zbx_proc_stat != ZBX_PROC_STAT_ALL) { switch (zbx_proc_stat) { case ZBX_PROC_STAT_RUN: if (proc[i].ZBX_PROC_STAT == SRUN) stat_ok = 1; break; case ZBX_PROC_STAT_SLEEP: if (proc[i].ZBX_PROC_STAT == SSLEEP) stat_ok = 1; break; case ZBX_PROC_STAT_ZOMB: if (proc[i].ZBX_PROC_STAT == SZOMB) stat_ok = 1; break; } } else stat_ok = 1; if (*proccomm != '\0') { if (NULL != (args = get_commandline(&proc[i]))) if (zbx_regexp_match(args, proccomm, NULL) != NULL) comm_ok = 1; } else comm_ok = 1; if (proc_ok && stat_ok && comm_ok) proccount++; } zbx_free(proc); SET_UI64_RESULT(result, proccount); return SYSINFO_RET_OK; }
static T getSysctl(int name, const T def) { T ret; int names[] = {CTL_HW, name}; size_t len = sizeof(def); return (sysctl(names, 2u, &ret, &len, NULL, 0) < 0) ? def : ret; }
/* * Return a Python list of named tuples with overall network I/O information */ static PyObject* get_network_io_counters(PyObject* self, PyObject* args) { PyObject* py_retdict = PyDict_New(); PyObject* py_ifc_info; char *buf = NULL, *lim, *next; struct if_msghdr *ifm; int mib[6]; size_t len; mib[0] = CTL_NET; // networking subsystem mib[1] = PF_ROUTE; // type of information mib[2] = 0; // protocol (IPPROTO_xxx) mib[3] = 0; // address family mib[4] = NET_RT_IFLIST; // operation mib[5] = 0; if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) { Py_DECREF(py_retdict); PyErr_SetFromErrno(0); return NULL; } buf = malloc(len); if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) { if (buf) { free(buf); } Py_DECREF(py_retdict); PyErr_SetFromErrno(0); return NULL; } lim = buf + len; for (next = buf; next < lim; ) { ifm = (struct if_msghdr *)next; next += ifm->ifm_msglen; if (ifm->ifm_type == RTM_IFINFO) { struct if_msghdr *if2m = (struct if_msghdr *)ifm; struct sockaddr_dl *sdl = (struct sockaddr_dl *)(if2m + 1); char ifc_name[32]; strncpy(ifc_name, sdl->sdl_data, sdl->sdl_nlen); ifc_name[sdl->sdl_nlen] = 0; py_ifc_info = Py_BuildValue("(KKKK)", if2m->ifm_data.ifi_obytes, if2m->ifm_data.ifi_ibytes, if2m->ifm_data.ifi_opackets, if2m->ifm_data.ifi_ipackets); PyDict_SetItemString(py_retdict, ifc_name, py_ifc_info); Py_XDECREF(py_ifc_info); } else { continue; } } free(buf); return py_retdict; }
static int cpu_read (void) { #if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE int cpu; kern_return_t status; #if PROCESSOR_CPU_LOAD_INFO processor_cpu_load_info_data_t cpu_info; mach_msg_type_number_t cpu_info_len; #endif #if PROCESSOR_TEMPERATURE processor_info_data_t cpu_temp; mach_msg_type_number_t cpu_temp_len; #endif host_t cpu_host; for (cpu = 0; cpu < cpu_list_len; cpu++) { #if PROCESSOR_CPU_LOAD_INFO cpu_host = 0; cpu_info_len = PROCESSOR_BASIC_INFO_COUNT; if ((status = processor_info (cpu_list[cpu], PROCESSOR_CPU_LOAD_INFO, &cpu_host, (processor_info_t) &cpu_info, &cpu_info_len)) != KERN_SUCCESS) { ERROR ("cpu plugin: processor_info failed with status %i", (int) status); continue; } if (cpu_info_len < CPU_STATE_MAX) { ERROR ("cpu plugin: processor_info returned only %i elements..", cpu_info_len); continue; } submit (cpu, "user", (counter_t) cpu_info.cpu_ticks[CPU_STATE_USER]); submit (cpu, "nice", (counter_t) cpu_info.cpu_ticks[CPU_STATE_NICE]); submit (cpu, "system", (counter_t) cpu_info.cpu_ticks[CPU_STATE_SYSTEM]); submit (cpu, "idle", (counter_t) cpu_info.cpu_ticks[CPU_STATE_IDLE]); #endif /* PROCESSOR_CPU_LOAD_INFO */ #if PROCESSOR_TEMPERATURE /* * Not all Apple computers do have this ability. To minimize * the messages sent to the syslog we do an exponential * stepback if `processor_info' fails. We still try ~once a day * though.. */ if (cpu_temp_retry_counter > 0) { cpu_temp_retry_counter--; continue; } cpu_temp_len = PROCESSOR_INFO_MAX; status = processor_info (cpu_list[cpu], PROCESSOR_TEMPERATURE, &cpu_host, cpu_temp, &cpu_temp_len); if (status != KERN_SUCCESS) { ERROR ("cpu plugin: processor_info failed: %s", mach_error_string (status)); cpu_temp_retry_counter = cpu_temp_retry_step; cpu_temp_retry_step *= 2; if (cpu_temp_retry_step > cpu_temp_retry_max) cpu_temp_retry_step = cpu_temp_retry_max; continue; } if (cpu_temp_len != 1) { DEBUG ("processor_info (PROCESSOR_TEMPERATURE) returned %i elements..?", (int) cpu_temp_len); continue; } cpu_temp_retry_counter = 0; cpu_temp_retry_step = 1; DEBUG ("cpu_temp = %i", (int) cpu_temp); #endif /* PROCESSOR_TEMPERATURE */ } /* #endif PROCESSOR_CPU_LOAD_INFO */ #elif defined(KERNEL_LINUX) int cpu; counter_t user, nice, syst, idle; counter_t wait, intr, sitr; /* sitr == soft interrupt */ FILE *fh; char buf[1024]; char *fields[9]; int numfields; if ((fh = fopen ("/proc/stat", "r")) == NULL) { char errbuf[1024]; ERROR ("cpu plugin: fopen (/proc/stat) failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } while (fgets (buf, 1024, fh) != NULL) { if (strncmp (buf, "cpu", 3)) continue; if ((buf[3] < '0') || (buf[3] > '9')) continue; numfields = strsplit (buf, fields, 9); if (numfields < 5) continue; cpu = atoi (fields[0] + 3); user = atoll (fields[1]); nice = atoll (fields[2]); syst = atoll (fields[3]); idle = atoll (fields[4]); submit (cpu, "user", user); submit (cpu, "nice", nice); submit (cpu, "system", syst); submit (cpu, "idle", idle); if (numfields >= 8) { wait = atoll (fields[5]); intr = atoll (fields[6]); sitr = atoll (fields[7]); submit (cpu, "wait", wait); submit (cpu, "interrupt", intr); submit (cpu, "softirq", sitr); if (numfields >= 9) submit (cpu, "steal", atoll (fields[8])); } } fclose (fh); /* #endif defined(KERNEL_LINUX) */ #elif defined(HAVE_LIBKSTAT) int cpu; counter_t user, syst, idle, wait; static cpu_stat_t cs; if (kc == NULL) return (-1); for (cpu = 0; cpu < numcpu; cpu++) { if (kstat_read (kc, ksp[cpu], &cs) == -1) continue; /* error message? */ idle = (counter_t) cs.cpu_sysinfo.cpu[CPU_IDLE]; user = (counter_t) cs.cpu_sysinfo.cpu[CPU_USER]; syst = (counter_t) cs.cpu_sysinfo.cpu[CPU_KERNEL]; wait = (counter_t) cs.cpu_sysinfo.cpu[CPU_WAIT]; submit (ksp[cpu]->ks_instance, "user", user); submit (ksp[cpu]->ks_instance, "system", syst); submit (ksp[cpu]->ks_instance, "idle", idle); submit (ksp[cpu]->ks_instance, "wait", wait); } /* #endif defined(HAVE_LIBKSTAT) */ #elif CAN_USE_SYSCTL uint64_t cpuinfo[numcpu][CPUSTATES]; size_t cpuinfo_size; int status; int i; if (numcpu < 1) { ERROR ("cpu plugin: Could not determine number of " "installed CPUs using sysctl(3)."); return (-1); } memset (cpuinfo, 0, sizeof (cpuinfo)); #if defined(KERN_CPTIME2) if (numcpu > 1) { for (i = 0; i < numcpu; i++) { int mib[] = {CTL_KERN, KERN_CPTIME2, i}; cpuinfo_size = sizeof (cpuinfo[0]); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), cpuinfo[i], &cpuinfo_size, NULL, 0); if (status == -1) { char errbuf[1024]; ERROR ("cpu plugin: sysctl failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } } } else #endif /* defined(KERN_CPTIME2) */ { int mib[] = {CTL_KERN, KERN_CPTIME}; long cpuinfo_tmp[CPUSTATES]; cpuinfo_size = sizeof(cpuinfo_tmp); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &cpuinfo_tmp, &cpuinfo_size, NULL, 0); if (status == -1) { char errbuf[1024]; ERROR ("cpu plugin: sysctl failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for(i = 0; i < CPUSTATES; i++) { cpuinfo[0][i] = cpuinfo_tmp[i]; } } for (i = 0; i < numcpu; i++) { submit (i, "user", cpuinfo[i][CP_USER]); submit (i, "nice", cpuinfo[i][CP_NICE]); submit (i, "system", cpuinfo[i][CP_SYS]); submit (i, "idle", cpuinfo[i][CP_IDLE]); submit (i, "interrupt", cpuinfo[i][CP_INTR]); } /* #endif CAN_USE_SYSCTL */ #elif defined(HAVE_SYSCTLBYNAME) long cpuinfo[CPUSTATES]; size_t cpuinfo_size; cpuinfo_size = sizeof (cpuinfo); if (sysctlbyname("kern.cp_time", &cpuinfo, &cpuinfo_size, NULL, 0) < 0) { char errbuf[1024]; ERROR ("cpu plugin: sysctlbyname failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } submit (0, "user", cpuinfo[CP_USER]); submit (0, "nice", cpuinfo[CP_NICE]); submit (0, "system", cpuinfo[CP_SYS]); submit (0, "idle", cpuinfo[CP_IDLE]); submit (0, "interrupt", cpuinfo[CP_INTR]); /* #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) sg_cpu_stats *cs; cs = sg_get_cpu_stats (); if (cs == NULL) { ERROR ("cpu plugin: sg_get_cpu_stats failed."); return (-1); } submit (0, "idle", (counter_t) cs->idle); submit (0, "nice", (counter_t) cs->nice); submit (0, "swap", (counter_t) cs->swap); submit (0, "system", (counter_t) cs->kernel); submit (0, "user", (counter_t) cs->user); submit (0, "wait", (counter_t) cs->iowait); #endif /* HAVE_LIBSTATGRAB */ return (0); }
gchar* mono_w32process_get_name (pid_t pid) { gint mib [6]; gsize size; struct kinfo_proc *pi; gchar *ret = NULL; #if defined(__FreeBSD__) mib [0] = CTL_KERN; mib [1] = KERN_PROC; mib [2] = KERN_PROC_PID; mib [3] = pid; if (sysctl(mib, 4, NULL, &size, NULL, 0) < 0) { mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_PROCESS, "%s: sysctl() failed: %d", __func__, errno); return NULL; } if ((pi = g_malloc (size)) == NULL) return NULL; if (sysctl (mib, 4, pi, &size, NULL, 0) < 0) { if (errno == ENOMEM) { g_free (pi); mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_PROCESS, "%s: Didn't allocate enough memory for kproc info", __func__); } return NULL; } ret = strlen (pi->ki_comm) > 0 ? g_strdup (pi->ki_comm) : NULL; g_free (pi); #elif defined(__OpenBSD__) mib [0] = CTL_KERN; mib [1] = KERN_PROC; mib [2] = KERN_PROC_PID; mib [3] = pid; mib [4] = sizeof(struct kinfo_proc); mib [5] = 0; retry: if (sysctl(mib, 6, NULL, &size, NULL, 0) < 0) { mono_trace (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER_PROCESS, "%s: sysctl() failed: %d", __func__, errno); return NULL; } if ((pi = g_malloc (size)) == NULL) return NULL; mib[5] = (int)(size / sizeof(struct kinfo_proc)); if ((sysctl (mib, 6, pi, &size, NULL, 0) < 0) || (size != sizeof (struct kinfo_proc))) { if (errno == ENOMEM) { g_free (pi); goto retry; } return NULL; } ret = strlen (pi->p_comm) > 0 ? g_strdup (pi->p_comm) : NULL; g_free (pi); #endif return ret; }
/* * Retrieves all threads used by process returning a list of tuples * including thread id, user time and system time. * Thanks to Robert N. M. Watson: * http://fxr.googlebit.com/source/usr.bin/procstat/procstat_threads.c?v=8-CURRENT */ static PyObject* get_process_threads(PyObject* self, PyObject* args) { long pid; int mib[4]; struct kinfo_proc *kip; struct kinfo_proc *kipp; int error; unsigned int i; size_t size; PyObject* retList = PyList_New(0); PyObject* pyTuple = NULL; if (! PyArg_ParseTuple(args, "l", &pid)) { return NULL; } /* * We need to re-query for thread information, so don't use *kipp. */ mib[0] = CTL_KERN; mib[1] = KERN_PROC; mib[2] = KERN_PROC_PID | KERN_PROC_INC_THREAD; mib[3] = pid; size = 0; error = sysctl(mib, 4, NULL, &size, NULL, 0); if (error == -1) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } if (size == 0) { return NoSuchProcess(); } kip = malloc(size); if (kip == NULL) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } error = sysctl(mib, 4, kip, &size, NULL, 0); if (error == -1) { PyErr_SetFromErrno(PyExc_OSError); return NULL; } if (size == 0) { return NoSuchProcess(); } for (i = 0; i < size / sizeof(*kipp); i++) { kipp = &kip[i]; pyTuple = Py_BuildValue("Idd", kipp->ki_tid, TV2DOUBLE(kipp->ki_rusage.ru_utime), TV2DOUBLE(kipp->ki_rusage.ru_stime) ); PyList_Append(retList, pyTuple); Py_XDECREF(pyTuple); } free(kip); return retList; }
/* Return the total amount of physical memory. */ double physmem_total (void) { #if defined _SC_PHYS_PAGES && defined _SC_PAGESIZE { /* This works on linux-gnu, solaris2 and cygwin. */ double pages = sysconf (_SC_PHYS_PAGES); double pagesize = sysconf (_SC_PAGESIZE); if (0 <= pages && 0 <= pagesize) return pages * pagesize; } #endif #if HAVE_PSTAT_GETSTATIC { /* This works on hpux11. */ struct pst_static pss; if (0 <= pstat_getstatic (&pss, sizeof pss, 1, 0)) { double pages = pss.physical_memory; double pagesize = pss.page_size; if (0 <= pages && 0 <= pagesize) return pages * pagesize; } } #endif #if HAVE_SYSMP && defined MP_SAGET && defined MPSA_RMINFO && defined _SC_PAGESIZE { /* This works on irix6. */ struct rminfo realmem; if (sysmp (MP_SAGET, MPSA_RMINFO, &realmem, sizeof realmem) == 0) { double pagesize = sysconf (_SC_PAGESIZE); double pages = realmem.physmem; if (0 <= pages && 0 <= pagesize) return pages * pagesize; } } #endif #if HAVE_GETSYSINFO && defined GSI_PHYSMEM { /* This works on Tru64 UNIX V4/5. */ int physmem; if (getsysinfo (GSI_PHYSMEM, (caddr_t) &physmem, sizeof (physmem), NULL, NULL, NULL) == 1) { double kbytes = physmem; if (0 <= kbytes) return kbytes * 1024.0; } } #endif #if HAVE_SYSCTL && defined HW_PHYSMEM { /* This works on *bsd and darwin. */ unsigned int physmem; size_t len = sizeof physmem; static int mib[2] = { CTL_HW, HW_PHYSMEM }; if (sysctl (mib, ARRAY_SIZE (mib), &physmem, &len, NULL, 0) == 0 && len == sizeof (physmem)) return (double) physmem; } #endif #if HAVE__SYSTEM_CONFIGURATION /* This works on AIX. */ return _system_configuration.physmem; #endif #if defined _WIN32 { /* this works on windows */ PFN_MS_EX pfnex; HMODULE h = GetModuleHandle ("kernel32.dll"); if (!h) return 0.0; /* Use GlobalMemoryStatusEx if available. */ if ((pfnex = (PFN_MS_EX) GetProcAddress (h, "GlobalMemoryStatusEx"))) { lMEMORYSTATUSEX lms_ex; lms_ex.dwLength = sizeof lms_ex; if (!pfnex (&lms_ex)) return 0.0; return (double) lms_ex.ullTotalPhys; } /* Fall back to GlobalMemoryStatus which is always available. but returns wrong results for physical memory > 4GB. */ else { MEMORYSTATUS ms; GlobalMemoryStatus (&ms); return (double) ms.dwTotalPhys; } } #endif /* Guess 64 MB. It's probably an older host, so guess small. */ return 64 * 1024 * 1024; }
/* Return the amount of physical memory available. */ double physmem_available (void) { #if defined _SC_AVPHYS_PAGES && defined _SC_PAGESIZE { /* This works on linux-gnu, solaris2 and cygwin. */ double pages = sysconf (_SC_AVPHYS_PAGES); double pagesize = sysconf (_SC_PAGESIZE); if (0 <= pages && 0 <= pagesize) return pages * pagesize; } #endif #if HAVE_PSTAT_GETSTATIC && HAVE_PSTAT_GETDYNAMIC { /* This works on hpux11. */ struct pst_static pss; struct pst_dynamic psd; if (0 <= pstat_getstatic (&pss, sizeof pss, 1, 0) && 0 <= pstat_getdynamic (&psd, sizeof psd, 1, 0)) { double pages = psd.psd_free; double pagesize = pss.page_size; if (0 <= pages && 0 <= pagesize) return pages * pagesize; } } #endif #if HAVE_SYSMP && defined MP_SAGET && defined MPSA_RMINFO && defined _SC_PAGESIZE { /* This works on irix6. */ struct rminfo realmem; if (sysmp (MP_SAGET, MPSA_RMINFO, &realmem, sizeof realmem) == 0) { double pagesize = sysconf (_SC_PAGESIZE); double pages = realmem.availrmem; if (0 <= pages && 0 <= pagesize) return pages * pagesize; } } #endif #if HAVE_TABLE && defined TBL_VMSTATS { /* This works on Tru64 UNIX V4/5. */ struct tbl_vmstats vmstats; if (table (TBL_VMSTATS, 0, &vmstats, 1, sizeof (vmstats)) == 1) { double pages = vmstats.free_count; double pagesize = vmstats.pagesize; if (0 <= pages && 0 <= pagesize) return pages * pagesize; } } #endif #if HAVE_SYSCTL && defined HW_USERMEM { /* This works on *bsd and darwin. */ unsigned int usermem; size_t len = sizeof usermem; static int mib[2] = { CTL_HW, HW_USERMEM }; if (sysctl (mib, ARRAY_SIZE (mib), &usermem, &len, NULL, 0) == 0 && len == sizeof (usermem)) return (double) usermem; } #endif #if defined _WIN32 { /* this works on windows */ PFN_MS_EX pfnex; HMODULE h = GetModuleHandle ("kernel32.dll"); if (!h) return 0.0; /* Use GlobalMemoryStatusEx if available. */ if ((pfnex = (PFN_MS_EX) GetProcAddress (h, "GlobalMemoryStatusEx"))) { lMEMORYSTATUSEX lms_ex; lms_ex.dwLength = sizeof lms_ex; if (!pfnex (&lms_ex)) return 0.0; return (double) lms_ex.ullAvailPhys; } /* Fall back to GlobalMemoryStatus which is always available. but returns wrong results for physical memory > 4GB */ else { MEMORYSTATUS ms; GlobalMemoryStatus (&ms); return (double) ms.dwAvailPhys; } } #endif /* Guess 25% of physical memory. */ return physmem_total () / 4; }
/* * Search for interface with name "ifn", and fill n accordingly: * * n->ip ip address of interface "ifn" * n->if_name copy of interface name "ifn" */ static void set_addr_dynamic(const char *ifn, struct cfg_nat *n) { size_t needed; int mib[6]; char *buf, *lim, *next; struct if_msghdr *ifm; struct ifa_msghdr *ifam; struct sockaddr_dl *sdl; struct sockaddr_in *sin; int ifIndex, ifMTU; mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = AF_INET; mib[4] = NET_RT_IFLIST; mib[5] = 0; /* * Get interface data. */ if (sysctl(mib, 6, NULL, &needed, NULL, 0) == -1) err(1, "iflist-sysctl-estimate"); buf = safe_calloc(1, needed); if (sysctl(mib, 6, buf, &needed, NULL, 0) == -1) err(1, "iflist-sysctl-get"); lim = buf + needed; /* * Loop through interfaces until one with * given name is found. This is done to * find correct interface index for routing * message processing. */ ifIndex = 0; next = buf; while (next < lim) { ifm = (struct if_msghdr *)next; next += ifm->ifm_msglen; if (ifm->ifm_version != RTM_VERSION) { if (co.verbose) warnx("routing message version %d " "not understood", ifm->ifm_version); continue; } if (ifm->ifm_type == RTM_IFINFO) { sdl = (struct sockaddr_dl *)(ifm + 1); if (strlen(ifn) == sdl->sdl_nlen && strncmp(ifn, sdl->sdl_data, sdl->sdl_nlen) == 0) { ifIndex = ifm->ifm_index; ifMTU = ifm->ifm_data.ifi_mtu; break; } } } if (!ifIndex) errx(1, "unknown interface name %s", ifn); /* * Get interface address. */ sin = NULL; while (next < lim) { ifam = (struct ifa_msghdr *)next; next += ifam->ifam_msglen; if (ifam->ifam_version != RTM_VERSION) { if (co.verbose) warnx("routing message version %d " "not understood", ifam->ifam_version); continue; } if (ifam->ifam_type != RTM_NEWADDR) break; if (ifam->ifam_addrs & RTA_IFA) { int i; char *cp = (char *)(ifam + 1); for (i = 1; i < RTA_IFA; i <<= 1) { if (ifam->ifam_addrs & i) cp += SA_SIZE((struct sockaddr *)cp); } if (((struct sockaddr *)cp)->sa_family == AF_INET) { sin = (struct sockaddr_in *)cp; break; } } } if (sin == NULL) errx(1, "%s: cannot get interface address", ifn); n->ip = sin->sin_addr; strncpy(n->if_name, ifn, IF_NAMESIZE); free(buf); }
void FeedbackDialog::GenerateSpecs() { // Gather some information about the system and embed it into the report QDesktopWidget* screen = QApplication::desktop(); QString os_version = "Operating system: "; QString qt_version = QString("Qt version: ") + QT_VERSION_STR + QString("\n"); QString total_ram = "Total RAM: "; QString number_of_cores = "Number of cores: "; QString compiler_bits = "Compiler architecture: "; QString compiler_version = "Compiler version: "; QString kernel_line = "Kernel: "; QString screen_size = "Size of the screen(s): " + QString::number(screen->width()) + "x" + QString::number(screen->height()) + "\n"; QString number_of_screens = "Number of screens: " + QString::number(screen->screenCount()) + "\n"; QString processor_name = "Processor: "; // platform specific code #ifdef Q_OS_MACX number_of_cores += QString::number(sysconf(_SC_NPROCESSORS_ONLN)) + "\n"; uint64_t memsize; size_t len = sizeof(memsize); static int mib_s[2] = { CTL_HW, HW_MEMSIZE }; if (sysctl (mib_s, 2, &memsize, &len, NULL, 0) == 0) total_ram += QString::number(memsize/1024/1024) + " MB\n"; else total_ram += "Error getting total RAM information\n"; int mib[] = {CTL_KERN, KERN_OSRELEASE}; sysctl(mib, sizeof mib / sizeof(int), NULL, &len, NULL, 0); char *kernelVersion = (char *)malloc(sizeof(char)*len); sysctl(mib, sizeof mib / sizeof(int), kernelVersion, &len, NULL, 0); QString kernelVersionStr = QString(kernelVersion); free(kernelVersion); int major_version = kernelVersionStr.split(".").first().toUInt() - 4; int minor_version = kernelVersionStr.split(".").at(1).toUInt(); os_version += QString("Mac OS X 10.%1.%2").arg(major_version).arg(minor_version) + " "; switch(major_version) { case 4: os_version += "\"Tiger\"\n"; break; case 5: os_version += "\"Leopard\"\n"; break; case 6: os_version += "\"Snow Leopard\"\n"; break; case 7: os_version += "\"Lion\"\n"; break; case 8: os_version += "\"Mountain Lion\"\n"; break; default: os_version += "\"Unknown version\"\n"; break; } #endif #ifdef Q_OS_WIN SYSTEM_INFO sysinfo; GetSystemInfo(&sysinfo); number_of_cores += QString::number(sysinfo.dwNumberOfProcessors) + "\n"; MEMORYSTATUSEX status; status.dwLength = sizeof(status); GlobalMemoryStatusEx(&status); total_ram += QString::number(status.ullTotalPhys/1024/1024) + " MB\n"; switch(QSysInfo::windowsVersion()) { case QSysInfo::WV_NT: os_version += "Windows NT\n"; break; case QSysInfo::WV_2000: os_version += "Windows 2000\n"; break; case QSysInfo::WV_XP: os_version += "Windows XP\n"; break; case QSysInfo::WV_2003: os_version += "Windows Server 2003\n"; break; case QSysInfo::WV_VISTA: os_version += "Windows Vista\n"; break; case QSysInfo::WV_WINDOWS7: os_version += "Windows 7\n"; break; #if QT_VERSION >= QT_VERSION_CHECK(5, 0, 0) case QSysInfo::WV_WINDOWS8: os_version += "Windows 8\n"; break; #endif default: os_version += "Windows (Unknown version)\n"; break; } kernel_line += "Windows kernel\n"; #endif #ifdef Q_OS_LINUX number_of_cores += QString::number(sysconf(_SC_NPROCESSORS_ONLN)) + "\n"; quint32 pages = sysconf(_SC_PHYS_PAGES); quint32 page_size = sysconf(_SC_PAGE_SIZE); quint64 total = (quint64)pages * page_size / 1024 / 1024; total_ram += QString::number(total) + " MB\n"; os_version += "GNU/Linux or BSD\n"; #endif // uname -a #if defined(Q_OS_LINUX) || defined(Q_OS_MAC) QProcess *process = new QProcess(); QStringList arguments = QStringList("-a"); process->start("uname", arguments); if (process->waitForFinished()) kernel_line += QString(process->readAll()); delete process; #endif #if (defined(Q_OS_WIN) && defined(__i386__)) || defined(__x86_64__) // cpu info quint32 registers[4]; quint32 i; i = 0x80000002; asm volatile ("cpuid" : "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]) : "a" (i), "c" (0)); processor_name += QByteArray(reinterpret_cast<char*>(®isters[0]), 4); processor_name += QByteArray(reinterpret_cast<char*>(®isters[1]), 4); processor_name += QByteArray(reinterpret_cast<char*>(®isters[2]), 4); processor_name += QByteArray(reinterpret_cast<char*>(®isters[3]), 4); i = 0x80000003; asm volatile ("cpuid" : "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]) : "a" (i), "c" (0)); processor_name += QByteArray(reinterpret_cast<char*>(®isters[0]), 4); processor_name += QByteArray(reinterpret_cast<char*>(®isters[1]), 4); processor_name += QByteArray(reinterpret_cast<char*>(®isters[2]), 4); processor_name += QByteArray(reinterpret_cast<char*>(®isters[3]), 4); i = 0x80000004; asm volatile ("cpuid" : "=a" (registers[0]), "=b" (registers[1]), "=c" (registers[2]), "=d" (registers[3]) : "a" (i), "c" (0)); processor_name += QByteArray(reinterpret_cast<char*>(®isters[0]), 4); processor_name += QByteArray(reinterpret_cast<char*>(®isters[1]), 4); processor_name += QByteArray(reinterpret_cast<char*>(®isters[2]), 4); processor_name += QByteArray(reinterpret_cast<char*>(®isters[3]), 4); processor_name += "\n"; #else processor_name += "Unknown"; #endif // compiler #ifdef __GNUC__ compiler_version += "GCC " + QString(__VERSION__) + "\n"; #else compiler_version += "Unknown\n"; #endif if(sizeof(void*) == 4) compiler_bits += "i386\n"; else if(sizeof(void*) == 8) compiler_bits += "x86_64\n"; // concat system info specs = qt_version + os_version + total_ram + screen_size + number_of_screens + processor_name + number_of_cores + compiler_version + compiler_bits + kernel_line; }
static int init (void) { #if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE kern_return_t status; port_host = mach_host_self (); /* FIXME: Free `cpu_list' if it's not NULL */ if ((status = host_processors (port_host, &cpu_list, &cpu_list_len)) != KERN_SUCCESS) { ERROR ("cpu plugin: host_processors returned %i", (int) status); cpu_list_len = 0; return (-1); } DEBUG ("host_processors returned %i %s", (int) cpu_list_len, cpu_list_len == 1 ? "processor" : "processors"); INFO ("cpu plugin: Found %i processor%s.", (int) cpu_list_len, cpu_list_len == 1 ? "" : "s"); cpu_temp_retry_max = 86400 / CDTIME_T_TO_TIME_T (plugin_get_interval ()); /* #endif PROCESSOR_CPU_LOAD_INFO */ #elif defined(HAVE_LIBKSTAT) kstat_t *ksp_chain; numcpu = 0; if (kc == NULL) return (-1); /* Solaris doesn't count linear.. *sigh* */ for (numcpu = 0, ksp_chain = kc->kc_chain; (numcpu < MAX_NUMCPU) && (ksp_chain != NULL); ksp_chain = ksp_chain->ks_next) if (strncmp (ksp_chain->ks_module, "cpu_stat", 8) == 0) ksp[numcpu++] = ksp_chain; /* #endif HAVE_LIBKSTAT */ #elif CAN_USE_SYSCTL size_t numcpu_size; int mib[2] = {CTL_HW, HW_NCPU}; int status; numcpu = 0; numcpu_size = sizeof (numcpu); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &numcpu, &numcpu_size, NULL, 0); if (status == -1) { char errbuf[1024]; WARNING ("cpu plugin: sysctl: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } /* #endif CAN_USE_SYSCTL */ #elif defined (HAVE_SYSCTLBYNAME) size_t numcpu_size; numcpu_size = sizeof (numcpu); if (sysctlbyname ("hw.ncpu", &numcpu, &numcpu_size, NULL, 0) < 0) { char errbuf[1024]; WARNING ("cpu plugin: sysctlbyname(hw.ncpu): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } #ifdef HAVE_SYSCTL_KERN_CP_TIMES numcpu_size = sizeof (maxcpu); if (sysctlbyname("kern.smp.maxcpus", &maxcpu, &numcpu_size, NULL, 0) < 0) { char errbuf[1024]; WARNING ("cpu plugin: sysctlbyname(kern.smp.maxcpus): %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } #else if (numcpu != 1) NOTICE ("cpu: Only one processor supported when using `sysctlbyname' (found %i)", numcpu); #endif /* #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) /* nothing to initialize */ /* #endif HAVE_LIBSTATGRAB */ #elif defined(HAVE_PERFSTAT) /* nothing to initialize */ #endif /* HAVE_PERFSTAT */ return (0); } /* int init */
static time_t get_boot_time (void) { #if defined (BOOT_TIME) int counter; #endif if (boot_time_initialized) return boot_time; boot_time_initialized = 1; #if defined (CTL_KERN) && defined (KERN_BOOTTIME) { int mib[2]; size_t size; struct timeval boottime_val; mib[0] = CTL_KERN; mib[1] = KERN_BOOTTIME; size = sizeof (boottime_val); if (sysctl (mib, 2, &boottime_val, &size, NULL, 0) >= 0) { boot_time = boottime_val.tv_sec; return boot_time; } } #endif /* defined (CTL_KERN) && defined (KERN_BOOTTIME) */ if (BOOT_TIME_FILE) { struct stat st; if (stat (BOOT_TIME_FILE, &st) == 0) { boot_time = st.st_mtime; return boot_time; } } #if defined (BOOT_TIME) #ifndef CANNOT_DUMP /* The utmp routines maintain static state. Don't touch that state unless we are initialized, since it might not survive dumping. */ if (! initialized) return boot_time; #endif /* not CANNOT_DUMP */ /* Try to get boot time from utmp before wtmp, since utmp is typically much smaller than wtmp. Passing a null pointer causes get_boot_time_1 to inspect the default file, namely utmp. */ get_boot_time_1 (0, 0); if (boot_time) return boot_time; /* Try to get boot time from the current wtmp file. */ get_boot_time_1 (WTMP_FILE, 1); /* If we did not find a boot time in wtmp, look at wtmp, and so on. */ for (counter = 0; counter < 20 && ! boot_time; counter++) { char cmd_string[sizeof WTMP_FILE ".19.gz"]; Lisp_Object tempname, filename; bool delete_flag = 0; filename = Qnil; tempname = make_formatted_string (cmd_string, "%s.%d", WTMP_FILE, counter); if (! NILP (Ffile_exists_p (tempname))) filename = tempname; else { tempname = make_formatted_string (cmd_string, "%s.%d.gz", WTMP_FILE, counter); if (! NILP (Ffile_exists_p (tempname))) { /* The utmp functions on mescaline.gnu.org accept only file names up to 8 characters long. Choose a 2 character long prefix, and call make_temp_file with second arg non-zero, so that it will add not more than 6 characters to the prefix. */ filename = Fexpand_file_name (build_string ("wt"), Vtemporary_file_directory); filename = make_temp_name (filename, 1); CALLN (Fcall_process, build_string ("gzip"), Qnil, list2 (QCfile, filename), Qnil, build_string ("-cd"), tempname); delete_flag = 1; } } if (! NILP (filename)) { get_boot_time_1 (SSDATA (filename), 1); if (delete_flag) unlink (SSDATA (filename)); } } return boot_time; #else return 0; #endif }
static int cpu_read (void) { #if PROCESSOR_CPU_LOAD_INFO || PROCESSOR_TEMPERATURE int cpu; kern_return_t status; #if PROCESSOR_CPU_LOAD_INFO processor_cpu_load_info_data_t cpu_info; mach_msg_type_number_t cpu_info_len; #endif #if PROCESSOR_TEMPERATURE processor_info_data_t cpu_temp; mach_msg_type_number_t cpu_temp_len; #endif host_t cpu_host; for (cpu = 0; cpu < cpu_list_len; cpu++) { #if PROCESSOR_CPU_LOAD_INFO derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; memset(derives, -1, sizeof(derives)); cpu_host = 0; cpu_info_len = PROCESSOR_BASIC_INFO_COUNT; if ((status = processor_info (cpu_list[cpu], PROCESSOR_CPU_LOAD_INFO, &cpu_host, (processor_info_t) &cpu_info, &cpu_info_len)) != KERN_SUCCESS) { ERROR ("cpu plugin: processor_info failed with status %i", (int) status); continue; } if (cpu_info_len < CPU_STATE_MAX) { ERROR ("cpu plugin: processor_info returned only %i elements..", cpu_info_len); continue; } derives[CPU_SUBMIT_USER] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_USER]; derives[CPU_SUBMIT_NICE] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_NICE]; derives[CPU_SUBMIT_SYSTEM] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_SYSTEM]; derives[CPU_SUBMIT_IDLE] = (derive_t) cpu_info.cpu_ticks[CPU_STATE_IDLE]; submit (cpu, derives); #endif /* PROCESSOR_CPU_LOAD_INFO */ #if PROCESSOR_TEMPERATURE /* * Not all Apple computers do have this ability. To minimize * the messages sent to the syslog we do an exponential * stepback if `processor_info' fails. We still try ~once a day * though.. */ if (cpu_temp_retry_counter > 0) { cpu_temp_retry_counter--; continue; } cpu_temp_len = PROCESSOR_INFO_MAX; status = processor_info (cpu_list[cpu], PROCESSOR_TEMPERATURE, &cpu_host, cpu_temp, &cpu_temp_len); if (status != KERN_SUCCESS) { ERROR ("cpu plugin: processor_info failed: %s", mach_error_string (status)); cpu_temp_retry_counter = cpu_temp_retry_step; cpu_temp_retry_step *= 2; if (cpu_temp_retry_step > cpu_temp_retry_max) cpu_temp_retry_step = cpu_temp_retry_max; continue; } if (cpu_temp_len != 1) { DEBUG ("processor_info (PROCESSOR_TEMPERATURE) returned %i elements..?", (int) cpu_temp_len); continue; } cpu_temp_retry_counter = 0; cpu_temp_retry_step = 1; #endif /* PROCESSOR_TEMPERATURE */ } submit_flush (); /* #endif PROCESSOR_CPU_LOAD_INFO */ #elif defined(KERNEL_LINUX) int cpu; FILE *fh; char buf[1024]; char *fields[9]; int numfields; if ((fh = fopen ("/proc/stat", "r")) == NULL) { char errbuf[1024]; ERROR ("cpu plugin: fopen (/proc/stat) failed: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } while (fgets (buf, 1024, fh) != NULL) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; if (strncmp (buf, "cpu", 3)) continue; if ((buf[3] < '0') || (buf[3] > '9')) continue; numfields = strsplit (buf, fields, 9); if (numfields < 5) continue; cpu = atoi (fields[0] + 3); derives[CPU_SUBMIT_USER] = atoll(fields[1]); derives[CPU_SUBMIT_NICE] = atoll(fields[2]); derives[CPU_SUBMIT_SYSTEM] = atoll(fields[3]); derives[CPU_SUBMIT_IDLE] = atoll(fields[4]); if (numfields >= 8) { derives[CPU_SUBMIT_WAIT] = atoll(fields[5]); derives[CPU_SUBMIT_INTERRUPT] = atoll(fields[6]); derives[CPU_SUBMIT_SOFTIRQ] = atoll(fields[6]); if (numfields >= 9) derives[CPU_SUBMIT_STEAL] = atoll(fields[8]); } submit(cpu, derives); } submit_flush(); fclose (fh); /* #endif defined(KERNEL_LINUX) */ #elif defined(HAVE_LIBKSTAT) int cpu; static cpu_stat_t cs; if (kc == NULL) return (-1); for (cpu = 0; cpu < numcpu; cpu++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; if (kstat_read (kc, ksp[cpu], &cs) == -1) continue; /* error message? */ memset(derives, -1, sizeof(derives)); derives[CPU_SUBMIT_IDLE] = cs.cpu_sysinfo.cpu[CPU_IDLE]; derives[CPU_SUBMIT_USER] = cs.cpu_sysinfo.cpu[CPU_USER]; derives[CPU_SUBMIT_SYSTEM] = cs.cpu_sysinfo.cpu[CPU_KERNEL]; derives[CPU_SUBMIT_WAIT] = cs.cpu_sysinfo.cpu[CPU_WAIT]; submit (ksp[cpu]->ks_instance, derives); } submit_flush (); /* #endif defined(HAVE_LIBKSTAT) */ #elif CAN_USE_SYSCTL uint64_t cpuinfo[numcpu][CPUSTATES]; size_t cpuinfo_size; int status; int i; if (numcpu < 1) { ERROR ("cpu plugin: Could not determine number of " "installed CPUs using sysctl(3)."); return (-1); } memset (cpuinfo, 0, sizeof (cpuinfo)); #if defined(KERN_CPTIME2) if (numcpu > 1) { for (i = 0; i < numcpu; i++) { int mib[] = {CTL_KERN, KERN_CPTIME2, i}; cpuinfo_size = sizeof (cpuinfo[0]); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), cpuinfo[i], &cpuinfo_size, NULL, 0); if (status == -1) { char errbuf[1024]; ERROR ("cpu plugin: sysctl failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } } } else #endif /* defined(KERN_CPTIME2) */ { int mib[] = {CTL_KERN, KERN_CPTIME}; long cpuinfo_tmp[CPUSTATES]; cpuinfo_size = sizeof(cpuinfo_tmp); status = sysctl (mib, STATIC_ARRAY_SIZE (mib), &cpuinfo_tmp, &cpuinfo_size, NULL, 0); if (status == -1) { char errbuf[1024]; ERROR ("cpu plugin: sysctl failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for(i = 0; i < CPUSTATES; i++) { cpuinfo[0][i] = cpuinfo_tmp[i]; } } for (i = 0; i < numcpu; i++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; derives[CPU_SUBMIT_USER] = cpuinfo[i][CP_USER]; derives[CPU_SUBMIT_NICE] = cpuinfo[i][CP_NICE]; derives[CPU_SUBMIT_SYSTEM] = cpuinfo[i][CP_SYS]; derives[CPU_SUBMIT_IDLE] = cpuinfo[i][CP_IDLE]; derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[i][CP_INTR]; submit(i, derives); } submit_flush(); /* #endif CAN_USE_SYSCTL */ #elif defined(HAVE_SYSCTLBYNAME) && defined(HAVE_SYSCTL_KERN_CP_TIMES) long cpuinfo[maxcpu][CPUSTATES]; size_t cpuinfo_size; int i; memset (cpuinfo, 0, sizeof (cpuinfo)); cpuinfo_size = sizeof (cpuinfo); if (sysctlbyname("kern.cp_times", &cpuinfo, &cpuinfo_size, NULL, 0) < 0) { char errbuf[1024]; ERROR ("cpu plugin: sysctlbyname failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for (i = 0; i < numcpu; i++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; derives[CPU_SUBMIT_USER] = cpuinfo[i][CP_USER]; derives[CPU_SUBMIT_NICE] = cpuinfo[i][CP_NICE]; derives[CPU_SUBMIT_SYSTEM] = cpuinfo[i][CP_SYS]; derives[CPU_SUBMIT_IDLE] = cpuinfo[i][CP_IDLE]; derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[i][CP_INTR]; submit(i, derives); } submit_flush(); /* #endif HAVE_SYSCTL_KERN_CP_TIMES */ #elif defined(HAVE_SYSCTLBYNAME) long cpuinfo[CPUSTATES]; size_t cpuinfo_size; derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; cpuinfo_size = sizeof (cpuinfo); if (sysctlbyname("kern.cp_time", &cpuinfo, &cpuinfo_size, NULL, 0) < 0) { char errbuf[1024]; ERROR ("cpu plugin: sysctlbyname failed: %s.", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } derives[CPU_SUBMIT_USER] = cpuinfo[CP_USER]; derives[CPU_SUBMIT_SYSTEM] = cpuinfo[CP_SYS]; derives[CPU_SUBMIT_NICE] = cpuinfo[CP_NICE]; derives[CPU_SUBMIT_IDLE] = cpuinfo[CP_IDLE]; derives[CPU_SUBMIT_INTERRUPT] = cpuinfo[CP_INTR]; submit(0, derives); submit_flush(); /* #endif HAVE_SYSCTLBYNAME */ #elif defined(HAVE_LIBSTATGRAB) sg_cpu_stats *cs; derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; cs = sg_get_cpu_stats (); if (cs == NULL) { ERROR ("cpu plugin: sg_get_cpu_stats failed."); return (-1); } derives[CPU_SUBMIT_IDLE] = (derive_t) cs->idle; derives[CPU_SUBMIT_NICE] = (derive_t) cs->nice; derives[CPU_SUBMIT_SWAP] = (derive_t) cs->swap; derives[CPU_SUBMIT_SYSTEM] = (derive_t) cs->kernel; derives[CPU_SUBMIT_USER] = (derive_t) cs->user; derives[CPU_SUBMIT_WAIT] = (derive_t) cs->iowait; submit(0, derives); submit_flush(); /* #endif HAVE_LIBSTATGRAB */ #elif defined(HAVE_PERFSTAT) perfstat_id_t id; int i, cpus; numcpu = perfstat_cpu(NULL, NULL, sizeof(perfstat_cpu_t), 0); if(numcpu == -1) { char errbuf[1024]; WARNING ("cpu plugin: perfstat_cpu: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } if (pnumcpu != numcpu || perfcpu == NULL) { if (perfcpu != NULL) free(perfcpu); perfcpu = malloc(numcpu * sizeof(perfstat_cpu_t)); } pnumcpu = numcpu; id.name[0] = '\0'; if ((cpus = perfstat_cpu(&id, perfcpu, sizeof(perfstat_cpu_t), numcpu)) < 0) { char errbuf[1024]; WARNING ("cpu plugin: perfstat_cpu: %s", sstrerror (errno, errbuf, sizeof (errbuf))); return (-1); } for (i = 0; i < cpus; i++) { derive_t derives[CPU_SUBMIT_MAX] = { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1 }; derives[CPU_SUBMIT_IDLE] = perfcpu[i].idle; derives[CPU_SUBMIT_SYSTEM] = perfcpu[i].sys; derives[CPU_SUBMIT_USER] = perfcpu[i].user; derives[CPU_SUBMIT_WAIT] = perfcpu[i].wait; submit(i, derives); } submit_flush(); #endif /* HAVE_PERFSTAT */ return (0); }
int PROC_MEM(const char *cmd, const char *param, unsigned flags, AGENT_RESULT *result) { char procname[MAX_STRING_LEN], buffer[MAX_STRING_LEN], proccomm[MAX_STRING_LEN], *args; int do_task, pagesize, count, i, proc_ok, comm_ok, mib[4], mibs; double value = 0.0, memsize = 0; int proccount = 0; size_t sz; struct kinfo_proc *proc = NULL; struct passwd *usrinfo; if (num_param(param) > 4) return SYSINFO_RET_FAIL; if (0 != get_param(param, 1, procname, sizeof(procname))) *procname = '\0'; else if (strlen(procname) > ZBX_COMMLEN) procname[ZBX_COMMLEN] = '\0'; if (0 != get_param(param, 2, buffer, sizeof(buffer))) *buffer = '\0'; if (*buffer != '\0') { usrinfo = getpwnam(buffer); if (usrinfo == NULL) /* incorrect user name */ return SYSINFO_RET_FAIL; } else usrinfo = NULL; if (0 != get_param(param, 3, buffer, sizeof(buffer))) *buffer = '\0'; if (*buffer != '\0') { if (0 == strcmp(buffer, "avg")) do_task = DO_AVG; else if (0 == strcmp(buffer, "max")) do_task = DO_MAX; else if (0 == strcmp(buffer, "min")) do_task = DO_MIN; else if (0 == strcmp(buffer, "sum")) do_task = DO_SUM; else return SYSINFO_RET_FAIL; } else do_task = DO_SUM; if (0 != get_param(param, 4, proccomm, sizeof(proccomm))) *proccomm = '\0'; pagesize = getpagesize(); mib[0] = CTL_KERN; mib[1] = KERN_PROC; if (NULL != usrinfo) { mib[2] = KERN_PROC_UID; mib[3] = usrinfo->pw_uid; mibs = 4; } else { mib[2] = KERN_PROC_ALL; mib[3] = 0; mibs = 3; } sz = 0; if (0 != sysctl(mib, mibs, NULL, &sz, NULL, 0)) return SYSINFO_RET_FAIL; proc = (struct kinfo_proc *)zbx_malloc(proc, sz); if (0 != sysctl(mib, mibs, proc, &sz, NULL, 0)) { zbx_free(proc); return SYSINFO_RET_FAIL; } count = sz / sizeof(struct kinfo_proc); for (i = 0; i < count; i++) { #if(__FreeBSD_version > 500000) if (proc[i].ki_flag & P_KTHREAD) /* skip a system thread */ continue; #endif proc_ok = 0; comm_ok = 0; if (*procname == '\0' || 0 == strcmp(procname, proc[i].ZBX_PROC_COMM)) proc_ok = 1; if (*proccomm != '\0') { if (NULL != (args = get_commandline(&proc[i]))) if (zbx_regexp_match(args, proccomm, NULL) != NULL) comm_ok = 1; } else comm_ok = 1; if (proc_ok && comm_ok) { value = proc[i].ZBX_PROC_TSIZE + proc[i].ZBX_PROC_DSIZE + proc[i].ZBX_PROC_SSIZE; value *= pagesize; if (0 == proccount++) memsize = value; else { if (do_task == DO_MAX) memsize = MAX(memsize, value); else if (do_task == DO_MIN) memsize = MIN(memsize, value); else memsize += value; } } } zbx_free(proc); if (do_task == DO_AVG) SET_DBL_RESULT(result, proccount == 0 ? 0 : memsize/proccount); else SET_UI64_RESULT(result, memsize); return SYSINFO_RET_OK; }
static void bsd_acpi_check(void) { int bat_val = 0; int mib_state[4]; int mib_life[4]; int mib_time[4]; int mib_units[4]; size_t len; int state = 0; int level = 0; int time_min = 0; int life = 0; int batteries = 0; time_left = -1; battery_full = -1; have_battery = 0; have_power = 0; /* Read some information on first run. */ len = 4; sysctlnametomib("hw.acpi.battery.state", mib_state, &len); len = sizeof(state); if (sysctl(mib_state, 4, &state, &len, NULL, 0) == -1) /* ERROR */ state = -1; len = 4; sysctlnametomib("hw.acpi.battery.life", mib_life, &len); len = sizeof(life); if (sysctl(mib_life, 4, &life, &len, NULL, 0) == -1) /* ERROR */ level = -1; bat_val = life; len = 4; sysctlnametomib("hw.acpi.battery.time", mib_time, &len); len = sizeof(time); if (sysctl(mib_time, 4, &time_min, &len, NULL, 0) == -1) /* ERROR */ time_min = -1; len = 4; sysctlnametomib("hw.acpi.battery.units", mib_units, &len); len = sizeof(batteries); if (sysctl(mib_time, 4, &batteries, &len, NULL, 0) == -1) /* ERROR */ batteries = 1; if (time_min >= 0) time_left = time_min * 60; if (batteries == 1) /* hw.acpi.battery.units = 1 means NO BATTS */ time_left = -1; else if ((state == BATTERY_STATE_CHARGING) || (state == BATTERY_STATE_DISCHARGING)) { have_battery = 1; if (state == BATTERY_STATE_CHARGING) have_power = 1; else if (state == BATTERY_STATE_DISCHARGING) have_power = 0; if (level == -1) time_left = -1; else if (time_min == -1) { time_left = -1; battery_full = bat_val; } else battery_full = bat_val; } else { have_battery = 1; battery_full = 100; time_left = -1; have_power = 1; } }
isc_result_t isc_interfaceiter_create(isc_mem_t *mctx, isc_interfaceiter_t **iterp) { isc_interfaceiter_t *iter; isc_result_t result; size_t bufsize; size_t bufused; char strbuf[ISC_STRERRORSIZE]; REQUIRE(mctx != NULL); REQUIRE(iterp != NULL); REQUIRE(*iterp == NULL); iter = isc_mem_get(mctx, sizeof(*iter)); if (iter == NULL) return (ISC_R_NOMEMORY); iter->mctx = mctx; iter->buf = 0; /* * Determine the amount of memory needed. */ bufsize = 0; if (sysctl(mib, 6, NULL, &bufsize, NULL, (size_t) 0) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERSYSCTL, ISC_MSG_GETIFLISTSIZE, "getting interface " "list size: sysctl: %s"), strbuf); result = ISC_R_UNEXPECTED; goto failure; } iter->bufsize = bufsize; iter->buf = isc_mem_get(iter->mctx, iter->bufsize); if (iter->buf == NULL) { result = ISC_R_NOMEMORY; goto failure; } bufused = bufsize; if (sysctl(mib, 6, iter->buf, &bufused, NULL, (size_t) 0) < 0) { isc__strerror(errno, strbuf, sizeof(strbuf)); UNEXPECTED_ERROR(__FILE__, __LINE__, isc_msgcat_get(isc_msgcat, ISC_MSGSET_IFITERSYSCTL, ISC_MSG_GETIFLIST, "getting interface list: " "sysctl: %s"), strbuf); result = ISC_R_UNEXPECTED; goto failure; } iter->bufused = bufused; INSIST(iter->bufused <= iter->bufsize); /* * A newly created iterator has an undefined position * until isc_interfaceiter_first() is called. */ iter->pos = (unsigned int) -1; iter->result = ISC_R_FAILURE; iter->magic = IFITER_MAGIC; *iterp = iter; return (ISC_R_SUCCESS); failure: if (iter->buf != NULL) isc_mem_put(mctx, iter->buf, iter->bufsize); isc_mem_put(mctx, iter, sizeof(*iter)); return (result); }
/** * Returns the size of physical memory (RAM) in bytes. */ size_t _getMemorySize() { #if defined(_WIN32) && (defined(__CYGWIN__) || defined(__CYGWIN32__)) /* Cygwin under Windows. ------------------------------------ */ /* New 64-bit MEMORYSTATUSEX isn't available. Use old 32.bit */ MEMORYSTATUS status; status.dwLength = sizeof(status); GlobalMemoryStatus( &status ); return (size_t)status.dwTotalPhys; #elif defined(_WIN32) /* Windows. ------------------------------------------------- */ /* Use new 64-bit MEMORYSTATUSEX, not old 32-bit MEMORYSTATUS */ MEMORYSTATUSEX status; status.dwLength = sizeof(status); GlobalMemoryStatusEx( &status ); return (size_t)status.ullTotalPhys; #elif defined(__unix__) || defined(__unix) || defined(unix) || \ (defined(__APPLE__) && defined(__MACH__)) /* UNIX variants. ------------------------------------------- */ /* Prefer sysctl() over sysconf() except sysctl() HW_REALMEM and HW_PHYSMEM */ #if defined(CTL_HW) && (defined(HW_MEMSIZE) || defined(HW_PHYSMEM64)) int mib[2]; mib[0] = CTL_HW; #if defined(HW_MEMSIZE) mib[1] = HW_MEMSIZE; /* OSX. --------------------- */ #elif defined(HW_PHYSMEM64) mib[1] = HW_PHYSMEM64; /* NetBSD, OpenBSD. --------- */ #endif int64_t size = 0; /* 64-bit */ size_t len = sizeof( size ); if ( sysctl( mib, 2, &size, &len, NULL, 0 ) == 0 ) return (size_t)size; return 0L; /* Failed? */ #elif defined(_SC_AIX_REALMEM) /* AIX. ----------------------------------------------------- */ return (size_t)sysconf( _SC_AIX_REALMEM ) * (size_t)1024L; #elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) /* FreeBSD, Linux, OpenBSD, and Solaris. -------------------- */ return (size_t)sysconf( _SC_PHYS_PAGES ) * (size_t)sysconf( _SC_PAGESIZE ); #elif defined(_SC_PHYS_PAGES) && defined(_SC_PAGE_SIZE) /* Legacy. -------------------------------------------------- */ return (size_t)sysconf( _SC_PHYS_PAGES ) * (size_t)sysconf( _SC_PAGE_SIZE ); #elif defined(CTL_HW) && (defined(HW_PHYSMEM) || defined(HW_REALMEM)) /* DragonFly BSD, FreeBSD, NetBSD, OpenBSD, and OSX. -------- */ int mib[2]; mib[0] = CTL_HW; #if defined(HW_REALMEM) mib[1] = HW_REALMEM; /* FreeBSD. ----------------- */ #elif defined(HW_PYSMEM) mib[1] = HW_PHYSMEM; /* Others. ------------------ */ #endif unsigned int size = 0; /* 32-bit */ size_t len = sizeof( size ); if ( sysctl( mib, 2, &size, &len, NULL, 0 ) == 0 ) return (size_t)size; return 0L; /* Failed? */ #endif /* sysctl and sysconf variants */ #else return 0L; /* Unknown OS. */ #endif }
/* read sensors from sysctl */ void update_obsd_sensors() { int sensor_cnt, dev, numt, mib[5] = { CTL_HW, HW_SENSORS, 0, 0, 0 }; struct sensor sensor; struct sensordev sensordev; size_t slen, sdlen; enum sensor_type type; slen = sizeof(sensor); sdlen = sizeof(sensordev); sensor_cnt = 0; dev = obsd_sensors.device; // FIXME: read more than one device /* for (dev = 0; dev < MAXSENSORDEVICES; dev++) { */ mib[2] = dev; if (sysctl(mib, 3, &sensordev, &sdlen, NULL, 0) == -1) { if (errno != ENOENT) { warn("sysctl"); } return; // continue; } for (type = 0; type < SENSOR_MAX_TYPES; type++) { mib[3] = type; for (numt = 0; numt < sensordev.maxnumt[type]; numt++) { mib[4] = numt; if (sysctl(mib, 5, &sensor, &slen, NULL, 0) == -1) { if (errno != ENOENT) { warn("sysctl"); } continue; } if (sensor.flags & SENSOR_FINVALID) { continue; } switch (type) { case SENSOR_TEMP: obsd_sensors.temp[dev][sensor.numt] = (sensor.value - 273150000) / 1000000.0; break; case SENSOR_FANRPM: obsd_sensors.fan[dev][sensor.numt] = sensor.value; break; case SENSOR_VOLTS_DC: obsd_sensors.volt[dev][sensor.numt] = sensor.value / 1000000.0; break; default: break; } sensor_cnt++; } } /* } */ init_sensors = 1; }
int GetBSDProcessList(kinfo_proc **procList, size_t *procCount) // Returns a list of all BSD processes on the system. This routine // allocates the list and puts it in *procList and a count of the // number of entries in *procCount. You are responsible for freeing // this list (use "free" from System framework). // On success, the function returns 0. // On error, the function returns a BSD errno value. { int err; kinfo_proc * result; bool done; static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL, 0 }; // Declaring name as const requires us to cast it when passing it to // sysctl because the prototype doesn't include the const modifier. size_t length; assert( procList != NULL); assert(*procList == NULL); assert(procCount != NULL); *procCount = 0; // We start by calling sysctl with result == NULL and length == 0. // That will succeed, and set length to the appropriate length. // We then allocate a buffer of that size and call sysctl again // with that buffer. If that succeeds, we're done. If that fails // with ENOMEM, we have to throw away our buffer and loop. Note // that the loop causes use to call sysctl with NULL again; this // is necessary because the ENOMEM failure case sets length to // the amount of data returned, not the amount of data that // could have been returned. result = NULL; done = false; do { assert(result == NULL); // Call sysctl with a NULL buffer. length = 0; err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1, NULL, &length, NULL, 0); if (err == -1) { err = errno; } // Allocate an appropriately sized buffer based on the results // from the previous call. if (err == 0) { result = malloc(length); if (result == NULL) { err = ENOMEM; } } // Call sysctl again with the new buffer. If we get an ENOMEM // error, toss away our buffer and start again. if (err == 0) { err = sysctl( (int *) name, (sizeof(name) / sizeof(*name)) - 1, result, &length, NULL, 0); if (err == -1) { err = errno; } if (err == 0) { done = true; } else if (err == ENOMEM) { assert(result != NULL); free(result); result = NULL; err = 0; } } } while (err == 0 && ! done); // Clean up and establish post conditions. if (err != 0 && result != NULL) { free(result); result = NULL; } *procList = result; if (err == 0) { *procCount = length / sizeof(kinfo_proc); } assert( (err == 0) == (*procList != NULL) ); return err; }
int main(int ac, char **av) { int exp_eno; int lc; char *msg; char osname[OSNAMESZ]; int osnamelth, status; int name[] = { CTL_KERN, KERN_OSTYPE }; pid_t pid; struct passwd *ltpuser; /* parse standard options */ if ((msg = parse_opts(ac, av, NULL, NULL)) != NULL) { tst_brkm(TBROK, NULL, "OPTION PARSING ERROR - %s", msg); } setup(); if ((tst_kvercmp(2, 6, 32)) <= 0) { exp_eno = EPERM; } else { /* ^^ Look above this warning. ^^ */ tst_resm(TWARN, "this test's results are based on potentially undocumented behavior in the kernel. read the NOTE in the source file for more details"); exp_eno = EACCES; exp_enos[0] = EACCES; } TEST_EXP_ENOS(exp_enos); for (lc = 0; TEST_LOOPING(lc); lc++) { /* reset Tst_count in case we are looping */ Tst_count = 0; strcpy(osname, "Linux"); osnamelth = SIZE(osname); TEST(sysctl(name, SIZE(name), 0, 0, osname, osnamelth)); if (TEST_RETURN != -1) { tst_resm(TFAIL, "sysctl(2) succeeded unexpectedly"); } else { TEST_ERROR_LOG(TEST_ERRNO); if (TEST_ERRNO == exp_eno) { tst_resm(TPASS|TTERRNO, "Got expected error"); } else if (errno == ENOSYS) { tst_resm(TCONF, "You may need to make CONFIG_SYSCTL_SYSCALL=y" " to your kernel config."); } else { tst_resm(TFAIL|TTERRNO, "Got unexpected error"); } } osnamelth = SIZE(osname); if ((ltpuser = getpwnam("nobody")) == NULL) { tst_brkm(TBROK, cleanup, "getpwnam() failed"); } /* set process ID to "ltpuser1" */ if (seteuid(ltpuser->pw_uid) == -1) { tst_brkm(TBROK, cleanup, "seteuid() failed, errno %d", errno); } if ((pid = FORK_OR_VFORK()) == -1) { tst_brkm(TBROK, cleanup, "fork() failed"); } if (pid == 0) { TEST(sysctl(name, SIZE(name), 0, 0, osname, osnamelth)); if (TEST_RETURN != -1) { tst_resm(TFAIL, "call succeeded unexpectedly"); } else { TEST_ERROR_LOG(TEST_ERRNO); if (TEST_ERRNO == exp_eno) { tst_resm(TPASS|TTERRNO, "Got expected error"); } else if (TEST_ERRNO == ENOSYS) { tst_resm(TCONF, "You may need to make CONFIG_SYSCTL_SYSCALL=y" " to your kernel config."); } else { tst_resm(TFAIL|TTERRNO, "Got unexpected error"); } } cleanup(); } else { /* wait for the child to finish */ wait(&status); } /* set process ID back to root */ if (seteuid(0) == -1) { tst_brkm(TBROK, cleanup, "seteuid() failed"); } } cleanup(); tst_exit(); }
long read_ip_stat(IP_STAT_STRUCTURE * ipstat, int magic) { long ret_value = 0; #if (defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS)) int i; #endif #if !(defined (linux) || defined(solaris2)) static int ttl, forward; #endif #ifdef hpux11 int fd; struct nmparms p; unsigned int ulen; #endif #if (defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS)) static int sname[4] = { CTL_NET, PF_INET, IPPROTO_IP, 0 }; size_t len; #endif #ifdef hpux11 if ((fd = open_mib("/dev/ip", O_RDONLY, 0, NM_ASYNC_OFF)) < 0) return (-1); /* error */ switch (magic) { case IPFORWARDING: p.objid = ID_ipForwarding; break; case IPDEFAULTTTL: p.objid = ID_ipDefaultTTL; break; case IPINRECEIVES: p.objid = ID_ipInReceives; break; case IPINHDRERRORS: p.objid = ID_ipInHdrErrors; break; case IPINADDRERRORS: p.objid = ID_ipInAddrErrors; break; case IPFORWDATAGRAMS: p.objid = ID_ipForwDatagrams; break; case IPINUNKNOWNPROTOS: p.objid = ID_ipInUnknownProtos; break; case IPINDISCARDS: p.objid = ID_ipInDiscards; break; case IPINDELIVERS: p.objid = ID_ipInDelivers; break; case IPOUTREQUESTS: p.objid = ID_ipOutRequests; break; case IPOUTDISCARDS: p.objid = ID_ipOutDiscards; break; case IPOUTNOROUTES: p.objid = ID_ipOutNoRoutes; break; case IPREASMTIMEOUT: p.objid = ID_ipReasmTimeout; break; case IPREASMREQDS: p.objid = ID_ipReasmReqds; break; case IPREASMOKS: p.objid = ID_ipReasmOKs; break; case IPREASMFAILS: p.objid = ID_ipReasmFails; break; case IPFRAGOKS: p.objid = ID_ipFragOKs; break; case IPFRAGFAILS: p.objid = ID_ipFragFails; break; case IPFRAGCREATES: p.objid = ID_ipFragCreates; break; case IPROUTEDISCARDS: p.objid = ID_ipRoutingDiscards; break; default: *ipstat = 0; close_mib(fd); return (0); } p.buffer = (void *) ipstat; ulen = sizeof(IP_STAT_STRUCTURE); p.len = &ulen; ret_value = get_mib_info(fd, &p); close_mib(fd); return (ret_value); /* 0: ok, < 0: error */ #else /* hpux11 */ if (ip_stats_cache_marker && (!atime_ready (ip_stats_cache_marker, IP_STATS_CACHE_TIMEOUT * 1000))) #if !(defined(linux) || defined(solaris2)) return ((magic == IPFORWARDING ? forward : (magic == IPDEFAULTTTL ? ttl : 0))); #else return 0; #endif if (ip_stats_cache_marker) atime_setMarker(ip_stats_cache_marker); else ip_stats_cache_marker = atime_newMarker(); #ifdef linux ret_value = linux_read_ip_stat(ipstat); #endif #ifdef solaris2 ret_value = getMibstat(MIB_IP, ipstat, sizeof(mib2_ip_t), GET_FIRST, &Get_everything, NULL); #endif #ifdef WIN32 ret_value = GetIpStatistics(ipstat); #endif #if !(defined(linux) || defined(solaris2) || defined(WIN32)) if (magic == IPFORWARDING) { #if defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS) len = sizeof i; sname[3] = IPCTL_FORWARDING; if (sysctl(sname, 4, &i, &len, 0, 0) < 0) forward = -1; else forward = (i ? 1 /* GATEWAY */ : 2 /* HOST */ ); #else if (!auto_nlist (IP_FORWARDING_SYMBOL, (char *) &ret_value, sizeof(ret_value))) forward = -1; else forward = (ret_value ? 1 /* GATEWAY */ : 2 /* HOST */ ); #endif if (forward == -1) { free(ip_stats_cache_marker); ip_stats_cache_marker = NULL; } return forward; } if (magic == IPDEFAULTTTL) { #if (defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS)) len = sizeof i; sname[3] = IPCTL_DEFTTL; if (sysctl(sname, 4, &i, &len, 0, 0) < 0) ttl = -1; else ttl = i; #else if (!auto_nlist (TCP_TTL_SYMBOL, (char *) &ret_value, sizeof(ret_value))) ttl = -1; else ttl = ret_value; #endif if (ttl == -1) { free(ip_stats_cache_marker); ip_stats_cache_marker = NULL; } return ttl; } #ifdef HAVE_SYS_TCPIPSTATS_H ret_value = sysmp(MP_SAGET, MPSA_TCPIPSTATS, ipstat, sizeof *ipstat); #endif #if (defined(CAN_USE_SYSCTL) && defined(IPCTL_STATS)) len = sizeof *ipstat; sname[3] = IPCTL_STATS; ret_value = sysctl(sname, 4, ipstat, &len, 0, 0); #endif #ifdef IPSTAT_SYMBOL if (auto_nlist(IPSTAT_SYMBOL, (char *) ipstat, sizeof(*ipstat))) ret_value = 0; #endif #endif /* !(defined(linux) || defined(solaris2)) */ if (ret_value == -1) { free(ip_stats_cache_marker); ip_stats_cache_marker = NULL; } return ret_value; #endif /* hpux11 */ }
static int vma_iterate_bsd (vma_iterate_callback_fn callback, void *data) { /* Documentation: https://man.openbsd.org/sysctl.3 */ int info_path[] = { CTL_KERN, KERN_PROC_VMMAP, getpid () }; size_t len; size_t pagesize; size_t memneed; void *auxmap; unsigned long auxmap_start; unsigned long auxmap_end; char *mem; char *p; char *p_end; len = 0; if (sysctl (info_path, 3, NULL, &len, NULL, 0) < 0) return -1; /* Allow for small variations over time. In a multithreaded program new VMAs can be allocated at any moment. */ len = 2 * len + 10 * sizeof (struct kinfo_vmentry); /* But the system call rejects lengths > 64 KB. */ if (len > 0x10000) len = 0x10000; /* And the system call rejects lengths that are not a multiple of sizeof (struct kinfo_vmentry). */ len = (len / sizeof (struct kinfo_vmentry)) * sizeof (struct kinfo_vmentry); /* Allocate memneed bytes of memory. We cannot use alloca here, because not much stack space is guaranteed. We also cannot use malloc here, because a malloc() call may call mmap() and thus pre-allocate available memory. So use mmap(), and ignore the resulting VMA. */ pagesize = getpagesize (); memneed = len; memneed = ((memneed - 1) / pagesize + 1) * pagesize; auxmap = (void *) mmap ((void *) 0, memneed, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0); if (auxmap == (void *) -1) return -1; auxmap_start = (unsigned long) auxmap; auxmap_end = auxmap_start + memneed; mem = (char *) auxmap; if (sysctl (info_path, 3, mem, &len, NULL, 0) < 0 || len > 0x10000 - sizeof (struct kinfo_vmentry)) { /* sysctl failed, or the list of VMAs is possibly truncated. */ munmap (auxmap, memneed); return -1; } p = mem; p_end = mem + len; while (p < p_end) { struct kinfo_vmentry *kve = (struct kinfo_vmentry *) p; unsigned long start = kve->kve_start; unsigned long end = kve->kve_end; unsigned int flags = 0; if (kve->kve_protection & KVE_PROT_READ) flags |= VMA_PROT_READ; if (kve->kve_protection & KVE_PROT_WRITE) flags |= VMA_PROT_WRITE; if (kve->kve_protection & KVE_PROT_EXEC) flags |= VMA_PROT_EXECUTE; if (start <= auxmap_start && auxmap_end - 1 <= end - 1) { /* Consider [start,end-1] \ [auxmap_start,auxmap_end-1] = [start,auxmap_start-1] u [auxmap_end,end-1]. */ if (start < auxmap_start) if (callback (data, start, auxmap_start, flags)) break; if (auxmap_end - 1 < end - 1) if (callback (data, auxmap_end, end, flags)) break; } else { if (start != end) if (callback (data, start, end, flags)) break; } p += sizeof (struct kinfo_vmentry); } munmap (auxmap, memneed); return 0; }
int __xuname(int namesize, void *namebuf) { int mib[2], rval; size_t len; char *p, *q; int oerrno; rval = 0; q = (char *)namebuf; mib[0] = CTL_KERN; if ((p = getenv("UNAME_s"))) strlcpy(q, p, namesize); else { mib[1] = KERN_OSTYPE; len = namesize; oerrno = errno; if (sysctl(mib, 2, q, &len, NULL, 0) == -1) { if (errno == ENOMEM) errno = oerrno; else rval = -1; } q[namesize - 1] = '\0'; } q += namesize; mib[1] = KERN_HOSTNAME; len = namesize; oerrno = errno; if (sysctl(mib, 2, q, &len, NULL, 0) == -1) { if (errno == ENOMEM) errno = oerrno; else rval = -1; } q[namesize - 1] = '\0'; q += namesize; if ((p = getenv("UNAME_r"))) strlcpy(q, p, namesize); else { mib[1] = KERN_OSRELEASE; len = namesize; oerrno = errno; if (sysctl(mib, 2, q, &len, NULL, 0) == -1) { if (errno == ENOMEM) errno = oerrno; else rval = -1; } q[namesize - 1] = '\0'; } q += namesize; if ((p = getenv("UNAME_v"))) strlcpy(q, p, namesize); else { /* * The version may have newlines in it, turn them into * spaces. */ mib[1] = KERN_VERSION; len = namesize; oerrno = errno; if (sysctl(mib, 2, q, &len, NULL, 0) == -1) { if (errno == ENOMEM) errno = oerrno; else rval = -1; } q[namesize - 1] = '\0'; for (p = q; len--; ++p) { if (*p == '\n' || *p == '\t') { if (len > 1) *p = ' '; else *p = '\0'; } } } q += namesize; if ((p = getenv("UNAME_m"))) strlcpy(q, p, namesize); else { mib[0] = CTL_HW; mib[1] = HW_MACHINE; len = namesize; oerrno = errno; if (sysctl(mib, 2, q, &len, NULL, 0) == -1) { if (errno == ENOMEM) errno = oerrno; else rval = -1; } q[namesize - 1] = '\0'; } return (rval); }
bool w_start_listener(const char *path) { pthread_mutexattr_t mattr; #ifndef _WIN32 struct sigaction sa; sigset_t sigset; #endif void *ignored; #ifdef HAVE_LIBGIMLI_H volatile struct gimli_heartbeat *hb = NULL; #endif struct timeval tv; int n_clients = 0; listener_thread = pthread_self(); pthread_mutexattr_init(&mattr); pthread_mutexattr_settype(&mattr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&w_client_lock, &mattr); pthread_mutexattr_destroy(&mattr); #ifdef HAVE_LIBGIMLI_H hb = gimli_heartbeat_attach(); #endif #if defined(HAVE_KQUEUE) || defined(HAVE_FSEVENTS) { struct rlimit limit; # ifndef __OpenBSD__ int mib[2] = { CTL_KERN, # ifdef KERN_MAXFILESPERPROC KERN_MAXFILESPERPROC # else KERN_MAXFILES # endif }; # endif int maxperproc; getrlimit(RLIMIT_NOFILE, &limit); # ifndef __OpenBSD__ size_t len; len = sizeof(maxperproc); sysctl(mib, 2, &maxperproc, &len, NULL, 0); w_log(W_LOG_ERR, "file limit is %" PRIu64 " kern.maxfilesperproc=%i\n", limit.rlim_cur, maxperproc); # else maxperproc = limit.rlim_max; w_log(W_LOG_ERR, "openfiles-cur is %" PRIu64 " openfiles-max=%i\n", limit.rlim_cur, maxperproc); # endif if (limit.rlim_cur != RLIM_INFINITY && maxperproc > 0 && limit.rlim_cur < (rlim_t)maxperproc) { limit.rlim_cur = maxperproc; if (setrlimit(RLIMIT_NOFILE, &limit)) { w_log(W_LOG_ERR, "failed to raise limit to %" PRIu64 " (%s).\n", limit.rlim_cur, strerror(errno)); } else { w_log(W_LOG_ERR, "raised file limit to %" PRIu64 "\n", limit.rlim_cur); } } getrlimit(RLIMIT_NOFILE, &limit); #ifndef HAVE_FSEVENTS if (limit.rlim_cur < 10240) { w_log(W_LOG_ERR, "Your file descriptor limit is very low (%" PRIu64 "), " "please consult the watchman docs on raising the limits\n", limit.rlim_cur); } #endif } #endif proc_pid = (int)getpid(); if (gettimeofday(&tv, NULL) == -1) { w_log(W_LOG_ERR, "gettimeofday failed: %s\n", strerror(errno)); return false; } proc_start_time = (uint64_t)tv.tv_sec; #ifndef _WIN32 signal(SIGPIPE, SIG_IGN); /* allow SIGUSR1 and SIGCHLD to wake up a blocked thread, without restarting * syscalls */ memset(&sa, 0, sizeof(sa)); sa.sa_handler = wakeme; sa.sa_flags = 0; sigaction(SIGUSR1, &sa, NULL); sigaction(SIGCHLD, &sa, NULL); // Block SIGCHLD everywhere sigemptyset(&sigset); sigaddset(&sigset, SIGCHLD); sigprocmask(SIG_BLOCK, &sigset, NULL); listener_fd = get_listener_socket(path); if (listener_fd == -1) { return false; } w_set_cloexec(listener_fd); #endif if (pthread_create(&reaper_thread, NULL, child_reaper, NULL)) { w_log(W_LOG_FATAL, "pthread_create(reaper): %s\n", strerror(errno)); return false; } if (!clients) { clients = w_ht_new(2, &client_hash_funcs); } w_state_load(); #ifdef HAVE_LIBGIMLI_H if (hb) { gimli_heartbeat_set(hb, GIMLI_HB_RUNNING); } else { w_setup_signal_handlers(); } #else w_setup_signal_handlers(); #endif w_set_nonblock(listener_fd); // Now run the dispatch #ifndef _WIN32 accept_loop(); #else named_pipe_accept_loop(path); #endif #ifndef _WIN32 /* close out some resources to persuade valgrind to run clean */ close(listener_fd); listener_fd = -1; #endif // Wait for clients, waking any sleeping clients up in the process do { w_ht_iter_t iter; pthread_mutex_lock(&w_client_lock); n_clients = w_ht_size(clients); if (w_ht_first(clients, &iter)) do { struct watchman_client *client = w_ht_val_ptr(iter.value); w_event_set(client->ping); } while (w_ht_next(clients, &iter)); pthread_mutex_unlock(&w_client_lock); w_log(W_LOG_ERR, "waiting for %d clients to terminate\n", n_clients); usleep(2000); } while (n_clients > 0); w_root_free_watched_roots(); pthread_join(reaper_thread, &ignored); cfg_shutdown(); return true; }
int ip_rt_dev(u_int32_t addr,u_char *name) { size_t needed; int mib[6], rlen, seqno; char *buf, *next, *lim,i; register struct rt_msghdr *rtm; struct sockaddr *sa ; struct sockaddr_in *sin; u_int32_t devip = 0,dest,mask,gate,local; char *cp; local = htonl(0x7f000001); mib[0] = CTL_NET; mib[1] = PF_ROUTE; mib[2] = 0; mib[3] = 0; mib[4] = NET_RT_DUMP; mib[5] = 0; if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0){ croak("route-sysctl-estimate"); } if ((buf = malloc(needed)) == NULL){ croak("malloc"); } if (sysctl(mib, 6, buf, &needed, NULL, 0) < 0){ croak("route-sysctl-get"); } lim = buf + needed; for (next = buf; next < lim; next += rtm->rtm_msglen) { rtm = (struct rt_msghdr *)next; sa = (struct sockaddr *)(rtm + 1); cp = (char*)sa; if (sa->sa_family != AF_INET) continue; dest = mask = gate = 0; for (i = 1; i; i <<= 1) if (i & rtm->rtm_addrs) { sa = (struct sockaddr *)cp; switch (i) { case RTA_DST: sin = (struct sockaddr_in*)sa; dest = sin->sin_addr.s_addr; break; case RTA_GATEWAY: if(rtm->rtm_flags & RTF_GATEWAY){ sin = (struct sockaddr_in*)sa; gate = sin->sin_addr.s_addr; } break; case RTA_NETMASK: sin = (struct sockaddr_in*)sa; mask = sin->sin_addr.s_addr; break; } ADVANCE(cp, sa); } if(!(rtm->rtm_flags & RTF_LLINFO) && (rtm->rtm_flags & RTF_HOST)) mask = 0xffffffff; if(!mask && dest && (dest != local)) continue; if(!dest) mask = 0; if(dest == local) { dest = htonl(0x7f000000); mask = htonl(0xff000000); } if(!((mask & addr) ^ dest)){ switch (gate) { case 0: devip = addr; break; default: devip = gate; } } } free(buf); return dev_name(devip,name); }