Example #1
0
static PyObject*
pymonotonic(_Py_clock_info_t *info)
{
#if defined(MS_WINDOWS)
    static ULONGLONG (*GetTickCount64) (void) = NULL;
    static ULONGLONG (CALLBACK *Py_GetTickCount64)(void);
    static int has_getickcount64 = -1;
    double result;

    if (has_getickcount64 == -1) {
        /* GetTickCount64() was added to Windows Vista */
        if (winver.dwMajorVersion >= 6) {
            HINSTANCE hKernel32;
            hKernel32 = GetModuleHandleW(L"KERNEL32");
            *(FARPROC*)&Py_GetTickCount64 = GetProcAddress(hKernel32,
                                                           "GetTickCount64");
            has_getickcount64 = (Py_GetTickCount64 != NULL);
        }
        else
            has_getickcount64 = 0;
    }

    if (has_getickcount64) {
        ULONGLONG ticks;
        ticks = Py_GetTickCount64();
        result = (double)ticks * 1e-3;
    }
    else {
        static DWORD last_ticks = 0;
        static DWORD n_overflow = 0;
        DWORD ticks;

        ticks = GetTickCount();
        if (ticks < last_ticks)
            n_overflow++;
        last_ticks = ticks;

        result = ldexp(n_overflow, 32);
        result += ticks;
        result *= 1e-3;
    }

    if (info) {
        DWORD timeAdjustment, timeIncrement;
        BOOL isTimeAdjustmentDisabled, ok;
        if (has_getickcount64)
            info->implementation = "GetTickCount64()";
        else
            info->implementation = "GetTickCount()";
        info->monotonic = 1;
        ok = GetSystemTimeAdjustment(&timeAdjustment, &timeIncrement,
                                     &isTimeAdjustmentDisabled);
        if (!ok) {
            PyErr_SetFromWindowsErr(0);
            return NULL;
        }
        info->resolution = timeIncrement * 1e-7;
        info->adjustable = 0;
    }
    return PyFloat_FromDouble(result);

#elif defined(__APPLE__)
    static mach_timebase_info_data_t timebase;
    uint64_t time;
    double secs;

    if (timebase.denom == 0) {
        /* According to the Technical Q&A QA1398, mach_timebase_info() cannot
           fail: https://developer.apple.com/library/mac/#qa/qa1398/ */
        (void)mach_timebase_info(&timebase);
    }

    time = mach_absolute_time();
    secs = (double)time * timebase.numer / timebase.denom * 1e-9;
    if (info) {
        info->implementation = "mach_absolute_time()";
        info->resolution = (double)timebase.numer / timebase.denom * 1e-9;
        info->monotonic = 1;
        info->adjustable = 0;
    }
    return PyFloat_FromDouble(secs);

#elif defined(HAVE_CLOCK_GETTIME) && (defined(CLOCK_HIGHRES) || defined(CLOCK_MONOTONIC))
    struct timespec tp;
#ifdef CLOCK_HIGHRES
    const clockid_t clk_id = CLOCK_HIGHRES;
    const char *function = "clock_gettime(CLOCK_HIGHRES)";
#else
    const clockid_t clk_id = CLOCK_MONOTONIC;
    const char *function = "clock_gettime(CLOCK_MONOTONIC)";
#endif

    if (clock_gettime(clk_id, &tp) != 0) {
        PyErr_SetFromErrno(PyExc_OSError);
        return NULL;
    }

    if (info) {
        struct timespec res;
        info->monotonic = 1;
        info->implementation = function;
        info->adjustable = 0;
        if (clock_getres(clk_id, &res) == 0)
            info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
        else
            info->resolution = 1e-9;
    }
    return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
#endif
}
Example #2
0
static PyObject *
mmap_resize_method(mmap_object *self,
                   PyObject *args)
{
    Py_ssize_t new_size;
    CHECK_VALID(NULL);
    if (!PyArg_ParseTuple(args, "n:resize", &new_size) ||
            !is_resizeable(self)) {
        return NULL;
#ifdef MS_WINDOWS
    } else {
        DWORD dwErrCode = 0;
        DWORD newSizeLow, newSizeHigh;
        /* First, unmap the file view */
        UnmapViewOfFile(self->data);
        /* Close the mapping object */
        CloseHandle(self->map_handle);
        /* Move to the desired EOF position */
#if SIZEOF_SIZE_T > 4
        newSizeHigh = (DWORD)(new_size >> 32);
        newSizeLow = (DWORD)(new_size & 0xFFFFFFFF);
#else
        newSizeHigh = 0;
        newSizeLow = (DWORD)new_size;
#endif
        SetFilePointer(self->file_handle,
                       newSizeLow, &newSizeHigh, FILE_BEGIN);
        /* Change the size of the file */
        SetEndOfFile(self->file_handle);
        /* Create another mapping object and remap the file view */
        self->map_handle = CreateFileMapping(
                               self->file_handle,
                               NULL,
                               PAGE_READWRITE,
                               newSizeHigh,
                               newSizeLow,
                               self->tagname);
        if (self->map_handle != NULL) {
            self->data = (char *) MapViewOfFile(self->map_handle,
                                                FILE_MAP_WRITE,
                                                0,
                                                0,
                                                0);
            if (self->data != NULL) {
                self->size = new_size;
                Py_INCREF(Py_None);
                return Py_None;
            } else {
                dwErrCode = GetLastError();
            }
        } else {
            dwErrCode = GetLastError();
        }
        PyErr_SetFromWindowsErr(dwErrCode);
        return NULL;
#endif /* MS_WINDOWS */

#ifdef UNIX
#ifndef HAVE_MREMAP
    }
    else {
Example #3
0
static PyObject*
py_process_time(_Py_clock_info_t *info)
{
#if defined(MS_WINDOWS)
    HANDLE process;
    FILETIME creation_time, exit_time, kernel_time, user_time;
    ULARGE_INTEGER large;
    double total;
    BOOL ok;

    process = GetCurrentProcess();
    ok = GetProcessTimes(process, &creation_time, &exit_time, &kernel_time, &user_time);
    if (!ok)
        return PyErr_SetFromWindowsErr(0);

    large.u.LowPart = kernel_time.dwLowDateTime;
    large.u.HighPart = kernel_time.dwHighDateTime;
    total = (double)large.QuadPart;
    large.u.LowPart = user_time.dwLowDateTime;
    large.u.HighPart = user_time.dwHighDateTime;
    total += (double)large.QuadPart;
    if (info) {
        info->implementation = "GetProcessTimes()";
        info->resolution = 1e-7;
        info->monotonic = 1;
        info->adjustable = 0;
    }
    return PyFloat_FromDouble(total * 1e-7);
#else

#if defined(HAVE_SYS_RESOURCE_H)
    struct rusage ru;
#endif
#ifdef HAVE_TIMES
    struct tms t;
    static long ticks_per_second = -1;
#endif

#if defined(HAVE_CLOCK_GETTIME) \
    && (defined(CLOCK_PROCESS_CPUTIME_ID) || defined(CLOCK_PROF))
    struct timespec tp;
#ifdef CLOCK_PROF
    const clockid_t clk_id = CLOCK_PROF;
    const char *function = "clock_gettime(CLOCK_PROF)";
#else
    const clockid_t clk_id = CLOCK_PROCESS_CPUTIME_ID;
    const char *function = "clock_gettime(CLOCK_PROCESS_CPUTIME_ID)";
#endif

    if (clock_gettime(clk_id, &tp) == 0) {
        if (info) {
            struct timespec res;
            info->implementation = function;
            info->monotonic = 1;
            info->adjustable = 0;
            if (clock_getres(clk_id, &res) == 0)
                info->resolution = res.tv_sec + res.tv_nsec * 1e-9;
            else
                info->resolution = 1e-9;
        }
        return PyFloat_FromDouble(tp.tv_sec + tp.tv_nsec * 1e-9);
    }
#endif

#if defined(HAVE_SYS_RESOURCE_H)
    if (getrusage(RUSAGE_SELF, &ru) == 0) {
        double total;
        total = ru.ru_utime.tv_sec + ru.ru_utime.tv_usec * 1e-6;
        total += ru.ru_stime.tv_sec + ru.ru_stime.tv_usec * 1e-6;
        if (info) {
            info->implementation = "getrusage(RUSAGE_SELF)";
            info->monotonic = 1;
            info->adjustable = 0;
            info->resolution = 1e-6;
        }
        return PyFloat_FromDouble(total);
    }
#endif

#ifdef HAVE_TIMES
    if (times(&t) != (clock_t)-1) {
        double total;

        if (ticks_per_second == -1) {
#if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
            ticks_per_second = sysconf(_SC_CLK_TCK);
            if (ticks_per_second < 1)
                ticks_per_second = -1;
#elif defined(HZ)
            ticks_per_second = HZ;
#else
            ticks_per_second = 60; /* magic fallback value; may be bogus */
#endif
        }

        if (ticks_per_second != -1) {
            total = (double)t.tms_utime / ticks_per_second;
            total += (double)t.tms_stime / ticks_per_second;
            if (info) {
                info->implementation = "times()";
                info->monotonic = 1;
                info->adjustable = 0;
                info->resolution = 1.0 / ticks_per_second;
            }
            return PyFloat_FromDouble(total);
        }
    }
#endif

    return floatclock(info);
#endif
}
Example #4
0
PyMODINIT_FUNC
init_multiprocessing(void)
{
    PyObject *module, *temp, *value;

    /* Initialize module */
    module = Py_InitModule("_multiprocessing", module_methods);
    if (!module)
        return;

    /* Get copy of objects from pickle */
    temp = PyImport_ImportModule(PICKLE_MODULE);
    if (!temp)
        return;
    pickle_dumps = PyObject_GetAttrString(temp, "dumps");
    pickle_loads = PyObject_GetAttrString(temp, "loads");
    pickle_protocol = PyObject_GetAttrString(temp, "HIGHEST_PROTOCOL");
    Py_XDECREF(temp);

    /* Get copy of BufferTooShort */
    temp = PyImport_ImportModule("multiprocessing");
    if (!temp)
        return;
    BufferTooShort = PyObject_GetAttrString(temp, "BufferTooShort");
    Py_XDECREF(temp);

    /* Add connection type to module */
    if (PyType_Ready(&ConnectionType) < 0)
        return;
    Py_INCREF(&ConnectionType);
    PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType);

#if defined(MS_WINDOWS) ||                                              \
  (defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED))
    /* Add SemLock type to module */
    if (PyType_Ready(&SemLockType) < 0)
        return;
    Py_INCREF(&SemLockType);
    {
        PyObject *py_sem_value_max;
        /* Some systems define SEM_VALUE_MAX as an unsigned value that
         * causes it to be negative when used as an int (NetBSD). */
        if ((int)(SEM_VALUE_MAX) < 0)
            py_sem_value_max = PyLong_FromLong(INT_MAX);
        else
            py_sem_value_max = PyLong_FromLong(SEM_VALUE_MAX);
        if (py_sem_value_max == NULL)
            return;
        PyDict_SetItemString(SemLockType.tp_dict, "SEM_VALUE_MAX",
                             py_sem_value_max);
    }
    PyModule_AddObject(module, "SemLock", (PyObject*)&SemLockType);
#endif

#ifdef MS_WINDOWS
    /* Add PipeConnection to module */
    if (PyType_Ready(&PipeConnectionType) < 0)
        return;
    Py_INCREF(&PipeConnectionType);
    PyModule_AddObject(module, "PipeConnection",
                       (PyObject*)&PipeConnectionType);

    /* Initialize win32 class and add to multiprocessing */
    temp = create_win32_namespace();
    if (!temp)
        return;
    PyModule_AddObject(module, "win32", temp);

    /* Initialize the event handle used to signal Ctrl-C */
    sigint_event = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!sigint_event) {
        PyErr_SetFromWindowsErr(0);
        return;
    }
    if (!SetConsoleCtrlHandler(ProcessingCtrlHandler, TRUE)) {
        PyErr_SetFromWindowsErr(0);
        return;
    }
