/* * Return number of threads used by process as a Python integer. */ static PyObject* get_process_num_threads(PyObject* self, PyObject* args) { long pid; int err, ret; unsigned int info_count = TASK_BASIC_INFO_COUNT; mach_port_t task; struct task_basic_info tasks_info; thread_act_port_array_t thread_list; mach_msg_type_number_t thread_count; // the argument passed should be a process id if (! PyArg_ParseTuple(args, "l", &pid)) { return NULL; } /* task_for_pid() requires special privileges * "This function can be called only if the process is owned by the * procmod group or if the caller is root." * - http://developer.apple.com/documentation/MacOSX/Conceptual/universal_binary/universal_binary_tips/chapter_5_section_19.html */ err = task_for_pid(mach_task_self(), pid, &task); if ( err == KERN_SUCCESS) { info_count = TASK_BASIC_INFO_COUNT; err = task_info(task, TASK_BASIC_INFO, (task_info_t)&tasks_info, &info_count); if (err != KERN_SUCCESS) { // errcode 4 is "invalid argument" (access denied) if (err == 4) { return AccessDenied(); } // otherwise throw a runtime error with appropriate error code return PyErr_Format(PyExc_RuntimeError, "task_info(TASK_BASIC_INFO) failed"); } err = task_threads(task, &thread_list, &thread_count); if (err == KERN_SUCCESS) { ret = vm_deallocate(task, (vm_address_t)thread_list, thread_count * sizeof(int)); if (ret != KERN_SUCCESS) { printf("vm_deallocate() failed\n"); } return Py_BuildValue("l", (long)thread_count); } else { return PyErr_Format(PyExc_RuntimeError, "task_thread() failed"); } } else { if (! pid_exists(pid) ) { return NoSuchProcess(); } // pid exists, so return AccessDenied error since task_for_pid() failed return AccessDenied(); } return NULL; }
/* * A wrapper around OpenProcess setting NSP exception if process * no longer exists. * "pid" is the process pid, "dwDesiredAccess" is the first argument * exptected by OpenProcess. * Return a process handle or NULL. */ HANDLE psutil_handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess) { HANDLE hProcess; DWORD processExitCode = 0; if (pid == 0) { // otherwise we'd get NoSuchProcess return AccessDenied(); } hProcess = OpenProcess(dwDesiredAccess, FALSE, pid); if (hProcess == NULL) { if (GetLastError() == ERROR_INVALID_PARAMETER) { NoSuchProcess(); } else { PyErr_SetFromWindowsErr(0); } return NULL; } // make sure the process is running GetExitCodeProcess(hProcess, &processExitCode); if (processExitCode == 0) { NoSuchProcess(); CloseHandle(hProcess); return NULL; } return hProcess; }
int psutil_raise_ad_or_nsp(long pid) { // Set exception to AccessDenied if pid exists else NoSuchProcess. if (psutil_pid_exists(pid) == 0) NoSuchProcess(); else AccessDenied(); }
void Win32ThrowLastError(const char* fmt, ...) { DWORD err; char buff[HiME_MAX_MSG]; char* s; wchar_t winmsg[512]; char* ret; va_list lst; err = GetLastError(); if (err == ERROR_SUCCESS) return; s = buff; strcpy(s, "win32 error: "); s += strlen(s); if (fmt) { va_start(lst, fmt); s += _vsnprintf(s, HiME_MAX_MSG - (s - buff) - 2, fmt, lst); va_end(lst); strcat(s, ": "); s += 2; } FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, NULL, err, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), winmsg, sizeof(winmsg) / sizeof(winmsg[0]) - 1, NULL); OutputDebugStringW(winmsg); WideCharToMultiByte(CP_ACP, 0, winmsg, -1, (LPSTR)s, (int)(Exception::MAX_MSG - (s - buff) - 2), NULL, NULL); ret = strstr(buff, "\r\n"); if (ret) *ret = 0; switch (err) { case ERROR_FILE_NOT_FOUND: case ERROR_PATH_NOT_FOUND: throw FileNotFound(buff, err); case ERROR_ACCESS_DENIED: case ERROR_SHARING_VIOLATION: throw AccessDenied(buff, err); break; default: throw Exception(buff, err); break; } }
int psutil_raise_ad_or_nsp(long pid) { // Set exception to AccessDenied if pid exists else NoSuchProcess. int ret; ret = psutil_pid_exists(pid); if (ret == 0) NoSuchProcess(); else if (ret == 1) AccessDenied(); return ret; }
/* * A wrapper around OpenProcess setting NSP exception if process * no longer exists. * "pid" is the process pid, "dwDesiredAccess" is the first argument * exptected by OpenProcess. * Return a process handle or NULL. */ HANDLE psutil_handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess) { HANDLE hProcess; if (pid == 0) { // otherwise we'd get NoSuchProcess return AccessDenied(""); } hProcess = OpenProcess(dwDesiredAccess, FALSE, pid); return psutil_check_phandle(hProcess, pid); }
static void throw_errno(const String& path) { switch (errno) { case EACCES: throw AccessDenied(path.c_str()); case ENOENT: throw FileNotFound(path.c_str()); default: throw IOException(path.c_str()); } }
/* * Return process threads */ static PyObject* get_process_threads(PyObject* self, PyObject* args) { long pid; int err, j, ret; kern_return_t kr; unsigned int info_count = TASK_BASIC_INFO_COUNT; mach_port_t task; struct task_basic_info tasks_info; thread_act_port_array_t thread_list; thread_info_data_t thinfo; thread_basic_info_t basic_info_th; mach_msg_type_number_t thread_count, thread_info_count; PyObject* retList = PyList_New(0); PyObject* pyTuple = NULL; // the argument passed should be a process id if (! PyArg_ParseTuple(args, "l", &pid)) { return NULL; } // task_for_pid() requires special privileges err = task_for_pid(mach_task_self(), pid, &task); if (err != KERN_SUCCESS) { if (! pid_exists(pid) ) { return NoSuchProcess(); } return AccessDenied(); } info_count = TASK_BASIC_INFO_COUNT; err = task_info(task, TASK_BASIC_INFO, (task_info_t)&tasks_info, &info_count); if (err != KERN_SUCCESS) { // errcode 4 is "invalid argument" (access denied) if (err == 4) { return AccessDenied(); } // otherwise throw a runtime error with appropriate error code return PyErr_Format(PyExc_RuntimeError, "task_info(TASK_BASIC_INFO) failed"); } err = task_threads(task, &thread_list, &thread_count); if (err != KERN_SUCCESS) { return PyErr_Format(PyExc_RuntimeError, "task_threads() failed"); } for (j = 0; j < thread_count; j++) { thread_info_count = THREAD_INFO_MAX; kr = thread_info(thread_list[j], THREAD_BASIC_INFO, (thread_info_t)thinfo, &thread_info_count); if (kr != KERN_SUCCESS) { return PyErr_Format(PyExc_RuntimeError, "thread_info() failed"); } basic_info_th = (thread_basic_info_t)thinfo; // XXX - thread_info structure does not provide any process id; // the best we can do is assigning an incremental bogus value pyTuple = Py_BuildValue("Iff", j + 1, (float)basic_info_th->user_time.microseconds / 1000000.0, (float)basic_info_th->system_time.microseconds / 1000000.0 ); PyList_Append(retList, pyTuple); Py_XDECREF(pyTuple); } ret = vm_deallocate(task, (vm_address_t)thread_list, thread_count * sizeof(int)); if (ret != KERN_SUCCESS) { printf("vm_deallocate() failed\n"); } return retList; }
/* * Return a tuple of RSS and VMS memory usage. */ static PyObject* get_memory_info(PyObject* self, PyObject* args) { long pid; int err; unsigned int info_count = TASK_BASIC_INFO_COUNT; mach_port_t task; struct task_basic_info tasks_info; vm_region_basic_info_data_64_t b_info; vm_address_t address = GLOBAL_SHARED_TEXT_SEGMENT; vm_size_t size; mach_port_t object_name; // the argument passed should be a process id if (! PyArg_ParseTuple(args, "l", &pid)) { return NULL; } /* task_for_pid() requires special privileges * "This function can be called only if the process is owned by the * procmod group or if the caller is root." * - http://developer.apple.com/documentation/MacOSX/Conceptual/universal_binary/universal_binary_tips/chapter_5_section_19.html */ err = task_for_pid(mach_task_self(), pid, &task); if ( err == KERN_SUCCESS) { info_count = TASK_BASIC_INFO_COUNT; err = task_info(task, TASK_BASIC_INFO, (task_info_t)&tasks_info, &info_count); if (err != KERN_SUCCESS) { if (err == 4) { // errcode 4 is "invalid argument" (access denied) return AccessDenied(); } // otherwise throw a runtime error with appropriate error code return PyErr_Format(PyExc_RuntimeError, "task_info(TASK_BASIC_INFO) failed"); } /* Issue #73 http://code.google.com/p/psutil/issues/detail?id=73 * adjust the virtual memory size down to account for * shared memory that task_info.virtual_size includes w/every process */ info_count = VM_REGION_BASIC_INFO_COUNT_64; err = vm_region_64(task, &address, &size, VM_REGION_BASIC_INFO, (vm_region_info_t)&b_info, &info_count, &object_name); if (err == KERN_SUCCESS) { if (b_info.reserved && size == (SHARED_TEXT_REGION_SIZE) && tasks_info.virtual_size > (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE)) { tasks_info.virtual_size -= (SHARED_TEXT_REGION_SIZE + SHARED_DATA_REGION_SIZE); } } } else { if (! pid_exists(pid) ) { return NoSuchProcess(); } // pid exists, so return AccessDenied error since task_for_pid() failed return AccessDenied(); } return Py_BuildValue("(ll)", tasks_info.resident_size, tasks_info.virtual_size); }
/* * Return a Python tuple (user_time, kernel_time) */ static PyObject* get_cpu_times(PyObject* self, PyObject* args) { long pid; int err; unsigned int info_count = TASK_BASIC_INFO_COUNT; task_port_t task; // = (task_port_t)NULL; time_value_t user_time, system_time; struct task_basic_info tasks_info; struct task_thread_times_info task_times; if (! PyArg_ParseTuple(args, "l", &pid)) { return NULL; } /* task_for_pid() requires special privileges * "This function can be called only if the process is owned by the * procmod group or if the caller is root." * - http://developer.apple.com/documentation/MacOSX/Conceptual/universal_binary/universal_binary_tips/chapter_5_section_19.html */ err = task_for_pid(mach_task_self(), pid, &task); if ( err == KERN_SUCCESS) { info_count = TASK_BASIC_INFO_COUNT; err = task_info(task, TASK_BASIC_INFO, (task_info_t)&tasks_info, &info_count); if (err != KERN_SUCCESS) { // errcode 4 is "invalid argument" (access denied) if (err == 4) { return AccessDenied(); } // otherwise throw a runtime error with appropriate error code return PyErr_Format(PyExc_RuntimeError, "task_info(TASK_BASIC_INFO) failed"); } info_count = TASK_THREAD_TIMES_INFO_COUNT; err = task_info(task, TASK_THREAD_TIMES_INFO, (task_info_t)&task_times, &info_count); if (err != KERN_SUCCESS) { // errcode 4 is "invalid argument" (access denied) if (err == 4) { return AccessDenied(); } return PyErr_Format(PyExc_RuntimeError, "task_info(TASK_BASIC_INFO) failed"); } } else { // task_for_pid failed if (! pid_exists(pid) ) { return NoSuchProcess(); } // pid exists, so return AccessDenied error since task_for_pid() failed return AccessDenied(); } float user_t = -1.0; float sys_t = -1.0; user_time = tasks_info.user_time; system_time = tasks_info.system_time; time_value_add(&user_time, &task_times.user_time); time_value_add(&system_time, &task_times.system_time); user_t = (float)user_time.seconds + ((float)user_time.microseconds / 1000000.0); sys_t = (float)system_time.seconds + ((float)system_time.microseconds / 1000000.0); return Py_BuildValue("(dd)", user_t, sys_t); }
int main(int argc, char* argv[]) { int iTestCase = 0; bErrorVerbose = true; char pszDecision[20]; for (;;) { // Get the pointers to the functions for disabling and enabling interception... getInterceptionDisablers(); uninterceptedPrint("=== HOLODECK FAULT TESTER 1.0 by TERRY LENTZ ===\n\n"); uninterceptedPrint("*** FILE FAULTS ***\n"); uninterceptedPrint("0 - File Not Found\t\t10 - File Cannot Be Created\n"); uninterceptedPrint("1 - File Cannot Be Accessed\t11 - Filename Too Long\n"); uninterceptedPrint("2 - Access Denied\t\t12 - Directory Read Only\n"); uninterceptedPrint("3 - Write Protected\t\t13 - Path Not Found\n"); uninterceptedPrint("4 - Crc Data Error\t\t14 - Directory Cannot Be Removed\n"); uninterceptedPrint("5 - Drive Cannot Seek Disk\t15 - Directory Not Empty\n"); uninterceptedPrint("6 - File In Use\t\t\t16 - Path Invalid\n"); uninterceptedPrint("7 - File Locked\t\t\t17 - Corrupt Structure\n"); uninterceptedPrint("8 - Disk Full\t\t\n"); uninterceptedPrint("9 - File Already Exists\t\t\n\n"); uninterceptedPrint("*** MEMORY FAULTS ***\n"); uninterceptedPrint("18 - Insufficient Memory\t\t21 - Invalid Address\n"); uninterceptedPrint("19 - Invalid Access To Location\t\t22 - Paging File Too Small\n"); uninterceptedPrint("20 - Segment Locked\t\t\n\n"); uninterceptedPrint("*** NETWORK FAULTS ***\n"); uninterceptedPrint("23 - Disconnected \t\t\t26 - Winsock Task Limit Reached\n"); uninterceptedPrint("24 - Network Not Installed\t\t27 - All Ports Unavailable\n"); uninterceptedPrint("25 - Wrong Winsock Version\t\t28 - Network is Down\n"); uninterceptedPrint("\nPlease enter the test that you would like to run: "); if (disableInterception != NULL) disableInterception(); scanf("%d", &iTestCase); if (enableInterception != NULL) enableInterception(); uninterceptedPrint("\n"); switch (iTestCase) { // FileNotFound case 0: uninterceptedPrint("=== TEST CASE: FileNotFound ===\n"); if (FileNotFound()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // FileCannotBeAccessed case 1: uninterceptedPrint("=== TEST CASE: FileCannotBeAccessed ===\n"); if (FileCannotBeAccessed()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // AccessDenied case 2: uninterceptedPrint("=== TEST CASE: AccessDenied ===\n"); if (AccessDenied()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // WriteProtected case 3: uninterceptedPrint("=== TEST CASE: WriteProtected ===\n"); if (WriteProtected()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // CrcDataError case 4: uninterceptedPrint("=== TEST CASE: CrcDataError ===\n"); if (CrcDataError()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // DriveCannotSeekDisk case 5: uninterceptedPrint("=== TEST CASE: DriveCannotSeekDisk ===\n"); if (DriveCannotSeekDisk()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // FileInUse case 6: uninterceptedPrint("=== TEST CASE: FileInUse ===\n"); if (FileInUse()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // FileLocked case 7: uninterceptedPrint("=== TEST CASE: FileLocked ===\n"); if (FileLocked()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // DiskFull case 8: uninterceptedPrint("=== TEST CASE: DiskFull ===\n"); if (DiskFull()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // FileAlreadyExists case 9: uninterceptedPrint("=== TEST CASE: FileAlreadyExists ===\n"); if (FileAlreadyExists()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // FileCannotBeCreated case 10: uninterceptedPrint("=== TEST CASE: FileCannotBeCreated ===\n"); if (FileCannotBeCreated()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // FileNameTooLong case 11: uninterceptedPrint("=== TEST CASE: FileNameTooLong ===\n"); if (FileNameTooLong()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // DirectoryReadOnly case 12: uninterceptedPrint("=== TEST CASE: DirectoryReadOnly ===\n"); if (DirectoryReadOnly()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // PathNotFound case 13: uninterceptedPrint("=== TEST CASE: PathNotFound ===\n"); if (PathNotFound()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // DirectoryCannotBeRemoved case 14: uninterceptedPrint("=== TEST CASE: DirectoryCannotBeRemoved ===\n"); if (DirectoryCannotBeRemoved()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // DirectoryNotEmpty case 15: uninterceptedPrint("=== TEST CASE: DirectoryNotEmpty ===\n"); if (DirectoryNotEmpty()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // PathInvalid case 16: uninterceptedPrint("=== TEST CASE: PathInvalid ===\n"); if (PathInvalid()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // CorruptStructure case 17: uninterceptedPrint("=== TEST CASE: CorruptStructure ===\n"); if (CorruptStructure()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // InsufficientMemory case 18: uninterceptedPrint("=== TEST CASE: InsufficientMemory ===\n"); if (InsufficientMemory()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // InvalidAccessToLocation case 19: uninterceptedPrint("=== TEST CASE: InvalidAccessToLocation ===\n"); if (InvalidAccessToLocation()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // SegmentLocked case 20: uninterceptedPrint("=== TEST CASE: SegmentLocked ===\n"); if (SegmentLocked()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // InvalidAddress case 21: uninterceptedPrint("=== TEST CASE: InvalidAddress ===\n"); if (InvalidAddress()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // PagingFileTooSmall case 22: uninterceptedPrint("=== TEST CASE: PagingFileTooSmall ===\n"); if (PagingFileTooSmall()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // Disconnected case 23: uninterceptedPrint("=== TEST CASE: Disconnected ===\n"); if (Disconnected()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // NetworkNotInstalled case 24: uninterceptedPrint("=== TEST CASE: NetworkNotInstalled ===\n"); if (NetworkNotInstalled()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // WrongWinsockVersion case 25: uninterceptedPrint("=== TEST CASE: WrongWinsockVersion ===\n"); if (WrongWinsockVersion()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // WinsockTaskLimitReached case 26: uninterceptedPrint("=== TEST CASE: WinsockTaskLimitReached ===\n"); if (WinsockTaskLimitReached()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // AllPortsUnavailable case 27: uninterceptedPrint("=== TEST CASE: AllPortsUnavailable ===\n"); if (AllPortsUnavailable()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; // NetworkIsDown case 28: uninterceptedPrint("=== TEST CASE: NetworkIsDown ===\n"); if (NetworkIsDown()) uninterceptedPrint("\nTEST Passed!\n"); else uninterceptedPrint("\nTEST Failed!\n"); break; } uninterceptedPrint("\nWould You Like to Run Another Test (Y/N) ? "); if (disableInterception != NULL) disableInterception(); scanf("%s", pszDecision); if (enableInterception != NULL) enableInterception(); if ((_stricmp(pszDecision, "y"))) break; } return 0; }
/* * Return process environ block. */ static PyObject * psutil_proc_environ(PyObject *self, PyObject *args) { int pid; char path[1000]; psinfo_t info; const char *procfs_path; char **env = NULL; ssize_t env_count = -1; char *dm; int i = 0; PyObject *py_envname = NULL; PyObject *py_envval = NULL; PyObject *py_retdict = PyDict_New(); if (! py_retdict) return PyErr_NoMemory(); if (! PyArg_ParseTuple(args, "is", &pid, &procfs_path)) return NULL; sprintf(path, "%s/%i/psinfo", procfs_path, pid); if (! psutil_file_to_struct(path, (void *)&info, sizeof(info))) goto error; if (! info.pr_envp) { AccessDenied(""); goto error; } env = psutil_read_raw_env(info, procfs_path, &env_count); if (! env && env_count != 0) goto error; for (i=0; i<env_count; i++) { if (! env[i]) break; dm = strchr(env[i], '='); if (! dm) continue; *dm = '\0'; py_envname = PyUnicode_DecodeFSDefault(env[i]); if (! py_envname) goto error; py_envval = PyUnicode_DecodeFSDefault(dm+1); if (! py_envname) goto error; if (PyDict_SetItem(py_retdict, py_envname, py_envval) < 0) goto error; Py_DECREF(py_envname); Py_DECREF(py_envval); } psutil_free_cstrings_array(env, env_count); return py_retdict; error: if (env && env_count >= 0) psutil_free_cstrings_array(env, env_count); Py_XDECREF(py_envname); Py_XDECREF(py_envval); Py_XDECREF(py_retdict); return NULL; }
PyObject * psutil_proc_threads(PyObject *self, PyObject *args) { // OpenBSD reference: // https://github.com/janmojzis/pstree/blob/master/proc_kvm.c // Note: this requires root access, else it will fail trying // to access /dev/kmem. long pid; kvm_t *kd = NULL; int nentries, i; char errbuf[4096]; struct kinfo_proc *kp; PyObject *py_retlist = PyList_New(0); PyObject *py_tuple = NULL; if (py_retlist == NULL) return NULL; if (! PyArg_ParseTuple(args, "l", &pid)) goto error; kd = kvm_openfiles(0, 0, 0, O_RDONLY, errbuf); if (! kd) { if (strstr(errbuf, "Permission denied") != NULL) AccessDenied(); else PyErr_Format(PyExc_RuntimeError, "kvm_openfiles() failed"); goto error; } kp = kvm_getprocs( kd, KERN_PROC_PID | KERN_PROC_SHOW_THREADS | KERN_PROC_KTHREAD, pid, sizeof(*kp), &nentries); if (! kp) { if (strstr(errbuf, "Permission denied") != NULL) AccessDenied(); else PyErr_Format(PyExc_RuntimeError, "kvm_getprocs() failed"); goto error; } for (i = 0; i < nentries; i++) { if (kp[i].p_tid < 0) continue; if (kp[i].p_pid == pid) { py_tuple = Py_BuildValue( "Idd", kp[i].p_tid, PSUTIL_KPT2DOUBLE(kp[i].p_uutime), PSUTIL_KPT2DOUBLE(kp[i].p_ustime)); if (py_tuple == NULL) goto error; if (PyList_Append(py_retlist, py_tuple)) goto error; Py_DECREF(py_tuple); } } kvm_close(kd); return py_retlist; error: Py_XDECREF(py_tuple); Py_DECREF(py_retlist); if (kd != NULL) kvm_close(kd); return NULL; }