Skip to content

Commit

Permalink
Solaris 10 Fixes (#1248)
Browse files Browse the repository at this point in the history
* Fix nice() for realtime processes under Solaris 10

fixes #1194

* Use psinfo as fallback [gu]id source on Solaris 10

fixes #1193

* Fix double free

* Match ssize_t return type of read functions

* Fix undefined behavior

with respect to strict aliasing rules and fix some warnings

For example, under strict aliasing rules of the C standard, casting a
char pointer to a struct pointer and accessing the character array
through that struct pointer yields undefined behavior.

* Update HISTORY with Solaris notes
  • Loading branch information
gsauthof authored and giampaolo committed Mar 17, 2018
1 parent c088fb5 commit 6276764
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 117 deletions.
7 changes: 7 additions & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,13 @@ XXXX-XX-XX
- 1240_: [Windows] cpu_times() float loses accuracy in a long running system.
(patch by stswandering)
- 1245_: [Linux] sensors_temperatures() may fail with IOError "no such file".
- 1193_: [SunOS] Return uid/gid from /proc/pid/psinfo if there aren't
enough permissions for /proc/pid/cred
- 1194_: [SunOS] Return nice value from psinfo as getpriority() doesn't
support real-time processes
- 1194_: [SunOS] Fix double free in psutil_proc_cpu_num()
- 1194_: [SunOS] Fix undefined behavior related to strict-aliasing rules
and warnings

5.4.3
=====
Expand Down
50 changes: 25 additions & 25 deletions psutil/_pssunos.py
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,11 @@
nice=4,
num_threads=5,
status=6,
ttynr=7)
ttynr=7,
uid=8,
euid=9,
gid=10,
egid=11)


# =====================================================================
Expand Down Expand Up @@ -394,7 +398,10 @@ def _proc_basic_info(self):

@memoize_when_activated
def _proc_cred(self):
return cext.proc_cred(self.pid, self._procfs_path)
@wrap_exceptions
def proc_cred(self):
return cext.proc_cred(self.pid, self._procfs_path)
return proc_cred(self)

@wrap_exceptions
def name(self):
Expand Down Expand Up @@ -432,27 +439,10 @@ def num_threads(self):

@wrap_exceptions
def nice_get(self):
# Note #1: for some reason getpriority(3) return ESRCH (no such
# process) for certain low-pid processes, no matter what (even
# as root).
# The process actually exists though, as it has a name,
# creation time, etc.
# The best thing we can do here appears to be raising AD.
# Note: tested on Solaris 11; on Open Solaris 5 everything is
# fine.
#
# Note #2: we also can get niceness from /proc/pid/psinfo
# but it's wrong, see:
# https://github.com/giampaolo/psutil/issues/1082
try:
return cext_posix.getpriority(self.pid)
except EnvironmentError as err:
# 48 is 'operation not supported' but errno does not expose
# it. It occurs for low system pids.
if err.errno in (errno.ENOENT, errno.ESRCH, 48):
if pid_exists(self.pid):
raise AccessDenied(self.pid, self._name)
raise
# Note #1: getpriority(3) doesn't work for realtime processes.
# Psinfo is what ps uses, see:
# https://github.com/giampaolo/psutil/issues/1194
return self._proc_basic_info()[proc_info_map['nice']]

@wrap_exceptions
def nice_set(self, value):
Expand All @@ -471,12 +461,22 @@ def ppid(self):

@wrap_exceptions
def uids(self):
real, effective, saved, _, _, _ = self._proc_cred()
try:
real, effective, saved, _, _, _ = self._proc_cred()
except AccessDenied:
real = self._proc_basic_info()[proc_info_map['uid']]
effective = self._proc_basic_info()[proc_info_map['euid']]
saved = None
return _common.puids(real, effective, saved)

@wrap_exceptions
def gids(self):
_, _, _, real, effective, saved = self._proc_cred()
try:
_, _, _, real, effective, saved = self._proc_cred()
except AccessDenied:
real = self._proc_basic_info()[proc_info_map['gid']]
effective = self._proc_basic_info()[proc_info_map['egid']]
saved = None
return _common.puids(real, effective, saved)

@wrap_exceptions
Expand Down
4 changes: 2 additions & 2 deletions psutil/_psutil_common.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ PyUnicode_DecodeFSDefaultAndSize(char *s, Py_ssize_t size) {
* If msg != "" the exception message will change in accordance.
*/
PyObject *
NoSuchProcess(char *msg) {
NoSuchProcess(const char *msg) {
PyObject *exc;
exc = PyObject_CallFunction(
PyExc_OSError, "(is)", ESRCH, strlen(msg) ? msg : strerror(ESRCH));
Expand All @@ -55,7 +55,7 @@ NoSuchProcess(char *msg) {
* If msg != "" the exception message will change in accordance.
*/
PyObject *
AccessDenied(char *msg) {
AccessDenied(const char *msg) {
PyObject *exc;
exc = PyObject_CallFunction(
PyExc_OSError, "(is)", EACCES, strlen(msg) ? msg : strerror(EACCES));
Expand Down
9 changes: 7 additions & 2 deletions psutil/_psutil_common.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
* found in the LICENSE file.
*/

#ifndef PSUTIL_PSUTIL_COMMON_H
#define PSUTIL_PSUTIL_COMMON_H

#include <Python.h>

extern int PSUTIL_TESTING;
Expand All @@ -17,9 +20,11 @@ PyObject* PyUnicode_DecodeFSDefault(char *s);
PyObject* PyUnicode_DecodeFSDefaultAndSize(char *s, Py_ssize_t size);
#endif

PyObject* AccessDenied(char *msg);
PyObject* NoSuchProcess(char *msg);
PyObject* AccessDenied(const char *msg);
PyObject* NoSuchProcess(const char *msg);

PyObject* psutil_set_testing(PyObject *self, PyObject *args);
void psutil_debug(const char* format, ...);
void psutil_setup(void);

#endif // PSUTIL_PSUTIL_COMMON_H
Loading

0 comments on commit 6276764

Please sign in to comment.