#endif

    /* Add configuration macros */
    temp = PyDict_New();
    if (!temp)
        return;
#define ADD_FLAG(name)                                            \
    value = Py_BuildValue("i", name);                             \
    if (value == NULL) { Py_DECREF(temp); return; }               \
    if (PyDict_SetItemString(temp, #name, value) < 0) {           \
        Py_DECREF(temp); Py_DECREF(value); return; }              \
    Py_DECREF(value)

#if defined(HAVE_SEM_OPEN) && !defined(POSIX_SEMAPHORES_NOT_ENABLED)
    ADD_FLAG(HAVE_SEM_OPEN);
#endif
#ifdef HAVE_SEM_TIMEDWAIT
    ADD_FLAG(HAVE_SEM_TIMEDWAIT);
#endif
#ifdef HAVE_FD_TRANSFER
    ADD_FLAG(HAVE_FD_TRANSFER);
#endif
#ifdef HAVE_BROKEN_SEM_GETVALUE
    ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE);
#endif
#ifdef HAVE_BROKEN_SEM_UNLINK
    ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
#endif
    if (PyModule_AddObject(module, "flags", temp) < 0)
        return;
}
Example #5
0
/*
 * returns a Python list representing the arguments for the process
 * with given pid or NULL on error.
 */
PyObject *
psutil_get_arg_list(long pid)
{
    int nArgs, i;
    LPWSTR *szArglist = NULL;
    HANDLE hProcess = NULL;
    PVOID pebAddress;
    PVOID rtlUserProcParamsAddress;
    UNICODE_STRING commandLine;
    WCHAR *commandLineContents = NULL;
    PyObject *arg = NULL;
    PyObject *arg_from_wchar = NULL;
    PyObject *argList = NULL;

    hProcess = psutil_handle_from_pid(pid);
    if (hProcess == NULL) {
        return NULL;
    }

    pebAddress = psutil_get_peb_address(hProcess);

    // get the address of ProcessParameters
#ifdef _WIN64
    if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 32,
                           &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
#else
    if (!ReadProcessMemory(hProcess, (PCHAR)pebAddress + 0x10,
                           &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
#endif
    {
        ////printf("Could not read the address of ProcessParameters!\n");
        PyErr_SetFromWindowsErr(0);
        goto error;
    }

    // read the CommandLine UNICODE_STRING structure
#ifdef _WIN64
    if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 112,
                           &commandLine, sizeof(commandLine), NULL))
#else
    if (!ReadProcessMemory(hProcess, (PCHAR)rtlUserProcParamsAddress + 0x40,
                           &commandLine, sizeof(commandLine), NULL))
#endif
    {
        PyErr_SetFromWindowsErr(0);
        goto error;
    }


    // allocate memory to hold the command line
    commandLineContents = (WCHAR *)malloc(commandLine.Length + 1);
    if (commandLineContents == NULL) {
        PyErr_NoMemory();
        goto error;
    }

    // read the command line
    if (!ReadProcessMemory(hProcess, commandLine.Buffer,
                           commandLineContents, commandLine.Length, NULL))
    {
        PyErr_SetFromWindowsErr(0);
        goto error;
    }

    // Null-terminate the string to prevent wcslen from returning
    // incorrect length the length specifier is in characters, but
    // commandLine.Length is in bytes.
    commandLineContents[(commandLine.Length / sizeof(WCHAR))] = '\0';

    // attempt tp parse the command line using Win32 API, fall back
    // on string cmdline version otherwise
    szArglist = CommandLineToArgvW(commandLineContents, &nArgs);
    if (NULL == szArglist) {
        // failed to parse arglist
        // encode as a UTF8 Python string object from WCHAR string
        arg_from_wchar = PyUnicode_FromWideChar(commandLineContents,
                                                commandLine.Length / 2);
        if (arg_from_wchar == NULL)
            goto error;
#if PY_MAJOR_VERSION >= 3
        argList = Py_BuildValue("N", PyUnicode_AsUTF8String(arg_from_wchar));
#else
        argList = Py_BuildValue("N", PyUnicode_FromObject(arg_from_wchar));
#endif
        if (!argList)
            goto error;
    }
    else {
        // arglist parsed as array of UNICODE_STRING, so convert each to
        // Python string object and add to arg list
        argList = Py_BuildValue("[]");
        if (argList == NULL)
            goto error;
        for (i = 0; i < nArgs; i++) {
            arg_from_wchar = NULL;
            arg = NULL;
            arg_from_wchar = PyUnicode_FromWideChar(szArglist[i],
                                                    wcslen(szArglist[i]));
            if (arg_from_wchar == NULL)
                goto error;
#if PY_MAJOR_VERSION >= 3
            arg = PyUnicode_FromObject(arg_from_wchar);
#else
            arg = PyUnicode_AsUTF8String(arg_from_wchar);
#endif
            if (arg == NULL)
                goto error;
            Py_XDECREF(arg_from_wchar);
            if (PyList_Append(argList, arg))
                goto error;
            Py_XDECREF(arg);
        }
    }

    if (szArglist != NULL)
        LocalFree(szArglist);
    free(commandLineContents);
    CloseHandle(hProcess);
    return argList;

error:
    Py_XDECREF(arg);
    Py_XDECREF(arg_from_wchar);
    Py_XDECREF(argList);
    if (hProcess != NULL)
        CloseHandle(hProcess);
    if (commandLineContents != NULL)
        free(commandLineContents);
    if (szArglist != NULL)
        LocalFree(szArglist);
    return NULL;
}
Example #6
0
static void SetException(DWORD code, EXCEPTION_RECORD *pr)
{
	/* The 'code' is a normal win32 error code so it could be handled by
	PyErr_SetFromWindowsErr(). However, for some errors, we have additional
	information not included in the error code. We handle those here and
	delegate all others to the generic function. */
	switch (code) {
	case EXCEPTION_ACCESS_VIOLATION:
		/* The thread attempted to read from or write
		   to a virtual address for which it does not
		   have the appropriate access. */
		if (pr->ExceptionInformation[0] == 0)
			PyErr_Format(PyExc_WindowsError,
				     "exception: access violation reading %p",
				     pr->ExceptionInformation[1]);
		else
			PyErr_Format(PyExc_WindowsError,
				     "exception: access violation writing %p",
				     pr->ExceptionInformation[1]);
		break;

	case EXCEPTION_BREAKPOINT:
		/* A breakpoint was encountered. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: breakpoint encountered");
		break;

	case EXCEPTION_DATATYPE_MISALIGNMENT:
		/* The thread attempted to read or write data that is
		   misaligned on hardware that does not provide
		   alignment. For example, 16-bit values must be
		   aligned on 2-byte boundaries, 32-bit values on
		   4-byte boundaries, and so on. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: datatype misalignment");
		break;

	case EXCEPTION_SINGLE_STEP:
		/* A trace trap or other single-instruction mechanism
		   signaled that one instruction has been executed. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: single step");
		break;

	case EXCEPTION_ARRAY_BOUNDS_EXCEEDED: 
		/* The thread attempted to access an array element
		   that is out of bounds, and the underlying hardware
		   supports bounds checking. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: array bounds exceeded");
		break;

	case EXCEPTION_FLT_DENORMAL_OPERAND:
		/* One of the operands in a floating-point operation
		   is denormal. A denormal value is one that is too
		   small to represent as a standard floating-point
		   value. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: floating-point operand denormal");
		break;

	case EXCEPTION_FLT_DIVIDE_BY_ZERO:
		/* The thread attempted to divide a floating-point
		   value by a floating-point divisor of zero. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: float divide by zero");
		break;

	case EXCEPTION_FLT_INEXACT_RESULT:
		/* The result of a floating-point operation cannot be
		   represented exactly as a decimal fraction. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: float inexact");
		break;

	case EXCEPTION_FLT_INVALID_OPERATION:
		/* This exception represents any floating-point
		   exception not included in this list. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: float invalid operation");
		break;

	case EXCEPTION_FLT_OVERFLOW:
		/* The exponent of a floating-point operation is
		   greater than the magnitude allowed by the
		   corresponding type. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: float overflow");
		break;

	case EXCEPTION_FLT_STACK_CHECK:
		/* The stack overflowed or underflowed as the result
		   of a floating-point operation. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: stack over/underflow");
		break;

	case EXCEPTION_STACK_OVERFLOW:
		/* The stack overflowed or underflowed as the result
		   of a floating-point operation. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: stack overflow");
		break;

	case EXCEPTION_FLT_UNDERFLOW:
		/* The exponent of a floating-point operation is less
		   than the magnitude allowed by the corresponding
		   type. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: float underflow");
		break;

	case EXCEPTION_INT_DIVIDE_BY_ZERO:
		/* The thread attempted to divide an integer value by
		   an integer divisor of zero. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: integer divide by zero");
		break;

	case EXCEPTION_INT_OVERFLOW:
		/* The result of an integer operation caused a carry
		   out of the most significant bit of the result. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: integer overflow");
		break;

	case EXCEPTION_PRIV_INSTRUCTION:
		/* The thread attempted to execute an instruction
		   whose operation is not allowed in the current
		   machine mode. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: priviledged instruction");
		break;

	case EXCEPTION_NONCONTINUABLE_EXCEPTION:
		/* The thread attempted to continue execution after a
		   noncontinuable exception occurred. */
		PyErr_SetString(PyExc_WindowsError,
				"exception: nocontinuable");
		break;

	default:
		PyErr_SetFromWindowsErr(code);
		break;
	}
}
Example #7
0
static PyObject *
mmap_resize_method(mmap_object *self,
                   PyObject *args)
{
    Py_ssize_t new_size;
    CHECK_VALID(NULL);
    if (!PyArg_ParseTuple(args, "n:resize", &new_size) ||
        !is_resizeable(self)) {
        return NULL;
    }
    if (new_size < 0 || PY_SSIZE_T_MAX - new_size < self->offset) {
        PyErr_SetString(PyExc_ValueError, "new size out of range");
        return NULL;
    }

    {
#ifdef MS_WINDOWS
        DWORD dwErrCode = 0;
        DWORD off_hi, off_lo, newSizeLow, newSizeHigh;
        /* First, unmap the file view */
        UnmapViewOfFile(self->data);
        self->data = NULL;
        /* Close the mapping object */
        CloseHandle(self->map_handle);
        self->map_handle = NULL;
        /* Move to the desired EOF position */
        newSizeHigh = (DWORD)((self->offset + new_size) >> 32);
        newSizeLow = (DWORD)((self->offset + new_size) & 0xFFFFFFFF);
        off_hi = (DWORD)(self->offset >> 32);
        off_lo = (DWORD)(self->offset & 0xFFFFFFFF);
        SetFilePointer(self->file_handle,
                       newSizeLow, &newSizeHigh, FILE_BEGIN);
        /* Change the size of the file */
        SetEndOfFile(self->file_handle);
        /* Create another mapping object and remap the file view */
        self->map_handle = CreateFileMapping(
            self->file_handle,
            NULL,
            PAGE_READWRITE,
            0,
            0,
            self->tagname);
        if (self->map_handle != NULL) {
            self->data = (char *) MapViewOfFile(self->map_handle,
                                                FILE_MAP_WRITE,
                                                off_hi,
                                                off_lo,
                                                new_size);
            if (self->data != NULL) {
                self->size = new_size;
                Py_INCREF(Py_None);
                return Py_None;
            } else {
                dwErrCode = GetLastError();
                CloseHandle(self->map_handle);
                self->map_handle = NULL;
            }
        } else {
            dwErrCode = GetLastError();
        }
        PyErr_SetFromWindowsErr(dwErrCode);
        return NULL;
#endif /* MS_WINDOWS */

#ifdef UNIX
#ifndef HAVE_MREMAP
        PyErr_SetString(PyExc_SystemError,
                        "mmap: resizing not available--no mremap()");
        return NULL;
#else
        void *newmap;

        if (self->fd != -1 && ftruncate(self->fd, self->offset + new_size) == -1) {
            PyErr_SetFromErrno(PyExc_OSError);
            return NULL;
        }

#ifdef MREMAP_MAYMOVE
        newmap = mremap(self->data, self->size, new_size, MREMAP_MAYMOVE);
#else
#if defined(__NetBSD__)
        newmap = mremap(self->data, self->size, self->data, new_size, 0);
#else
        newmap = mremap(self->data, self->size, new_size, 0);
#endif /* __NetBSD__ */
#endif
        if (newmap == (void *)-1)
        {
            PyErr_SetFromErrno(PyExc_OSError);
            return NULL;
        }
        self->data = newmap;
        self->size = new_size;
        Py_INCREF(Py_None);
        return Py_None;
#endif /* HAVE_MREMAP */
#endif /* UNIX */
    }
}
Example #8
0
static int
set_inheritable(int fd, int inheritable, int raise, int *atomic_flag_works)
{
#ifdef MS_WINDOWS
    HANDLE handle;
    DWORD flags;
#else
#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
    static int ioctl_works = -1;
    int request;
    int err;
#endif
    int flags, new_flags;
    int res;
#endif

    /* atomic_flag_works can only be used to make the file descriptor
       non-inheritable */
    assert(!(atomic_flag_works != NULL && inheritable));

    if (atomic_flag_works != NULL && !inheritable) {
        if (*atomic_flag_works == -1) {
            int isInheritable = get_inheritable(fd, raise);
            if (isInheritable == -1)
                return -1;
            *atomic_flag_works = !isInheritable;
        }

        if (*atomic_flag_works)
            return 0;
    }

#ifdef MS_WINDOWS
    _Py_BEGIN_SUPPRESS_IPH
    handle = (HANDLE)_get_osfhandle(fd);
    _Py_END_SUPPRESS_IPH
    if (handle == INVALID_HANDLE_VALUE) {
        if (raise)
            PyErr_SetFromErrno(PyExc_OSError);
        return -1;
    }

    if (inheritable)
        flags = HANDLE_FLAG_INHERIT;
    else
        flags = 0;
    if (!SetHandleInformation(handle, HANDLE_FLAG_INHERIT, flags)) {
        if (raise)
            PyErr_SetFromWindowsErr(0);
        return -1;
    }
    return 0;

#else

#if defined(HAVE_SYS_IOCTL_H) && defined(FIOCLEX) && defined(FIONCLEX)
    if (ioctl_works != 0) {
        /* fast-path: ioctl() only requires one syscall */
        if (inheritable)
            request = FIONCLEX;
        else
            request = FIOCLEX;
        err = ioctl(fd, request, NULL);
        if (!err) {
            ioctl_works = 1;
            return 0;
        }

        if (errno != ENOTTY && errno != EACCES) {
            if (raise)
                PyErr_SetFromErrno(PyExc_OSError);
            return -1;
        }
        else {
            /* Issue #22258: Here, ENOTTY means "Inappropriate ioctl for
               device". The ioctl is declared but not supported by the kernel.
               Remember that ioctl() doesn't work. It is the case on
               Illumos-based OS for example.

               Issue #27057: When SELinux policy disallows ioctl it will fail
               with EACCES. While FIOCLEX is safe operation it may be
               unavailable because ioctl was denied altogether.
               This can be the case on Android. */
            ioctl_works = 0;
        }
        /* fallback to fcntl() if ioctl() does not work */
    }
#endif

    /* slow-path: fcntl() requires two syscalls */
    flags = fcntl(fd, F_GETFD);
    if (flags < 0) {
        if (raise)
            PyErr_SetFromErrno(PyExc_OSError);
        return -1;
    }

    if (inheritable) {
        new_flags = flags & ~FD_CLOEXEC;
    }
    else {
        new_flags = flags | FD_CLOEXEC;
    }

    if (new_flags == flags) {
        /* FD_CLOEXEC flag already set/cleared: nothing to do */
        return 0;
    }

    res = fcntl(fd, F_SETFD, new_flags);
    if (res < 0) {
        if (raise)
            PyErr_SetFromErrno(PyExc_OSError);
        return -1;
    }
    return 0;
#endif
}
Example #9
0
static PyObject *
semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
{
    int blocking = 1;
    double timeout;
    PyObject *timeout_obj = Py_None;
    DWORD res, full_msecs, msecs, start, ticks;

    static char *kwlist[] = {"block", "timeout", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist,
                                     &blocking, &timeout_obj))
        return NULL;

    /* calculate timeout */
    if (!blocking) {
        full_msecs = 0;
    } else if (timeout_obj == Py_None) {
        full_msecs = INFINITE;
    } else {
        timeout = PyFloat_AsDouble(timeout_obj);
        if (PyErr_Occurred())
            return NULL;
        timeout *= 1000.0;      /* convert to millisecs */
        if (timeout < 0.0) {
            timeout = 0.0;
        } else if (timeout >= 0.5 * INFINITE) { /* 25 days */
            PyErr_SetString(PyExc_OverflowError,
                            "timeout is too large");
            return NULL;
        }
        full_msecs = (DWORD)(timeout + 0.5);
    }

    /* check whether we already own the lock */
    if (self->kind == RECURSIVE_MUTEX && ISMINE(self)) {
        ++self->count;
        Py_RETURN_TRUE;
    }

    /* check whether we can acquire without blocking */
    if (WaitForSingleObject(self->handle, 0) == WAIT_OBJECT_0) {
        self->last_tid = GetCurrentThreadId();
        ++self->count;
        Py_RETURN_TRUE;
    }

    msecs = full_msecs;
    start = GetTickCount();

    for ( ; ; ) {
        HANDLE handles[2] = {self->handle, sigint_event};

        /* do the wait */
        Py_BEGIN_ALLOW_THREADS
        ResetEvent(sigint_event);
        res = WaitForMultipleObjects(2, handles, FALSE, msecs);
        Py_END_ALLOW_THREADS

        /* handle result */
        if (res != WAIT_OBJECT_0 + 1)
            break;

        /* got SIGINT so give signal handler a chance to run */
        Sleep(1);

        /* if this is main thread let KeyboardInterrupt be raised */
        if (PyErr_CheckSignals())
            return NULL;

        /* recalculate timeout */
        if (msecs != INFINITE) {
            ticks = GetTickCount();
            if ((DWORD)(ticks - start) >= full_msecs)
                Py_RETURN_FALSE;
            msecs = full_msecs - (ticks - start);
        }
    }

    /* handle result */
    switch (res) {
    case WAIT_TIMEOUT:
        Py_RETURN_FALSE;
    case WAIT_OBJECT_0:
        self->last_tid = GetCurrentThreadId();
        ++self->count;
        Py_RETURN_TRUE;
    case WAIT_FAILED:
        return PyErr_SetFromWindowsErr(0);
    default:
        PyErr_Format(PyExc_RuntimeError, "WaitForSingleObject() or "
                     "WaitForMultipleObjects() gave unrecognized "
                     "value %d", res);
        return NULL;
    }
}
/* Returns:
 * 1: pid exists
 * 0: it doesn't
 * -1: error
 */
