Skip to content

Commit

Permalink
Merge pull request #610 from Infinidat/master
Browse files Browse the repository at this point in the history
fix build and tests on Solaris 10
  • Loading branch information
giampaolo committed Sep 5, 2015
2 parents 95625f1 + e91f722 commit 7ca207d
Show file tree
Hide file tree
Showing 11 changed files with 189 additions and 27 deletions.
4 changes: 4 additions & 0 deletions CREDITS
Original file line number Diff line number Diff line change
Expand Up @@ -325,3 +325,7 @@ I: 670
N: maozguttman
W: https://github.com/maozguttman
I: 659

N: wiggin15
W: https://github.com/wiggin15
I: 607, 610
1 change: 1 addition & 0 deletions HISTORY.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ Bug tracker at https://github.com/giampaolo/psutil/issues
**Bug fixes**

- #677: [Linux] can't install psutil due to bug in setup.py.
- #610: [SunOS] fix build and tests on Solaris 10


3.2.0 - 2015-09-02
Expand Down
10 changes: 4 additions & 6 deletions psutil/_pssunos.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,13 @@ def swap_memory():
# ...nevertheless I can't manage to obtain the same numbers as 'swap'
# cmdline utility, so let's parse its output (sigh!)
p = subprocess.Popen(['/usr/bin/env', 'PATH=/usr/sbin:/sbin:%s' %
os.environ['PATH'], 'swap', '-l', '-k'],
os.environ['PATH'], 'swap', '-l'],
stdout=subprocess.PIPE)
stdout, stderr = p.communicate()
if PY3:
stdout = stdout.decode(sys.stdout.encoding)
if p.returncode != 0:
raise RuntimeError("'swap -l -k' failed (retcode=%s)" % p.returncode)
raise RuntimeError("'swap -l' failed (retcode=%s)" % p.returncode)