int
psutil_pid_is_running(DWORD pid) {
    HANDLE hProcess;
    DWORD exitCode;
    DWORD err;

    // Special case for PID 0 System Idle Process
    if (pid == 0)
        return 1;
    if (pid < 0)
        return 0;
    hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,
                           FALSE, pid);
    if (NULL == hProcess) {
        err = GetLastError();
        // Yeah, this is the actual error code in case of "no such process".
        if (err == ERROR_INVALID_PARAMETER) {
            if (! psutil_assert_pid_not_exists(
                    pid, "pir: OpenProcess() -> INVALID_PARAMETER")) {
                return -1;
            }
            return 0;
        }
        // Access denied obviously means there's a process to deny access to.
        else if (err == ERROR_ACCESS_DENIED) {
            if (! psutil_assert_pid_exists(
                    pid, "pir: OpenProcess() ACCESS_DENIED")) {
                return -1;
            }
            return 1;
        }
        // Be strict and raise an exception; the caller is supposed
        // to take -1 into account.
        else {
            PyErr_SetFromWindowsErr(err);
            return -1;
        }
    }

    if (GetExitCodeProcess(hProcess, &exitCode)) {
        CloseHandle(hProcess);
        // XXX - maybe STILL_ACTIVE is not fully reliable as per:
        // http://stackoverflow.com/questions/1591342/#comment47830782_1591379
        if (exitCode == STILL_ACTIVE) {
            if (! psutil_assert_pid_exists(
                    pid, "pir: GetExitCodeProcess() -> STILL_ACTIVE")) {
                return -1;
            }
            return 1;
        }
        // We can't be sure so we look into pids.
        else {
            return psutil_pid_in_pids(pid);
        }
    }
    else {
        err = GetLastError();
        CloseHandle(hProcess);
        // Same as for OpenProcess, assume access denied means there's
        // a process to deny access to.
        if (err == ERROR_ACCESS_DENIED) {
            if (! psutil_assert_pid_exists(
                    pid, "pir: GetExitCodeProcess() -> ERROR_ACCESS_DENIED")) {
                return -1;
            }
            return 1;
        }
        else {
            PyErr_SetFromWindowsErr(0);
            return -1;
        }
    }
}
/* Get data from the process with the given pid.  The data is returned in the
   pdata output member as a nul terminated string which must be freed on
   success.

   On success 0 is returned.  On error the output parameter is not touched, -1
   is returned, and an appropriate Python exception is set. */
static int psutil_get_process_data(long pid,
                                   enum psutil_process_data_kind kind,
                                   WCHAR **pdata,
                                   SIZE_T *psize) {
    /* This function is quite complex because there are several cases to be
       considered:

       Two cases are really simple:  we (i.e. the python interpreter) and the
       target process are both 32 bit or both 64 bit.  In that case the memory
       layout of the structures matches up and all is well.

       When we are 64 bit and the target process is 32 bit we need to use
       custom 32 bit versions of the structures.

       When we are 32 bit and the target process is 64 bit we need to use
       custom 64 bit version of the structures.  Also we need to use separate
       Wow64 functions to get the information.

       A few helper structs are defined above so that the compiler can handle
       calculating the correct offsets.

       Additional help also came from the following sources:

         https://github.com/kohsuke/winp and
         http://wj32.org/wp/2009/01/24/howto-get-the-command-line-of-processes/
         http://stackoverflow.com/a/14012919
         http://www.drdobbs.com/embracing-64-bit-windows/184401966
     */
    static _NtQueryInformationProcess NtQueryInformationProcess = NULL;
#ifndef _WIN64
    static _NtQueryInformationProcess NtWow64QueryInformationProcess64 = NULL;
    static _NtWow64ReadVirtualMemory64 NtWow64ReadVirtualMemory64 = NULL;
#endif
    HANDLE hProcess = NULL;
    LPCVOID src;
    SIZE_T size;
    WCHAR *buffer = NULL;
#ifdef _WIN64
    LPVOID ppeb32 = NULL;
#else
    PVOID64 src64;
    BOOL weAreWow64;
    BOOL theyAreWow64;
#endif

    hProcess = psutil_handle_from_pid(pid);
    if (hProcess == NULL)
        return -1;

    if (NtQueryInformationProcess == NULL) {
        NtQueryInformationProcess = (_NtQueryInformationProcess)GetProcAddress(
                GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");
    }

#ifdef _WIN64
    /* 64 bit case.  Check if the target is a 32 bit process running in WoW64
     * mode. */
    if (!NT_SUCCESS(NtQueryInformationProcess(hProcess,
                                              ProcessWow64Information,
                                              &ppeb32,
                                              sizeof(LPVOID),
                                              NULL))) {
        PyErr_SetFromWindowsErr(0);
        goto error;
    }

    if (ppeb32 != NULL) {
        /* We are 64 bit.  Target process is 32 bit running in WoW64 mode. */
        PEB32 peb32;
        RTL_USER_PROCESS_PARAMETERS32 procParameters32;

        // read PEB
        if (!ReadProcessMemory(hProcess, ppeb32, &peb32, sizeof(peb32), NULL)) {
            PyErr_SetFromWindowsErr(0);
            goto error;
        }

        // read process parameters
        if (!ReadProcessMemory(hProcess,
                              UlongToPtr(peb32.ProcessParameters),
                              &procParameters32,
                              sizeof(procParameters32),
                              NULL)) {
            PyErr_SetFromWindowsErr(0);
            goto error;
        }

        switch (kind) {
            case KIND_CMDLINE:
                src = UlongToPtr(procParameters32.CommandLine.Buffer),
                size = procParameters32.CommandLine.Length;
                break;
            case KIND_CWD:
                src = UlongToPtr(procParameters32.CurrentDirectoryPath.Buffer);
                size = procParameters32.CurrentDirectoryPath.Length;
                break;
            case KIND_ENVIRON:
                src = UlongToPtr(procParameters32.env);
                break;
        }
    } else
#else
    /* 32 bit case.  Check if the target is also 32 bit. */
    if (!IsWow64Process(GetCurrentProcess(), &weAreWow64) ||
        !IsWow64Process(hProcess, &theyAreWow64)) {
        PyErr_SetFromWindowsErr(0);
        goto error;
    }

    if (weAreWow64 && !theyAreWow64) {
        /* We are 32 bit running in WoW64 mode.  Target process is 64 bit. */
        PROCESS_BASIC_INFORMATION64 pbi64;
        PEB64 peb64;
        RTL_USER_PROCESS_PARAMETERS64 procParameters64;

        if (NtWow64QueryInformationProcess64 == NULL) {
            NtWow64QueryInformationProcess64 =
                (_NtQueryInformationProcess)GetProcAddress(
                        GetModuleHandleA("ntdll.dll"),
                        "NtWow64QueryInformationProcess64");

            if (NtWow64QueryInformationProcess64 == NULL) {
                PyErr_SetString(PyExc_NotImplementedError,
                                "NtWow64QueryInformationProcess64 missing");
                goto error;
            }
        }

        if (!NT_SUCCESS(NtWow64QueryInformationProcess64(
                        hProcess,
                        ProcessBasicInformation,
                        &pbi64,
                        sizeof(pbi64),
                        NULL))) {
            PyErr_SetFromWindowsErr(0);
            goto error;
        }

        // read peb
        if (NtWow64ReadVirtualMemory64 == NULL) {
            NtWow64ReadVirtualMemory64 =
                (_NtWow64ReadVirtualMemory64)GetProcAddress(
                        GetModuleHandleA("ntdll.dll"),
                        "NtWow64ReadVirtualMemory64");

            if (NtWow64ReadVirtualMemory64 == NULL) {
                PyErr_SetString(PyExc_NotImplementedError,
                                "NtWow64ReadVirtualMemory64 missing");
                goto error;
            }
        }

        if (!NT_SUCCESS(NtWow64ReadVirtualMemory64(hProcess,
                                                   pbi64.PebBaseAddress,
                                                   &peb64,
                                                   sizeof(peb64),
                                                   NULL))) {
            PyErr_SetFromWindowsErr(0);
            goto error;
        }

        // read process parameters
        if (!NT_SUCCESS(NtWow64ReadVirtualMemory64(hProcess,
                                                   peb64.ProcessParameters,
                                                   &procParameters64,
                                                   sizeof(procParameters64),
                                                   NULL))) {
            PyErr_SetFromWindowsErr(0);
            goto error;
        }

        switch (kind) {
            case KIND_CMDLINE:
                src64 = procParameters64.CommandLine.Buffer;
                size = procParameters64.CommandLine.Length;
                break;
            case KIND_CWD:
                src64 = procParameters64.CurrentDirectoryPath.Buffer,
                size = procParameters64.CurrentDirectoryPath.Length;
                break;
            case KIND_ENVIRON:
                src64 = procParameters64.env;
                break;
        }
    } else
#endif

    /* Target process is of the same bitness as us. */
    {
        PROCESS_BASIC_INFORMATION pbi;
        PEB_ peb;
        RTL_USER_PROCESS_PARAMETERS_ procParameters;

        if (!NT_SUCCESS(NtQueryInformationProcess(hProcess,
                                                  ProcessBasicInformation,
                                                  &pbi,
                                                  sizeof(pbi),
                                                  NULL))) {
            PyErr_SetFromWindowsErr(0);
            goto error;
        }

        // read peb
        if (!ReadProcessMemory(hProcess,
                               pbi.PebBaseAddress,
                               &peb,
                               sizeof(peb),
                               NULL)) {
            PyErr_SetFromWindowsErr(0);
            goto error;
        }

        // read process parameters
        if (!ReadProcessMemory(hProcess,
                               peb.ProcessParameters,
                               &procParameters,
                               sizeof(procParameters),
                               NULL)) {
            PyErr_SetFromWindowsErr(0);
            goto error;
        }

        switch (kind) {
            case KIND_CMDLINE:
                src = procParameters.CommandLine.Buffer;
                size = procParameters.CommandLine.Length;
                break;
            case KIND_CWD:
                src = procParameters.CurrentDirectoryPath.Buffer;
                size = procParameters.CurrentDirectoryPath.Length;
                break;
            case KIND_ENVIRON:
                src = procParameters.env;
                break;
        }
    }

    if (kind == KIND_ENVIRON) {
#ifndef _WIN64
        if (weAreWow64 && !theyAreWow64) {
            ULONG64 size64;

            if (psutil_get_process_region_size64(hProcess, src64, &size64) != 0)
                goto error;

            size = (SIZE_T)size64;
        }
        else
#endif
        if (psutil_get_process_region_size(hProcess, src, &size) != 0)
            goto error;
    }

    buffer = calloc(size + 2, 1);

    if (buffer == NULL) {
        PyErr_NoMemory();
        goto error;
    }

#ifndef _WIN64
    if (weAreWow64 && !theyAreWow64) {
        if (!NT_SUCCESS(NtWow64ReadVirtualMemory64(hProcess,
                                                   src64,
                                                   buffer,
                                                   size,
                                                   NULL))) {
            PyErr_SetFromWindowsErr(0);
            goto error;
        }
    } else
#endif
    if (!ReadProcessMemory(hProcess, src, buffer, size, NULL)) {
        PyErr_SetFromWindowsErr(0);
        goto error;
    }

    CloseHandle(hProcess);

    *pdata = buffer;
    *psize = size;

    return 0;

error:
    if (hProcess != NULL)
        CloseHandle(hProcess);
    if (buffer != NULL)
        free(buffer);
    return -1;
}
Example #12
0
static PyObject *
semlock_acquire(SemLockObject *self, PyObject *args, PyObject *kwds)
{
    int blocking = 1;
    double timeout;
    PyObject *timeout_obj = Py_None;
    DWORD res, full_msecs, nhandles;
    HANDLE handles[2], sigint_event;

    static char *kwlist[] = {"block", "timeout", NULL};

    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|iO", kwlist,
                                     &blocking, &timeout_obj))
        return NULL;

    /* calculate timeout */
    if (!blocking) {
        full_msecs = 0;
    } else if (timeout_obj == Py_None) {
        full_msecs = INFINITE;
    } else {
        timeout = PyFloat_AsDouble(timeout_obj);
        if (PyErr_Occurred())
            return NULL;
        timeout *= 1000.0;      /* convert to millisecs */
        if (timeout < 0.0) {
            timeout = 0.0;
        } else if (timeout >= 0.5 * INFINITE) { /* 25 days */
            PyErr_SetString(PyExc_OverflowError,
                            "timeout is too large");
            return NULL;
        }
        full_msecs = (DWORD)(timeout + 0.5);
    }

    /* check whether we already own the lock */
    if (self->kind == RECURSIVE_MUTEX && ISMINE(self)) {
        ++self->count;
        Py_RETURN_TRUE;
    }

    /* check whether we can acquire without releasing the GIL and blocking */
    if (WaitForSingleObjectEx(self->handle, 0, FALSE) == WAIT_OBJECT_0) {
        self->last_tid = GetCurrentThreadId();
        ++self->count;
        Py_RETURN_TRUE;
    }

    /* prepare list of handles */
    nhandles = 0;
    handles[nhandles++] = self->handle;
    if (_PyOS_IsMainThread()) {
        sigint_event = _PyOS_SigintEvent();
        assert(sigint_event != NULL);
        handles[nhandles++] = sigint_event;
    }

    /* do the wait */
    Py_BEGIN_ALLOW_THREADS
    if (sigint_event != NULL)
        ResetEvent(sigint_event);
    res = WaitForMultipleObjectsEx(nhandles, handles, FALSE, full_msecs, FALSE);
    Py_END_ALLOW_THREADS

    /* handle result */
    switch (res) {
    case WAIT_TIMEOUT:
        Py_RETURN_FALSE;
    case WAIT_OBJECT_0 + 0:
        self->last_tid = GetCurrentThreadId();
        ++self->count;
        Py_RETURN_TRUE;
    case WAIT_OBJECT_0 + 1:
        errno = EINTR;
        return PyErr_SetFromErrno(PyExc_IOError);
    case WAIT_FAILED:
        return PyErr_SetFromWindowsErr(0);
    default:
        PyErr_Format(PyExc_RuntimeError, "WaitForSingleObject() or "
                     "WaitForMultipleObjects() gave unrecognized "
                     "value %d", res);
        return NULL;
    }
}
Example #13
0
/*
 * Enumerate all services.
 */