lines = stdout.strip().split('\n')[1:]
if not lines:
Expand All @@ -110,10 +110,8 @@ def swap_memory():
for line in lines:
line = line.split()
t, f = line[-2:]
t = t.replace('K', '')
f = f.replace('K', '')
total += int(int(t) * 1024)
free += int(int(f) * 1024)
total += int(int(t) * 512)
free += int(int(f) * 512)
used = total - free
percent = usage_percent(used, total, _round=1)
return _common.sswap(total, used, free, percent,
Expand Down
7 changes: 6 additions & 1 deletion psutil/_psutil_posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,14 @@
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <ifaddrs.h>
#include <net/if.h>

#ifdef PSUTIL_SUNOS10
#include "arch/solaris10/ifaddrs.h"
#else
#include <ifaddrs.h>
#endif

#ifdef __linux
#include <netdb.h>
#include <linux/if_packet.h>
Expand Down
12 changes: 6 additions & 6 deletions psutil/_psutil_sunos.c
Original file line number Diff line number Diff line change
Expand Up @@ -1157,21 +1157,21 @@ psutil_net_if_stats(PyObject* self, PyObject* args) {

for (ksp = kc->kc_chain; ksp; ksp = ksp->ks_next) {
if (strcmp(ksp->ks_class, "net") == 0) {
struct ifreq ifr;
struct lifreq ifr;

kstat_read(kc, ksp, NULL);
if (ksp->ks_type != KSTAT_TYPE_NAMED)
continue;
if (strcmp(ksp->ks_class, "net") != 0)
continue;

strncpy(ifr.ifr_name, ksp->ks_name, sizeof(ifr.ifr_name));
ret = ioctl(sock, SIOCGIFFLAGS, &ifr);
strncpy(ifr.lifr_name, ksp->ks_name, sizeof(ifr.lifr_name));
ret = ioctl(sock, SIOCGLIFFLAGS, &ifr);
if (ret == -1)
continue; // not a network interface

// is up?
if ((ifr.ifr_flags & IFF_UP) != 0) {
if ((ifr.lifr_flags & IFF_UP) != 0) {
if ((knp = kstat_data_lookup(ksp, "link_up")) != NULL) {
if (knp->value.ui32 != 0u)
py_is_up = Py_True;
Expand Down Expand Up @@ -1204,12 +1204,12 @@ psutil_net_if_stats(PyObject* self, PyObject* args) {
speed = 0;

// mtu
ret = ioctl(sock, SIOCGIFMTU, &ifr);
ret = ioctl(sock, SIOCGLIFMTU, &ifr);
if (ret == -1)
goto error;

py_ifc_info = Py_BuildValue("(Oiii)", py_is_up, duplex, speed,
ifr.ifr_mtu);
ifr.lifr_mtu);
if (!py_ifc_info)
goto error;
if (PyDict_SetItemString(py_retdict, ksp->ks_name, py_ifc_info))
Expand Down
124 changes: 124 additions & 0 deletions psutil/arch/solaris/v10/ifaddrs.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
/* Refrences:
* https://lists.samba.org/archive/samba-technical/2009-February/063079.html
* http://stackoverflow.com/questions/4139405/#4139811
* https://code.google.com/p/openpgm/source/browse/trunk/openpgm/pgm/getifaddrs.c
*/

#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <net/if.h>
#include <netinet/in.h>
#include <sys/ioctl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/sockio.h>

#include "ifaddrs.h"

#define MAX(x,y) ((x)>(y)?(x):(y))
#define SIZE(p) MAX((p).ss_len,sizeof(p))


static struct sockaddr *
sa_dup (struct sockaddr *sa1)
{
struct sockaddr *sa2;
size_t sz = sizeof(sa1);
sa2 = (struct sockaddr *) calloc(1,sz);
memcpy(sa2,sa1,sz);
return(sa2);
}


void freeifaddrs (struct ifaddrs *ifp)
{
if (NULL == ifp) return;
free(ifp->ifa_name);
free(ifp->ifa_addr);
free(ifp->ifa_netmask);
free(ifp->ifa_dstaddr);
freeifaddrs(ifp->ifa_next);
free(ifp);
}


int getifaddrs (struct ifaddrs **ifap)
{
int sd = -1;
char *ccp, *ecp;
struct lifconf ifc;
struct lifreq *ifr;
struct lifnum lifn;
struct ifaddrs *cifa = NULL; /* current */
struct ifaddrs *pifa = NULL; /* previous */
const size_t IFREQSZ = sizeof(struct lifreq);

sd = socket(AF_INET, SOCK_STREAM, 0);
if (sd < 0)
goto error;

ifc.lifc_buf = NULL;
*ifap = NULL;
/* find how much memory to allocate for the SIOCGLIFCONF call */
lifn.lifn_family = AF_UNSPEC;
lifn.lifn_flags = 0;
if (ioctl(sd, SIOCGLIFNUM, &lifn) < 0)
goto error;

/* Sun and Apple code likes to pad the interface count here in case interfaces
* are coming up between calls */
lifn.lifn_count += 4;

ifc.lifc_family = AF_UNSPEC;
ifc.lifc_len = lifn.lifn_count * sizeof(struct lifreq);
ifc.lifc_buf = calloc(1, ifc.lifc_len);
if (ioctl(sd, SIOCGLIFCONF, &ifc) < 0)
goto error;

ccp = (char *)ifc.lifc_req;
ecp = ccp + ifc.lifc_len;

while (ccp < ecp) {

ifr = (struct lifreq *) ccp;
cifa = (struct ifaddrs *) calloc(1, sizeof(struct ifaddrs));
cifa->ifa_next = NULL;
cifa->ifa_name = strdup(ifr->lifr_name);

if (pifa == NULL) *ifap = cifa; /* first one */
else pifa->ifa_next = cifa;

if (ioctl(sd, SIOCGLIFADDR, ifr, IFREQSZ) < 0)
goto error;
cifa->ifa_addr = sa_dup((struct sockaddr*)&ifr->lifr_addr);

if (ioctl(sd, SIOCGLIFNETMASK, ifr, IFREQSZ) < 0)
goto error;
cifa->ifa_netmask = sa_dup((struct sockaddr*)&ifr->lifr_addr);

cifa->ifa_flags = 0;
cifa->ifa_dstaddr = NULL;

if (0 == ioctl(sd, SIOCGLIFFLAGS, ifr)) /* optional */
cifa->ifa_flags = ifr->lifr_flags;

if (ioctl(sd, SIOCGLIFDSTADDR, ifr, IFREQSZ) < 0) {
if (0 == ioctl(sd, SIOCGLIFBRDADDR, ifr, IFREQSZ))
cifa->ifa_dstaddr = sa_dup((struct sockaddr*)&ifr->lifr_addr);
}
else cifa->ifa_dstaddr = sa_dup((struct sockaddr*)&ifr->lifr_addr);

pifa = cifa;
ccp += IFREQSZ;
}
free(ifc.lifc_buf);
close(sd);
return 0;
error:
if (ifc.lifc_buf != NULL)
free(ifc.lifc_buf);
if (sd != -1)
close(sd);
return (-1);
}
26 changes: 26 additions & 0 deletions psutil/arch/solaris/v10/ifaddrs.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/* Reference: https://lists.samba.org/archive/samba-technical/2009-February/063079.html */


#ifndef __IFADDRS_H___
#define __IFADDRS_H___

#include <sys/socket.h>
#include <net/if.h>

#undef ifa_dstaddr
#undef ifa_broadaddr
#define ifa_broadaddr ifa_dstaddr

struct ifaddrs {
struct ifaddrs *ifa_next;
char *ifa_name;
unsigned int ifa_flags;
struct sockaddr *ifa_addr;
struct sockaddr *ifa_netmask;
struct sockaddr *ifa_dstaddr;
};

extern int getifaddrs(struct ifaddrs **);
extern void freeifaddrs(struct ifaddrs *);

#endif
13 changes: 8 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import os
import sys
import tempfile
import platform
try:
from setuptools import setup, Extension
except ImportError:
Expand Down Expand Up @@ -64,13 +65,15 @@ def write(self, s):

# POSIX
if os.name == 'posix':
libraries = []
if sys.platform.startswith("sunos"):
libraries.append('socket')
posix_extension = Extension(
'psutil._psutil_posix',
sources=['psutil/_psutil_posix.c'],
libraries=libraries)
sources=['psutil/_psutil_posix.c'])
if sys.platform.startswith("sunos"):
posix_extension.libraries.append('socket')
if platform.release() == '5.10':
posix_extension.sources.append('psutil/arch/solaris/v10/ifaddrs.c')
posix_extension.define_macros.append(('PSUTIL_SUNOS10', 1))

# Windows
if sys.platform.startswith("win32"):

Expand Down
3 changes: 2 additions & 1 deletion test/_posix.py
Original file line number Diff line number Diff line change
Expand Up @@ -150,11 +150,12 @@ def test_pids(self):
# Note: this test might fail if the OS is starting/killing
# other processes in the meantime
if SUNOS:
cmd = ["ps", "ax"]
cmd = ["ps", "-A", "-o", "pid"]
else:
cmd = ["ps", "ax", "-o", "pid"]
p = get_test_subprocess(cmd, stdout=subprocess.PIPE)
output = p.communicate()[0].strip()
assert p.poll() == 0
if PY3:
output = str(output, sys.stdout.encoding)
pids_ps = []
Expand Down
8 changes: 3 additions & 5 deletions test/_sunos.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,16 @@
class SunOSSpecificTestCase(unittest.TestCase):

def test_swap_memory(self):
out = sh('env PATH=/usr/sbin:/sbin:%s swap -l -k' % os.environ['PATH'])
out = sh('env PATH=/usr/sbin:/sbin:%s swap -l' % os.environ['PATH'])
lines = out.strip().split('\n')[1:]
if not lines:
raise ValueError('no swap device(s) configured')
total = free = 0
for line in lines:
line = line.split()
t, f = line[-2:]
t = t.replace('K', '')
f = f.replace('K', '')
total += int(int(t) * 1024)
free += int(int(f) * 1024)
total += int(int(t) * 512)
free += int(int(f) * 512)
used = total - free

psutil_swap = psutil.swap_memory()
Expand Down
8 changes: 5 additions & 3 deletions test/test_psutil.py
Original file line number Diff line number Diff line change
Expand Up @@ -755,7 +755,7 @@ def test_cpu_count(self):
self.assertEqual(logical, len(psutil.cpu_times(percpu=True)))
self.assertGreaterEqual(logical, 1)
#
if LINUX:
if os.path.exists("/proc/cpuinfo"):
with open("/proc/cpuinfo") as fd:
cpuinfo_data = fd.read()
if "physical id" not in cpuinfo_data:
Expand Down Expand Up @@ -1385,7 +1385,8 @@ def test_create_time(self):
def test_terminal(self):
terminal = psutil.Process().terminal()
if sys.stdin.isatty():
self.assertEqual(terminal, sh('tty'))
tty = os.path.realpath(sh('tty'))
self.assertEqual(terminal, tty)
else:
assert terminal, repr(terminal)

Expand Down Expand Up @@ -1645,7 +1646,8 @@ def test_memory_maps(self):
if not nt.path.startswith('['):
assert os.path.isabs(nt.path), nt.path
if POSIX:
assert os.path.exists(nt.path), nt.path
assert os.path.exists(nt.path) or \
os.path.islink(nt.path), nt.path
else:
# XXX - On Windows we have this strange behavior with
# 64 bit dlls: they are visible via explorer but cannot
Expand Down

0 comments on commit 7ca207d

Please sign in to comment.