PyObject *
psutil_winservice_enumerate(PyObject *self, PyObject *args) {
    ENUM_SERVICE_STATUS_PROCESS *lpService = NULL;
    BOOL ok;
    SC_HANDLE sc = NULL;
    DWORD bytesNeeded = 0;
    DWORD srvCount;
    DWORD resumeHandle = 0;
    DWORD dwBytes = 0;
    DWORD i;
    PyObject *py_retlist = PyList_New(0);
    PyObject *py_tuple = NULL;
    PyObject *py_unicode_display_name = NULL;

    if (py_retlist == NULL)
        return NULL;

    sc = OpenSCManager(NULL, NULL, SC_MANAGER_ENUMERATE_SERVICE);
    if (sc == NULL) {
        PyErr_SetFromWindowsErr(0);
        return NULL;
    }

    for (;;) {
        ok = EnumServicesStatusEx(
            sc,
            SC_ENUM_PROCESS_INFO,
            SERVICE_WIN32,  // XXX - extend this to include drivers etc.?
            SERVICE_STATE_ALL,
            (LPBYTE)lpService,
            dwBytes,
            &bytesNeeded,
            &srvCount,
            &resumeHandle,
            NULL);
        if (ok || (GetLastError() != ERROR_MORE_DATA))
            break;
        if (lpService)
            free(lpService);
        dwBytes = bytesNeeded;
        lpService = (ENUM_SERVICE_STATUS_PROCESS*)malloc(dwBytes);
    }

    for (i = 0; i < srvCount; i++) {
        // Get unicode display name.
        py_unicode_display_name = NULL;
        py_unicode_display_name = PyUnicode_Decode(
            lpService[i].lpDisplayName,
            _tcslen(lpService[i].lpDisplayName),
            Py_FileSystemDefaultEncoding,
            "replace");
        if (py_unicode_display_name == NULL)
            goto error;

        // Construct the result.
        py_tuple = Py_BuildValue(
            "(sO)",
            lpService[i].lpServiceName,  // name
            py_unicode_display_name  // display_name
        );
        if (py_tuple == NULL)
            goto error;
        if (PyList_Append(py_retlist, py_tuple))
            goto error;
        Py_DECREF(py_unicode_display_name);
        Py_DECREF(py_tuple);
    }

    // Free resources.
    CloseServiceHandle(sc);
    free(lpService);
    return py_retlist;

error:
    Py_XDECREF(py_unicode_display_name);
    Py_XDECREF(py_tuple);
    Py_DECREF(py_retlist);
    if (sc != NULL)
        CloseServiceHandle(sc);
    if (lpService != NULL)
        free(lpService);
    return NULL;
}
Example #14
0
/*
 * Get service status information. Returns:
 * - status
 * - pid
 */
PyObject *
psutil_winservice_query_status(PyObject *self, PyObject *args) {
    char *service_name;
    SC_HANDLE hService = NULL;
    BOOL ok;
    DWORD bytesNeeded = 0;
    DWORD resumeHandle = 0;
    DWORD dwBytes = 0;
    SERVICE_STATUS_PROCESS  *ssp = NULL;
    PyObject *py_tuple = NULL;

    if (!PyArg_ParseTuple(args, "s", &service_name))
        return NULL;
    hService = psutil_get_service_handler(
        service_name, SC_MANAGER_ENUMERATE_SERVICE, SERVICE_QUERY_STATUS);
    if (hService == NULL)
        goto error;

    // First call to QueryServiceStatusEx() is necessary to get the
    // right size.
    QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, NULL, 0,
                         &bytesNeeded);
    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        PyErr_SetFromWindowsErr(0);
        goto error;
    }
    ssp = (SERVICE_STATUS_PROCESS *)HeapAlloc(
        GetProcessHeap(), 0, bytesNeeded);
    if (ssp == NULL) {
        PyErr_NoMemory();
        goto error;
    }

    // Actual call.
    ok = QueryServiceStatusEx(hService, SC_STATUS_PROCESS_INFO, (LPBYTE)ssp,
                              bytesNeeded, &bytesNeeded);
    if (ok == 0) {
        PyErr_SetFromWindowsErr(0);
        goto error;
    }

    py_tuple = Py_BuildValue(
        "(sk)",
        get_state_string(ssp->dwCurrentState),
        ssp->dwProcessId
    );
    if (py_tuple == NULL)
        goto error;

    CloseServiceHandle(hService);
    HeapFree(GetProcessHeap(), 0, ssp);
    return py_tuple;

error:
    Py_XDECREF(py_tuple);
    if (hService != NULL)
        CloseServiceHandle(hService);
    if (ssp != NULL)
        HeapFree(GetProcessHeap(), 0, ssp);
    return NULL;
}
Example #15
0
/*
 * Get service config information. Returns:
 * - display_name
 * - binpath
 * - username
 * - startup_type
 */
PyObject *
psutil_winservice_query_config(PyObject *self, PyObject *args) {
    char *service_name;
    SC_HANDLE hService = NULL;
    BOOL ok;
    DWORD bytesNeeded = 0;
    DWORD resumeHandle = 0;
    DWORD dwBytes = 0;
    QUERY_SERVICE_CONFIG *qsc = NULL;
    PyObject *py_tuple = NULL;
    PyObject *py_unicode_display_name = NULL;
    PyObject *py_unicode_binpath = NULL;
    PyObject *py_unicode_username = NULL;

    if (!PyArg_ParseTuple(args, "s", &service_name))
        return NULL;
    hService = psutil_get_service_handler(
        service_name, SC_MANAGER_ENUMERATE_SERVICE, SERVICE_QUERY_CONFIG);
    if (hService == NULL)
        goto error;

    // First call to QueryServiceConfig() is necessary to get the
    // right size.
    bytesNeeded = 0;
    QueryServiceConfig(hService, NULL, 0, &bytesNeeded);
    if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
        PyErr_SetFromWindowsErr(0);
        goto error;
    }
    qsc = (QUERY_SERVICE_CONFIG *)malloc(bytesNeeded);
    ok = QueryServiceConfig(hService, qsc, bytesNeeded, &bytesNeeded);
    if (ok == 0) {
        PyErr_SetFromWindowsErr(0);
        goto error;
    }

    // Get unicode display name.
    py_unicode_display_name = PyUnicode_Decode(
        qsc->lpDisplayName,
        _tcslen(qsc->lpDisplayName),
        Py_FileSystemDefaultEncoding,
        "replace");
    if (py_unicode_display_name == NULL)
        goto error;

    // Get unicode bin path.
    py_unicode_binpath = PyUnicode_Decode(
        qsc->lpBinaryPathName,
        _tcslen(qsc->lpBinaryPathName),
        Py_FileSystemDefaultEncoding,
        "replace");
    if (py_unicode_binpath == NULL)
        goto error;

    // Get unicode username.
    py_unicode_username = PyUnicode_Decode(
        qsc->lpServiceStartName,
        _tcslen(qsc->lpServiceStartName),
        Py_FileSystemDefaultEncoding,
        "replace");
    if (py_unicode_username == NULL)
        goto error;

    // Construct result tuple.
    py_tuple = Py_BuildValue(
        "(OOOs)",
        py_unicode_display_name,
        py_unicode_binpath,
        py_unicode_username,
        get_startup_string(qsc->dwStartType)  // startup
    );
    if (py_tuple == NULL)
        goto error;

    // Free resources.
    Py_DECREF(py_unicode_display_name);
    Py_DECREF(py_unicode_binpath);
    Py_DECREF(py_unicode_username);
    free(qsc);
    CloseServiceHandle(hService);
    return py_tuple;

error:
    Py_XDECREF(py_unicode_display_name);
    Py_XDECREF(py_unicode_binpath);
    Py_XDECREF(py_unicode_username);
    Py_XDECREF(py_tuple);
    if (hService != NULL)
        CloseServiceHandle(hService);
    if (qsc != NULL)
        free(qsc);
    return NULL;
}
Example #16
0
PyMODINIT_FUNC
init_multiprocess(void)
{
    PyObject *module, *temp, *value;

    /* Initialize module */
    module = Py_InitModule("_multiprocess", module_methods);
    if (!module)
        return;

    /* Get copy of objects from pickle */
    temp = PyImport_ImportModule("dill");
    if (!temp)
        temp = PyImport_ImportModule(PICKLE_MODULE);
    if (!temp)
        return;
    pickle_dumps = PyObject_GetAttrString(temp, "dumps");
    pickle_loads = PyObject_GetAttrString(temp, "loads");
    pickle_protocol = PyObject_GetAttrString(temp, "DEFAULT_PROTOCOL");
    if (!pickle_protocol)
        pickle_protocol = PyObject_GetAttrString(temp, "HIGHEST_PROTOCOL");
    Py_XDECREF(temp);

    /* Get copy of BufferTooShort */
    temp = PyImport_ImportModule("multiprocess");
    if (!temp)
        return;
    BufferTooShort = PyObject_GetAttrString(temp, "BufferTooShort");
    Py_XDECREF(temp);

    /* Add connection type to module */
    if (PyType_Ready(&ConnectionType) < 0)
        return;
    Py_INCREF(&ConnectionType);
    PyModule_AddObject(module, "Connection", (PyObject*)&ConnectionType);

#if defined(MS_WINDOWS) || HAVE_SEM_OPEN
    /* Add SemLock type to module */
    if (PyType_Ready(&SemLockType) < 0)
        return;
    Py_INCREF(&SemLockType);
    PyDict_SetItemString(SemLockType.tp_dict, "SEM_VALUE_MAX",
                         Py_BuildValue("i", SEM_VALUE_MAX));
    PyModule_AddObject(module, "SemLock", (PyObject*)&SemLockType);
#endif

#ifdef MS_WINDOWS
    /* Add PipeConnection to module */
    if (PyType_Ready(&PipeConnectionType) < 0)
        return;
    Py_INCREF(&PipeConnectionType);
    PyModule_AddObject(module, "PipeConnection",
                       (PyObject*)&PipeConnectionType);

    /* Initialize win32 class and add to multiprocessing */
    temp = create_win32_namespace();
    if (!temp)
        return;
    PyModule_AddObject(module, "win32", temp);

    /* Initialize the event handle used to signal Ctrl-C */
    sigint_event = CreateEvent(NULL, TRUE, FALSE, NULL);
    if (!sigint_event) {
        PyErr_SetFromWindowsErr(0);
        return;
    }
    if (!SetConsoleCtrlHandler(ProcessingCtrlHandler, TRUE)) {
        PyErr_SetFromWindowsErr(0);
        return;
    }
#endif

    /* Add configuration macros */
    temp = PyDict_New();
    if (!temp)
        return;
#define ADD_FLAG(name)                                            \
    value = Py_BuildValue("i", name);                             \
    if (value == NULL) { Py_DECREF(temp); return; }               \
    if (PyDict_SetItemString(temp, #name, value) < 0) {           \
        Py_DECREF(temp); Py_DECREF(value); return; }              \
    Py_DECREF(value)

#ifdef HAVE_SEM_OPEN
    ADD_FLAG(HAVE_SEM_OPEN);
#endif
#ifdef HAVE_SEM_TIMEDWAIT
    ADD_FLAG(HAVE_SEM_TIMEDWAIT);
#endif
#ifdef HAVE_FD_TRANSFER
    ADD_FLAG(HAVE_FD_TRANSFER);
#endif
#ifdef HAVE_BROKEN_SEM_GETVALUE
    ADD_FLAG(HAVE_BROKEN_SEM_GETVALUE);
#endif
#ifdef HAVE_BROKEN_SEM_UNLINK
    ADD_FLAG(HAVE_BROKEN_SEM_UNLINK);
#endif
    if (PyModule_AddObject(module, "flags", temp) < 0)
        return;
}