Bug 870575 - Upgrade psutil to 0.7.1; rs=me
authorGregory Szorc <gps@mozilla.com>
Thu, 09 May 2013 15:39:30 -0700
changeset 131391 3269501068511f667f681c91907902035a85ab6d
parent 131390 6c48ce88a31ad3476e3403008a02b589ac44e2ba
child 131392 bb26a100852a495d8b36aae91c560a48c88cf1c2
push id1602
push userryanvm@gmail.com
push dateFri, 10 May 2013 19:00:56 +0000
treeherderfx-team@7869de238133 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersme
bugs870575
milestone23.0a1
Bug 870575 - Upgrade psutil to 0.7.1; rs=me Archive obtained from https://psutil.googlecode.com/files/psutil-0.7.1.tar.gz and checked in with no modifications.
python/psutil/CREDITS
python/psutil/HISTORY
python/psutil/INSTALL
python/psutil/PKG-INFO
python/psutil/examples/disk_usage.py
python/psutil/examples/free.py
python/psutil/examples/iotop.py
python/psutil/examples/killall.py
python/psutil/examples/meminfo.py
python/psutil/examples/netstat.py
python/psutil/examples/nettop.py
python/psutil/examples/pmap.py
python/psutil/examples/process_detail.py
python/psutil/examples/top.py
python/psutil/examples/who.py
python/psutil/psutil/__init__.py
python/psutil/psutil/_common.py
python/psutil/psutil/_compat.py
python/psutil/psutil/_error.py
python/psutil/psutil/_psbsd.py
python/psutil/psutil/_pslinux.py
python/psutil/psutil/_psmswindows.py
python/psutil/psutil/_psosx.py
python/psutil/psutil/_psposix.py
python/psutil/psutil/_psutil_bsd.c
python/psutil/psutil/_psutil_bsd.h
python/psutil/psutil/_psutil_common.c
python/psutil/psutil/_psutil_common.h
python/psutil/psutil/_psutil_linux.c
python/psutil/psutil/_psutil_linux.h
python/psutil/psutil/_psutil_mswindows.c
python/psutil/psutil/_psutil_mswindows.h
python/psutil/psutil/_psutil_osx.c
python/psutil/psutil/_psutil_osx.h
python/psutil/psutil/_psutil_posix.c
python/psutil/psutil/_psutil_posix.h
python/psutil/psutil/arch/bsd/process_info.c
python/psutil/psutil/arch/bsd/process_info.h
python/psutil/psutil/arch/mswindows/ntextapi.h
python/psutil/psutil/arch/mswindows/process_handles.c
python/psutil/psutil/arch/mswindows/process_handles.h
python/psutil/psutil/arch/mswindows/process_info.c
python/psutil/psutil/arch/mswindows/process_info.h
python/psutil/psutil/arch/mswindows/security.c
python/psutil/psutil/arch/mswindows/security.h
python/psutil/psutil/arch/osx/process_info.c
python/psutil/psutil/arch/osx/process_info.h
python/psutil/psutil/error.py
python/psutil/setup.cfg
python/psutil/setup.py
python/psutil/test/_bsd.py
python/psutil/test/_linux.py
python/psutil/test/_osx.py
python/psutil/test/_posix.py
python/psutil/test/_windows.py
python/psutil/test/test_memory_leaks.py
python/psutil/test/test_psutil.py
--- a/python/psutil/CREDITS
+++ b/python/psutil/CREDITS
@@ -13,16 +13,17 @@ Really thanks to all of you.
 
 
 Maintainers
 ===========
 
 N: Giampaolo Rodola'
 C: Italy
 E: g.rodola@gmail.com
+W: http://www.linkedin.com/in/grodola
 
 N: Jay Loden
 C: NJ, USA
 E: jloden@gmail.com
 W: http://www.jayloden.com
 
 
 Contributors
@@ -73,17 +74,17 @@ E: sandro.tosi@gmail.com
 I: 200, 201
 
 N: Andrew Colin
 E: andrew.colin@gmail.com
 I: 248
 
 N: Amoser
 E: amoser@google.com
-I: 266, 267
+I: 266, 267, 340
 
 N: Matthew Grant
 E: matthewgrant5@gmail.com
 I: 271
 
 N: oweidner
 E: oweidner@cct.lsu.edu
 I: 275
@@ -112,8 +113,52 @@ I: 314
 N: Kim Gräsman
 E: kim.grasman@gmail.com
 D: ...also kindly donated some money.
 I: 316
 
 N: Riccardo Murri
 C: Italy
 I: 318
+
+N: Florent Xicluna
+E: florent.xicluna@gmail.com
+I: 319
+
+N: Michal Spondr
+E: michal.spondr
+I: 313
+
+N: Jean Sebastien
+E: dumbboules@gmail.com
+I: 344
+
+N: Rob Smith
+W: http://www.kormoc.com/
+I: 341
+
+N: Youngsik Kim
+W: https://plus.google.com/101320747613749824490/
+I: 317
+
+N: Gregory Szorc
+W: https://plus.google.com/116873264322260110710/posts
+I: 323
+
+N: André Oriani
+E: aoriani@gmail.com
+I: 361
+
+N: clackwell
+E: clackwell@gmail.com
+I: 356
+
+N: m.malycha
+E: m.malycha@gmail.com
+I: 351
+
+N: John Baldwin
+E: jhb@FreeBSD.org
+I: 370
+
+N: Jan Beich
+E: jbeich@tormail.org
+I: 325
--- a/python/psutil/HISTORY
+++ b/python/psutil/HISTORY
@@ -1,187 +1,261 @@
 Bug tracker at http://code.google.com/p/psutil/issues
 
+0.7.1 - 2013-05-03
+------------------
+
+BUG FIXES:
+
+ * #325: [BSD] psutil.virtual_memory() can raise SystemError.
+         (patch by Jan Beich)
+ * #370: [BSD] Process.get_connections() requires root.  (patch by John Baldwin)
+ * #372: [BSD] different process methods raise NoSuchProcess instead of
+         AccessDenied.
+
+
+0.7.0 - 2013-04-12
+------------------
+
+NEW FEATURES
+
+ * #233: code migrated to Mercurial (yay!)
+ * #246: psutil.error module is deprecated and scheduled for removal.
+ * #328: [Windows] process IO nice/priority support.
+ * #359: psutil.get_boot_time()
+ * #361: [Linux] psutil.cpu_times() now includes new 'steal', 'guest' and
+         'guest_nice' fields available on recent Linux kernels.
+         Also, psutil.cpu_percent() is more accurate.
+ * #362: cpu_times_percent() (per-CPU-time utilization as a percentage)
+
+BUG FIXES
+
+ * #234: [Windows] disk_io_counters() fails to list certain disks.
+ * #264: [Windows] use of psutil.disk_partitions() may cause a message box to
+         appear.
+ * #313: [Linux] psutil.virtual_memory() and psutil.swap_memory() can crash on
+         certain exotic Linux flavors having an incomplete /proc interface.
+         If that's the case we now set the unretrievable stats to 0 and raise a
+         RuntimeWarning.
+ * #315: [OSX] fix some compilation warnings.
+ * #317: [Windows] cannot set process CPU affinity above 31 cores.
+ * #319: [Linux] process get_memory_maps() raises KeyError 'Anonymous' on Debian
+         squeeze.
+ * #321: [UNIX] Process.ppid property is no longer cached as the kernel may set
+         the ppid to 1 in case of a zombie process.
+ * #323: [OSX] disk_io_counters()'s read_time and write_time parameters were
+         reporting microseconds not milliseconds.  (patch by Gregory Szorc)
+ * #331: Process cmdline is no longer cached after first acces as it may change.
+ * #333: [OSX] Leak of Mach ports on OS X (patch by rsesek@google.com)
+ * #337: [Linux] process methods not working because of a poor /proc
+         implementation will raise NotImplementedError rather than RuntimeError
+         and Process.as_dict() will not blow up.  (patch by Curtin1060)
+ * #338: [Linux] disk_io_counters() fails to find some disks.
+ * #339: [FreeBSD] get_pid_list() can allocate all the memory on system.
+ * #341: [Linux] psutil might crash on import due to error in retrieving system
+         terminals map.
+ * #344: [FreeBSD] swap_memory() might return incorrect results due to
+         kvm_open(3) not being called. (patch by Jean Sebastien)
+ * #338: [Linux] disk_io_counters() fails to find some disks.
+ * #351: [Windows] if psutil is compiled with mingw32 (provided installers for
+         py2.4 and py2.5 are) disk_io_counters() will fail. (Patch by m.malycha)
+ * #353: [OSX] get_users() returns an empty list on OSX 10.8.
+ * #356: Process.parent now checks whether parent PID has been reused in which
+         case returns None.
+ * #365: Process.set_nice() should check PID has not been reused by another
+         process.
+ * #366: [FreeBSD] get_memory_maps(), get_num_fds(), get_open_files() and
+         getcwd() Process methods raise RuntimeError instead of AccessDenied.
+
+API CHANGES
+
+ * Process.cmdline property is no longer cached after first access.
+ * Process.ppid property is no longer cached after first access.
+ * [Linux] Process methods not working because of a poor /proc implementation
+   will raise NotImplementedError instead of RuntimeError.
+ * psutil.error module is deprecated and scheduled for removal.
+
+
 0.6.1 - 2012-08-16
 ------------------
 
 NEW FEATURES
 
- * Issue 316: process cmdline property now makes a better job at guessing the
-   process executable from the cmdline.
+ * #316: process cmdline property now makes a better job at guessing the process
+         executable from the cmdline.
 
 BUG FIXES
 
- * Issue 316: process exe was resolved in case it was a symlink.
- * Issue 318: python 2.4 compatibility was broken.
+ * #316: process exe was resolved in case it was a symlink.
+ * #318: python 2.4 compatibility was broken.
 
 API CHANGES
 
  * process exe can now return an empty string instead of raising AccessDenied.
  * process exe is no longer resolved in case it's a symlink.
 
 
 0.6.0 - 2012-08-13
 ------------------
 
 NEW FEATURES
 
- * Issue 216: (UNIX) get_connections() UNIX sockets support.
- * Issue 220: (BSD) get_connections() has been rewritten in C and no longer
-   requires lsof.
- * Issue 222: (OSX) add support for process cwd.
- * Issue 261: process extended memory info.
- * Issue 295: (OSX) process executable path is now determined by asking the OS
-   instead of being guessed from process cmdline.
- * Issue 297: (OSX) the Process methods below were always raising AccessDenied
-   for any process except the current one. Now this is no longer true. Also they
-   are 2.5x faster.
-    - name
-    - get_memory_info()
-    - get_memory_percent()
-    - get_cpu_times()
-    - get_cpu_percent()
-    - get_num_threads()
- * Issue 300: examples/pmap.py script.
- * Issue 301: process_iter() now yields processes sorted by their PIDs.
- * Issue 302: process number of voluntary and involuntary context switches.
- * Issue 303: (Windows) the Process methods below were always raising
-   AccessDenied for any process not owned by current user. Now this is no longer
-   true:
-    - create_time
-    - get_cpu_times()
-    - get_cpu_percent()
-    - get_memory_info()
-    - get_memory_percent()
-    - get_num_handles()
-    - get_io_counters()
- * Issue 305: add examples/netstat.py script.
- * Issue 311: system memory functions has been refactorized and rewritten and
-   now provide a more detailed and consistent representation of the system
-   memory.
-   New psutil.virtual_memory() function provides the following memory amounts:
-    - total
-    - available
-    - percent
-    - used
-    - active (UNIX)
-    - inactive (UNIX)
-    - buffers (BSD, Linux)
-    - cached (BSD, OSX)
-    - wired (OSX, BSD)
-    - shared (BSD)
-   New psutil.swap_memory() provides:
-    - total
-    - used
-    - free
-    - percent
-    - sin (no. of bytes the system has swapped in from disk (cumulative))
-    - sout (no. of bytes the system has swapped out from disk (cumulative))
-   All old memory-related functions are deprecated.
-   Also two new example scripts were added:  free.py and meminfo.py.
- * Issue 312: psutil.network_io_counters() namedtuple includes 4 new fields:
-   errin, errout dropin and dropout, reflecting the number of packets dropped
-   and with errors.
+ * #216: [POSIX] get_connections() UNIX sockets support.
+ * #220: [FreeBSD] get_connections() has been rewritten in C and no longer
+         requires lsof.
+ * #222: [OSX] add support for process cwd.
+ * #261: process extended memory info.
+ * #295: [OSX] process executable path is now determined by asking the OS
+         instead of being guessed from process cmdline.
+ * #297: [OSX] the Process methods below were always raising AccessDenied for
+         any process except the current one. Now this is no longer true. Also
+         they are 2.5x faster.
+           - name
+           - get_memory_info()
+           - get_memory_percent()
+           - get_cpu_times()
+           - get_cpu_percent()
+           - get_num_threads()
+ * #300: examples/pmap.py script.
+ * #301: process_iter() now yields processes sorted by their PIDs.
+ * #302: process number of voluntary and involuntary context switches.
+ * #303: [Windows] the Process methods below were always raising AccessDenied
+         for any process not owned by current user. Now this is no longer true:
+          - create_time
+          - get_cpu_times()
+          - get_cpu_percent()
+          - get_memory_info()
+          - get_memory_percent()
+          - get_num_handles()
+          - get_io_counters()
+ * #305: add examples/netstat.py script.
+ * #311: system memory functions has been refactorized and rewritten and now
+         provide a more detailed and consistent representation of the system
+         memory. New psutil.virtual_memory() function provides the following
+         memory amounts:
+          - total
+          - available
+          - percent
+          - used
+          - active [POSIX]
+          - inactive [POSIX]
+          - buffers (BSD, Linux)
+          - cached (BSD, OSX)
+          - wired (OSX, BSD)
+          - shared [FreeBSD]
+         New psutil.swap_memory() provides:
+          - total
+          - used
+          - free
+          - percent
+          - sin (no. of bytes the system has swapped in from disk (cumulative))
+          - sout (no. of bytes the system has swapped out from disk (cumulative))
+         All old memory-related functions are deprecated.
+         Also two new example scripts were added:  free.py and meminfo.py.
+ * #312: psutil.network_io_counters() namedtuple includes 4 new fields:
+         errin, errout dropin and dropout, reflecting the number of packets
+         dropped and with errors.
 
 BUGFIXES
 
- * Issue 298: (OSX - BSD) memory leak in get_num_fds().
- * Issue 299: potential memory leak every time PyList_New(0) is used.
- * Issue 303: (Windows) potential heap corruption in get_num_threads() and
-   get_status() Process methods.
- * Issue 305: (BSD) psutil can't compile on FreeBSD 9 due to removal of utmp.h.
- * Issue 306: at C level, errors are not checked when invoking Py* functions
-   which create or manipulate Python objects leading to potential memory related
-   errors and/or segmentation faults.
- * Issue 307: (BSD) values returned by psutil.network_io_counters() are wrong.
- * Issue 308: (BSD / Windows) psutil.virtmem_usage() wasn't actually returning
-   information about swap memory usage as it was supposed to do. It does now.
- * Issue 309: get_open_files() might not return files which can not be accessed
-   due to limited permissions. AccessDenied is now raised instead.
+ * #298: [OSX and BSD] memory leak in get_num_fds().
+ * #299: potential memory leak every time PyList_New(0) is used.
+ * #303: [Windows] potential heap corruption in get_num_threads() and
+         get_status() Process methods.
+ * #305: [FreeBSD] psutil can't compile on FreeBSD 9 due to removal of utmp.h.
+ * #306: at C level, errors are not checked when invoking Py* functions which
+         create or manipulate Python objects leading to potential memory related
+         errors and/or segmentation faults.
+ * #307: [FreeBSD] values returned by psutil.network_io_counters() are wrong.
+ * #308: [BSD / Windows] psutil.virtmem_usage() wasn't actually returning
+         information about swap memory usage as it was supposed to do. It does
+         now.
+ * #309: get_open_files() might not return files which can not be accessed
+         due to limited permissions. AccessDenied is now raised instead.
 
 API CHANGES
 
  * psutil.phymem_usage() is deprecated             (use psutil.virtual_memory())
  * psutil.virtmem_usage() is deprecated            (use psutil.swap_memory())
  * psutil.phymem_buffers() on Linux is deprecated  (use psutil.virtual_memory())
  * psutil.cached_phymem() on Linux is deprecated   (use psutil.virtual_memory())
- * (Windows and BSD) psutil.virtmem_usage() now returns information about swap
+ * [Windows and BSD] psutil.virtmem_usage() now returns information about swap
    memory instead of virtual memory.
 
 
 0.5.1 - 2012-06-29
 ------------------
 
 NEW FEATURES
 
- * Issue 293: (Windows) process executable path is now determined by asking the
-   OS instead of being guessed from process cmdline.
+ * #293: [Windows] process executable path is now determined by asking the OS
+         instead of being guessed from process cmdline.
 
 BUGFIXES
 
- * Issue 292: (Linux) race condition in process files/threads/connections.
- * Issue 294: (Windows) Process CPU affinity is only able to set CPU #0.
+ * #292: [Linux] race condition in process files/threads/connections.
+ * #294: [Windows] Process CPU affinity is only able to set CPU #0.
 
 
 0.5.0 - 2012-06-27
 ------------------
 
 NEW FEATURES
 
- * Issue #195: (Windows) number of handles opened by process.
- * Issue #209: psutil.disk_partitions() now provides also mount options.
- * Issue #229: list users currently connected on the system (psutil.get_users()).
- * Issue #238: (Linux, Windows) process CPU affinity (get and set).
- * Issue #242: Process.get_children(recursive=True): return all process
-   descendants.
- * Issue #245: (POSIX) Process.wait() incrementally consumes less CPU cycles.
- * Issue #257: (Windows) removed Windows 2000 support.
- * Issue #258: (Linux) Process.get_memory_info() is now 0.5x faster.
- * Issue #260: process's mapped memory regions. (Windows patch by wj32.64, OSX
-   patch by Jeremy Whitlock)
- * Issue #262: (Windows) psutil.disk_partitions() was slow due to inspecting
-   the floppy disk drive also when "all" argument was False.
- * Issue #273: psutil.get_process_list() is deprecated.
- * Issue #274: psutil no longer requires 2to3 at installation time in order to
-   work with Python 3.
- * Issue #278: new Process.as_dict() method.
- * Issue #281: ppid, name, exe, cmdline and create_time properties of Process
-   class are now cached after being accessed.
- * Issue #282: psutil.STATUS_* constants can now be compared by using their
-   string representation.
- * Issue #283: speedup Process.is_running() by caching its return value in case
-   the process is terminated.
- * Issue #284: (POSIX) per-process number of opened file descriptors.
- * Issue #287: psutil.process_iter() now caches Process instances between calls.
- * Issue #290: Process.nice property is deprecated in favor of new get_nice()
-   and set_nice() methods.
+ * #195: [Windows] number of handles opened by process.
+ * #209: psutil.disk_partitions() now provides also mount options.
+ * #229: list users currently connected on the system (psutil.get_users()).
+ * #238: [Linux, Windows] process CPU affinity (get and set).
+ * #242: Process.get_children(recursive=True): return all process
+         descendants.
+ * #245: [POSIX] Process.wait() incrementally consumes less CPU cycles.
+ * #257: [Windows] removed Windows 2000 support.
+ * #258: [Linux] Process.get_memory_info() is now 0.5x faster.
+ * #260: process's mapped memory regions. (Windows patch by wj32.64, OSX patch
+         by Jeremy Whitlock)
+ * #262: [Windows] psutil.disk_partitions() was slow due to inspecting the
+         floppy disk drive also when "all" argument was False.
+ * #273: psutil.get_process_list() is deprecated.
+ * #274: psutil no longer requires 2to3 at installation time in order to work
+         with Python 3.
+ * #278: new Process.as_dict() method.
+ * #281: ppid, name, exe, cmdline and create_time properties of Process class
+         are now cached after being accessed.
+ * #282: psutil.STATUS_* constants can now be compared by using their string
+         representation.
+ * #283: speedup Process.is_running() by caching its return value in case the
+         process is terminated.
+ * #284: [POSIX] per-process number of opened file descriptors.
+ * #287: psutil.process_iter() now caches Process instances between calls.
+ * #290: Process.nice property is deprecated in favor of new get_nice() and
+         set_nice() methods.
 
 BUGFIXES
 
- * Issue #193: psutil.Popen constructor can throw an exception if the spawned
-   process terminates quickly.
- * Issue #240: (OSX) incorrect use of free() for Process.get_connections().
- * Issue #244: (POSIX) Process.wait() can hog CPU resources if called against
-   a process which is not our children.
- * Issue #248: (Linux) psutil.network_io_counters() might return erroneous NIC
-   names.
- * Issue #252: (Windows) process getcwd() erroneously raise NoSuchProcess for
-   processes owned by another user.  It now raises AccessDenied instead.
- * Issue #266: (Windows) psutil.get_pid_list() only shows 1024 processes.
-   (patch by Amoser)
- * Issue #267: (OSX) Process.get_connections() - an erroneous remote address
-   was returned. (Patch by Amoser)
- * Issue #272: (Linux) Porcess.get_open_files() - potential race condition can
-   lead to unexpected NoSuchProcess exception.  Also, we can get incorrect
-   reports of not absolutized path names.
- * Issue #275: (Linux) Process.get_io_counters() erroneously raise NoSuchProcess
-   on old Linux versions. Where not available it now raises NotImplementedError.
- * Issue #286: Process.is_running() doesn't actually check whether PID has been
-   reused.
- * Issue #314: Process.get_children() can sometimes return non-children.
+ * #193: psutil.Popen constructor can throw an exception if the spawned process
+         terminates quickly.
+ * #240: [OSX] incorrect use of free() for Process.get_connections().
+ * #244: [POSIX] Process.wait() can hog CPU resources if called against a
+         process which is not our children.
+ * #248: [Linux] psutil.network_io_counters() might return erroneous NIC names.
+ * #252: [Windows] process getcwd() erroneously raise NoSuchProcess for
+         processes owned by another user.  It now raises AccessDenied instead.
+ * #266: [Windows] psutil.get_pid_list() only shows 1024 processes.
+         (patch by Amoser)
+ * #267: [OSX] Process.get_connections() - an erroneous remote address was
+         returned. (Patch by Amoser)
+ * #272: [Linux] Porcess.get_open_files() - potential race condition can lead to
+         unexpected NoSuchProcess exception.  Also, we can get incorrect reports
+         of not absolutized path names.
+ * #275: [Linux] Process.get_io_counters() erroneously raise NoSuchProcess on
+         old Linux versions. Where not available it now raises
+         NotImplementedError.
+ * #286: Process.is_running() doesn't actually check whether PID has been
+         reused.
+ * #314: Process.get_children() can sometimes return non-children.
 
 API CHANGES
 
  * Process.nice property is deprecated in favor of new get_nice() and set_nice()
    methods.
  * psutil.get_process_list() is deprecated.
  * ppid, name, exe, cmdline and create_time properties of Process class are now
    cached after being accessed, meaning NoSuchProcess will no longer be raised
@@ -190,175 +264,174 @@ API CHANGES
    representation.
 
 
 0.4.1 - 2011-12-14
 ------------------
 
 BUGFIXES
 
- * Issue 228: some example scripts were not working with python 3.
- * Issue 230: (Windows / OSX) memory leak in Process.get_connections().
- * Issue 232: (Linux) psutil.phymem_usage() can report erroneous values which
-   are different than "free" command.
- * Issue 236: (Windows) memory/handle leak in Process's get_memory_info(),
-   suspend() and resume() methods.
+ * #228: some example scripts were not working with python 3.
+ * #230: [Windows / OSX] memory leak in Process.get_connections().
+ * #232: [Linux] psutil.phymem_usage() can report erroneous values which are
+         different than "free" command.
+ * #236: [Windows] memory/handle leak in Process's get_memory_info(),
+         suspend() and resume() methods.
 
 
 0.4.0 - 2011-10-29
 ------------------
 
 NEW FEATURES
 
- * Issue 150: network I/O counters. (OSX and Windows patch by Jeremy Whitlock)
- * Issue 154: (FreeBSD) add support for process getcwd()
- * Issue 157: (Windows) provide installer for Python 3.2 64-bit.
- * Issue 198: Process.wait(timeout=0) can now be used to make wait() return
-   immediately.
- * Issue 206: disk I/O counters. (OSX and Windows patch by Jeremy Whitlock)
- * Issue 213: examples/iotop.py script.
- * Issue 217: Process.get_connections() now has a "kind" argument to filter
+ * #150: network I/O counters. (OSX and Windows patch by Jeremy Whitlock)
+ * #154: [FreeBSD] add support for process getcwd()
+ * #157: [Windows] provide installer for Python 3.2 64-bit.
+ * #198: Process.wait(timeout=0) can now be used to make wait() return
+         immediately.
+ * #206: disk I/O counters. (OSX and Windows patch by Jeremy Whitlock)
+ * #213: examples/iotop.py script.
+ * #217: Process.get_connections() now has a "kind" argument to filter
    for connections with different criteria.
- * Issue 221: (FreeBSD) Process.get_open_files has been rewritten in C and no
-   longer relies on lsof.
- * Issue 223: examples/top.py script.
- * Issue 227: examples/nettop.py script.
+ * #221: [FreeBSD] Process.get_open_files has been rewritten in C and no longer
+   relies on lsof.
+ * #223: examples/top.py script.
+ * #227: examples/nettop.py script.
 
 BUGFIXES
 
- * Issue 135: (OS X) psutil cannot create Process object
- * Issue 144: (Linux) no longer support 0 special PID.
- * Issue 188: (Linux) psutil import error on Linux ARM architectures.
- * Issue 194: (POSIX) psutil.Process.get_cpu_percent() now reports a percentage
-   over 100 on multicore processors.
- * Issue 197: (Linux) Process.get_connections() is broken on platforms not
-   supporting IPv6.
- * Issue 200: (Linux) psutil.NUM_CPUS not working on armel and sparc
-   architectures and causing crash on module import.
- * Issue 201: (Linux) Process.get_connections() is broken on big-endian
-   architectures.
- * Issue 211: Process instance can unexpectedly raise NoSuchProcess if tested
-   for equality with another object.
- * Issue 218: (Linux) crash at import time on Debian 64-bit because of a missing
-   line in /proc/meminfo.
- * Issue 226: (FreeBSD) crash at import time on FreeBSD 7 and minor.
+ * #135: [OSX] psutil cannot create Process object.
+ * #144: [Linux] no longer support 0 special PID.
+ * #188: [Linux] psutil import error on Linux ARM architectures.
+ * #194: [POSIX] psutil.Process.get_cpu_percent() now reports a percentage over
+         100 on multicore processors.
+ * #197: [Linux] Process.get_connections() is broken on platforms not supporting
+         IPv6.
+ * #200: [Linux] psutil.NUM_CPUS not working on armel and sparc architectures
+         and causing crash on module import.
+ * #201: [Linux] Process.get_connections() is broken on big-endian
+          architectures.
+ * #211: Process instance can unexpectedly raise NoSuchProcess if tested for
+         equality with another object.
+ * #218: [Linux] crash at import time on Debian 64-bit because of a missing line
+         in /proc/meminfo.
+ * #226: [FreeBSD] crash at import time on FreeBSD 7 and minor.
 
 
 0.3.0 - 2011-07-08
 ------------------
 
 NEW FEATURES
 
- * Issue 125: system per-cpu percentage utilization and times.
- * Issue 163: per-process associated terminal (TTY).
- * Issue 171: added get_phymem() and get_virtmem() functions returning system
-   memory information (total, used, free) and memory percent usage.
-   total_* avail_* and used_* memory functions are deprecated.
- * Issue 172: disk usage statistics.
- * Issue 174: mounted disk partitions.
- * Issue 179: setuptools is now used in setup.py
+ * #125: system per-cpu percentage utilization and times.
+ * #163: per-process associated terminal (TTY).
+ * #171: added get_phymem() and get_virtmem() functions returning system
+         memory information (total, used, free) and memory percent usage.
+         total_* avail_* and used_* memory functions are deprecated.
+ * #172: disk usage statistics.
+ * #174: mounted disk partitions.
+ * #179: setuptools is now used in setup.py
 
 BUGFIXES
 
- * Issue 159: SetSeDebug() does not close handles or unset impersonation on
-   return.
- * Issue 164: wait function raises a TimeoutException when a process returns
-   -1 (Windows).
- * Issue 165: process.status raises an unhandled exception.
- * Issue 166: get_memory_info() leaks handles hogging system resources.
- * Issue 168: psutil.cpu_percent() returns erroneous results when used in
-   non-blocking mode.  (patch by Philip Roberts)
- * Issue 178: OSX - Process.get_threads() leaks memory
- * Issue 180: Windows - Process's get_num_threads() and get_threads() methods
-   can raise NoSuchProcess exception while process still exists.
+ * #159: SetSeDebug() does not close handles or unset impersonation on return.
+ * #164: [Windows] wait function raises a TimeoutException when a process
+         returns -1 .
+ * #165: process.status raises an unhandled exception.
+ * #166: get_memory_info() leaks handles hogging system resources.
+ * #168: psutil.cpu_percent() returns erroneous results when used in
+         non-blocking mode.  (patch by Philip Roberts)
+ * #178: OSX - Process.get_threads() leaks memory
+ * #180: [Windows] Process's get_num_threads() and get_threads() methods can
+         raise NoSuchProcess exception while process still exists.
 
 
 0.2.1 - 2011-03-20
 ------------------
 
 NEW FEATURES
 
- * Issue 64: per-process I/O counters.
- * Issue 116: per-process wait() (wait for process to terminate and return its
-   exit code).
- * Issue 134: per-process get_threads() returning information (id, user and
-   kernel times) about threads opened by process.
- * Issue 136: process executable path on FreeBSD is now determined by asking
-   the kernel instead of guessing it from cmdline[0].
- * Issue 137: per-process real, effective and saved user and group ids.
- * Issue 140: system boot time.
- * Issue 142: per-process get and set niceness (priority).
- * Issue 143: per-process status.
- * Issue 147: per-process I/O nice (priority) - Linux only.
- * Issue 148: psutil.Popen class which tidies up subprocess.Popen and
-   psutil.Process in a unique interface.
- * Issue 152: (OSX) get_process_open_files() implementation has been rewritten
-   in C and no longer relies on lsof resulting in a 3x speedup.
- * Issue 153: (OSX) get_process_connection() implementation has been rewritten
-   in C and no longer relies on lsof resulting in a 3x speedup.
+ * #64: per-process I/O counters.
+ * #116: per-process wait() (wait for process to terminate and return its exit
+         code).
+ * #134: per-process get_threads() returning information (id, user and kernel
+         times) about threads opened by process.
+ * #136: process executable path on FreeBSD is now determined by asking the
+         kernel instead of guessing it from cmdline[0].
+ * #137: per-process real, effective and saved user and group ids.
+ * #140: system boot time.
+ * #142: per-process get and set niceness (priority).
+ * #143: per-process status.
+ * #147: per-process I/O nice (priority) - Linux only.
+ * #148: psutil.Popen class which tidies up subprocess.Popen and psutil.Process
+         in a unique interface.
+ * #152: [OSX] get_process_open_files() implementation has been rewritten
+         in C and no longer relies on lsof resulting in a 3x speedup.
+ * #153: [OSX] get_process_connection() implementation has been rewritten
+         in C and no longer relies on lsof resulting in a 3x speedup.
 
 BUGFIXES
 
- * Issue 83: process cmdline is empty on OSX 64-bit.
- * Issue 130: a race condition can cause IOError exception be raised on
-   Linux if process disappears between open() and subsequent read() calls.
- * Issue 145: WindowsError was raised instead of psutil.AccessDenied when using
-   process resume() or suspend() on Windows.
- * Issue 146: 'exe' property on Linux can raise TypeError if path contains NULL
-   bytes.
- * Issue 151: exe and getcwd() for PID 0 on Linux return inconsistent data.
+ * #83:  process cmdline is empty on OSX 64-bit.
+ * #130: a race condition can cause IOError exception be raised on
+         Linux if process disappears between open() and subsequent read() calls.
+ * #145: WindowsError was raised instead of psutil.AccessDenied when using
+         process resume() or suspend() on Windows.
+ * #146: 'exe' property on Linux can raise TypeError if path contains NULL
+         bytes.
+ * #151: exe and getcwd() for PID 0 on Linux return inconsistent data.
 
 API CHANGES
 
  * Process "uid" and "gid" properties are deprecated in favor of "uids" and
    "gids" properties.
 
 
 0.2.0 - 2010-11-13
 ------------------
 
 NEW FEATURES
 
- * Issue 79: per-process open files.
- * Issue 88: total system physical cached memory.
- * Issue 88: total system physical memory buffers used by the kernel.
- * Issue 91: per-process send_signal() and terminate() methods.
- * Issue 95: NoSuchProcess and AccessDenied exception classes now provide "pid",
-   "name" and "msg" attributes.
- * Issue 97: per-process children.
- * Issue 98: Process.get_cpu_times() and Process.get_memory_info now return
-   a namedtuple instead of a tuple.
- * Issue 103: per-process opened TCP and UDP connections.
- * Issue 107: add support for Windows 64 bit. (patch by cjgohlke)
- * Issue 111: per-process executable name.
- * Issue 113: exception messages now include process name and pid.
- * Issue 114: process username Windows implementation has been rewritten in pure
-   C and no longer uses WMI resulting in a big speedup. Also, pywin32 is no
-   longer required as a third-party dependancy. (patch by wj32)
- * Issue 117: added support for Windows 2000.
- * Issue 123: psutil.cpu_percent() and psutil.Process.cpu_percent() accept a
-   new 'interval' parameter.
- * Issue 129: per-process number of threads.
+ * #79: per-process open files.
+ * #88: total system physical cached memory.
+ * #88: total system physical memory buffers used by the kernel.
+ * #91: per-process send_signal() and terminate() methods.
+ * #95: NoSuchProcess and AccessDenied exception classes now provide "pid",
+        "name" and "msg" attributes.
+ * #97: per-process children.
+ * #98: Process.get_cpu_times() and Process.get_memory_info now return
+        a namedtuple instead of a tuple.
+ * #103: per-process opened TCP and UDP connections.
+ * #107: add support for Windows 64 bit. (patch by cjgohlke)
+ * #111: per-process executable name.
+ * #113: exception messages now include process name and pid.
+ * #114: process username Windows implementation has been rewritten in pure
+         C and no longer uses WMI resulting in a big speedup. Also, pywin32 is no
+         longer required as a third-party dependancy. (patch by wj32)
+ * #117: added support for Windows 2000.
+ * #123: psutil.cpu_percent() and psutil.Process.cpu_percent() accept a
+         new 'interval' parameter.
+ * #129: per-process number of threads.
 
 BUGFIXES
 
- * Issue 80: fixed warnings when installing psutil with easy_install.
- * Issue 81: psutil fails to compile with Visual Studio.
- * Issue 94: suspend() raises OSError instead of AccessDenied.
- * Issue 86: psutil didn't compile against FreeBSD 6.x.
- * Issue 102: orphaned process handles obtained by using OpenProcess in C were
-   left behind every time Process class was instantiated.
- * Issue 111: path and name Process properties report truncated or erroneous
-   values on UNIX.
- * Issue 120: cpu_percent() always returning 100% on OS X.
- * Issue 112: uid and gid properties don't change if process changes effective
-   user/group id at some point.
- * Issue 126: ppid, uid, gid, name, exe, cmdline and create_time properties are
-   no longer cached and correctly raise NoSuchProcess exception if the process
-   disappears.
+ * #80: fixed warnings when installing psutil with easy_install.
+ * #81: psutil fails to compile with Visual Studio.
+ * #94: suspend() raises OSError instead of AccessDenied.
+ * #86: psutil didn't compile against FreeBSD 6.x.
+ * #102: orphaned process handles obtained by using OpenProcess in C were
+         left behind every time Process class was instantiated.
+ * #111: path and name Process properties report truncated or erroneous
+         values on UNIX.
+ * #120: cpu_percent() always returning 100% on OS X.
+ * #112: uid and gid properties don't change if process changes effective
+         user/group id at some point.
+ * #126: ppid, uid, gid, name, exe, cmdline and create_time properties are
+         no longer cached and correctly raise NoSuchProcess exception if the process
+         disappears.
 
 API CHANGES
 
  * psutil.Process.path property is deprecated and works as an alias for "exe"
    property.
  * psutil.Process.kill(): signal argument was removed - to send a signal to the
    process use send_signal(signal) method instead.
  * psutil.Process.get_memory_info() returns a nametuple instead of a tuple.
@@ -372,92 +445,93 @@ API CHANGES
    immediately by default (see issue 123).
 
 
 0.1.3 - 2010-03-02
 ------------------
 
 NEW FEATURES
 
- * Issue 14: per-process username
- * Issue 51: per-process current working directory (Windows and Linux only)
- * Issue 59: Process.is_running() is now 10 times faster
- * Issue 61: added supoprt for FreeBSD 64 bit
- * Issue 71: implemented suspend/resume process
- * Issue 75: python 3 support
+ * #14: per-process username
+ * #51: per-process current working directory (Windows and Linux only)
+ * #59: Process.is_running() is now 10 times faster
+ * #61: added supoprt for FreeBSD 64 bit
+ * #71: implemented suspend/resume process
+ * #75: python 3 support
 
 BUGFIXES
 
- * Issue 36: process cpu_times() and memory_info() functions succeeded also for
-   dead processes while a NoSuchProcess exception is supposed to be raised.
- * Issue 48: incorrect size for mib array defined in getcmdargs for BSD
- * Issue 49: possible memory leak due to missing free() on error condition on
- * Issue 50: fixed getcmdargs() memory fragmentation on BSD
- * Issue 55: test_pid_4 was failing on Windows Vista
- * Issue 57: some unit tests were failing on systems where no swap memory is
-   available
- * Issue 58: is_running() is now called before kill() to make sure we are going
-   to kill the correct process.
- * Issue 73: virtual memory size reported on OS X includes shared library size
- * Issue 77: NoSuchProcess wasn't raised on Process.create_time if kill() was
-   used first.
+ * #36: process cpu_times() and memory_info() functions succeeded also for
+        dead processes while a NoSuchProcess exception is supposed to be raised.
+ * #48: incorrect size for mib array defined in getcmdargs for BSD
+ * #49: possible memory leak due to missing free() on error condition on
+ * #50: fixed getcmdargs() memory fragmentation on BSD
+ * #55: test_pid_4 was failing on Windows Vista
+ * #57: some unit tests were failing on systems where no swap memory is
+        available
+ * #58: is_running() is now called before kill() to make sure we are going
+        to kill the correct process.
+ * #73: virtual memory size reported on OS X includes shared library size
+ * #77: NoSuchProcess wasn't raised on Process.create_time if kill() was
+        used first.
 
 
 0.1.2 - 2009-05-06
 ------------------
 
 NEW FEATURES
 
- * Issue 32: Per-process CPU user/kernel times
- * Issue 33: Process create time
- * Issue 34: Per-process CPU utilization percentage
- * Issue 38: Per-process memory usage (bytes)
- * Issue 41: Per-process memory utilization (percent)
- * Issue 39: System uptime
- * Issue 43: Total system virtual memory
- * Issue 46: Total system physical memory
- * Issue 44: Total system used/free virtual and physical memory
+ * #32: Per-process CPU user/kernel times
+ * #33: Process create time
+ * #34: Per-process CPU utilization percentage
+ * #38: Per-process memory usage (bytes)
+ * #41: Per-process memory utilization (percent)
+ * #39: System uptime
+ * #43: Total system virtual memory
+ * #46: Total system physical memory
+ * #44: Total system used/free virtual and physical memory
 
 BUGFIXES
 
- * Issue 36: NoSuchProcess not raised on Windows when accessing timing methods
- * Issue 40: test_get_cpu_times() failing on FreeBSD and OS X
- * Issue 42: get_memory_percent() raises AccessDenied on Windows
+ * #36: [Windows] NoSuchProcess not raised when accessing timing methods.
+ * #40: test_get_cpu_times() failing on FreeBSD and OS X.
+ * #42: [Windows] get_memory_percent() raises AccessDenied.
 
 
 0.1.1 - 2009-03-06
 ------------------
 
 NEW FEATURES
 
- * Issue 4: FreeBSD support for all functions of psutil
- * Issue 9: Process.uid and Process.gid now retrieve process UID and GID.
- * Issue 11: Support for parent/ppid - Process.parent property returns a
-   Process object representing the parent process, and Process.ppid returns
-   the parent PID.
- * Issue 12 & 15: NoSuchProcess exception now raised when creating an object
-   for a nonexistent process, or when retrieving information about a process
-   that has gone away.
- * Issue 21: AccessDenied exception created for raising access denied errors
-   from OSError or WindowsError on individual platforms.
- * Issue 26: psutil.process_iter() function to iterate over processes as
-   Process objects with a generator.
- * Process objects can now also be compared with == operator for equality
-   (PID, name, command line are compared).
+ * #4: FreeBSD support for all functions of psutil
+ * #9: Process.uid and Process.gid now retrieve process UID and GID.
+ * #11: Support for parent/ppid - Process.parent property returns a
+        Process object representing the parent process, and Process.ppid returns
+        the parent PID.
+ * #12 & 15:
+        NoSuchProcess exception now raised when creating an object
+        for a nonexistent process, or when retrieving information about a process
+        that has gone away.
+ * #21: AccessDenied exception created for raising access denied errors
+        from OSError or WindowsError on individual platforms.
+ * #26: psutil.process_iter() function to iterate over processes as
+        Process objects with a generator.
+ * #?:  Process objects can now also be compared with == operator for equality
+        (PID, name, command line are compared).
 
 BUGFIXES
 
- * Issue 16: Special case for Windows' "System Idle Process" (PID 0) which
-   otherwise would return an "invalid parameter" exception.
- * Issue 17: get_process_list() ignores NoSuchProcess and AccessDenied
-   exceptions during building of the list.
- * Issue 22: Process(0).kill() was failing on Windows with an unset exception
- * Issue 23: Special case for pid_exists(0)
- * Issue 24: Process(0).kill() now raises AccessDenied exception instead of
-   WindowsError.
- * Issue 30: psutil.get_pid_list() was returning two instances of PID 0 on OS
-   X and FreeBSD platforms.
+ * #16: [Windows] Special case for "System Idle Process" (PID 0) which
+        otherwise would return an "invalid parameter" exception.
+ * #17: get_process_list() ignores NoSuchProcess and AccessDenied
+        exceptions during building of the list.
+ * #22: [Windows] Process(0).kill() was failing with an unset exception.
+ * #23: Special case for pid_exists(0)
+ * #24: [Windows] Process(0).kill() now raises AccessDenied exception instead of
+        WindowsError.
+ * #30: psutil.get_pid_list() was returning two instances of PID 0 on OS
+        X and FreeBSD platforms.
 
 
 0.1.0 - 2009-01-27
 ------------------
 
  * Initial release.
deleted file mode 100644
--- a/python/psutil/INSTALL
+++ /dev/null
@@ -1,110 +0,0 @@
-==================
-Using easy_install
-==================
-
-The easiest way to install psutil from sources is using easy_install.
-Get the latest easy_install version from http://pypi.python.org/pypi/setuptools
-and just run:
-
-    easy_install psutil
-
-This should get the most updated psutil version from the Python pypi repository,
-unpack it, compile it and install it automatically.
-
-
-===================================
-Installing on Windows using mingw32
-===================================
-
-After the mingw [1] environment is properly set up on your system you can
-compile Windows sources by entering:
-
-    setup.py build -c mingw32
-
-To compile and install just append the "install" keyword at the end of the
-command line above, like this:
-
-    setup.py build -c mingw32 install
-
-It might be possible that distutils will complain about missing gcc executable.
-That means you have to add mingw bin PATH variable first.
-Entering this line in the command prompt should do the work:
-
-    SET PATH=C:\MinGW\bin;%PATH%
-
-NOTE: this assumes MinGW is installed in C:\MinGW, if not simply replace the
-path in the command above with an appropriate location.
-
-[1] http://www.mingw.org/
-
-
-=========================================
-Installing on Windows using Visual Studio
-=========================================
-
-To use Visual Studio to install psutil, you must have the same version of
-Visual Studio used to compile your installation of Python. For older versions
-of Python that will be Visual Studio 2003. For 2.6 and later it should be
-Visual Studio 2008. If you do not have the requisite version of Visual Studio
-available then it is recommended to use MinGW to compile psutil instead.
-If you do have Visual Studio installed, you can use the basic distutils
-commands:
-
-     setup.py build
-
-...or to install and build:
-
-     setup.py install
-
-distutils should take care of any necessary magic to compile from there.
-
-
-==================
-Installing on OS X
-==================
-
-OS X installation from source will require gcc which you can obtain as part of
-the 'XcodeTools' installer from Apple. Then you can run the standard distutils
-commands.
-To build only:
-
-     python setup.py build
-
-To install and build:
-
-     python setup.py install
-
-NOTE: due to developer's hardware limitations psutil has only been compiled and
-tested on OS X 10.4.11 so may or may not work on other versions.
-
-
-=====================
-Installing on FreeBSD
-=====================
-
-The same compiler used to install Python must be present on the system in order
-to build modules using distutils. Assuming it is installed, you can build using
-the standard distutils commands.
-
-Build only:
-
-     python setup.py build
-
-Install and build:
-
-     python setup.py install
-
-
-===================
-Installing on Linux
-===================
-
-gcc is required and so the python headers. They can easily be installed by using
-the distro package manager. For example, on Ubuntu:
-
-     sudo apt-get install python-dev
-
-Once done, you can install/build psutil with:
-
-     python setup.py install
-
--- a/python/psutil/PKG-INFO
+++ b/python/psutil/PKG-INFO
@@ -1,17 +1,17 @@
 Metadata-Version: 1.1
 Name: psutil
-Version: 0.6.1
+Version: 0.7.1
 Summary: A process and system utilities module for Python
 Home-page: http://code.google.com/p/psutil/
 Author: Giampaolo Rodola
 Author-email: g.rodola <at> gmail <dot> com
 License: License :: OSI Approved :: BSD License
-Download-URL: http://psutil.googlecode.com/files/psutil-0.6.1.tar.gz
+Download-URL: http://psutil.googlecode.com/files/psutil-0.7.1.tar.gz
 Description: ===========
         Quick links
         ===========
         
         * `Home page <http://code.google.com/p/psutil>`_
         * `Download <http://code.google.com/p/psutil/downloads/list>`_
         * `Documentation <http://code.google.com/p/psutil/wiki/Documentation>`_
         
@@ -233,16 +233,17 @@ Classifier: Programming Language :: Pyth
 Classifier: Programming Language :: Python :: 2.4
 Classifier: Programming Language :: Python :: 2.5
 Classifier: Programming Language :: Python :: 2.6
 Classifier: Programming Language :: Python :: 2.7
 Classifier: Programming Language :: Python :: 3
 Classifier: Programming Language :: Python :: 3.0
 Classifier: Programming Language :: Python :: 3.1
 Classifier: Programming Language :: Python :: 3.2
+Classifier: Programming Language :: Python :: 3.3
 Classifier: Topic :: System :: Monitoring
 Classifier: Topic :: System :: Networking
 Classifier: Topic :: System :: Networking :: Monitoring
 Classifier: Topic :: System :: Benchmark
 Classifier: Topic :: System :: Hardware
 Classifier: Topic :: System :: Systems Administration
 Classifier: Topic :: Utilities
 Classifier: Topic :: Software Development :: Libraries
old mode 100644
new mode 100755
--- a/python/psutil/examples/disk_usage.py
+++ b/python/psutil/examples/disk_usage.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: disk_usage.py 1340 2012-06-09 13:42:21Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """
 List all mounted disk partitions a-la "df -h" command.
 """
 
old mode 100644
new mode 100755
--- a/python/psutil/examples/free.py
+++ b/python/psutil/examples/free.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: free.py 1508 2012-08-13 12:30:07Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """
 A clone of 'free' cmdline utility.
 """
 
old mode 100644
new mode 100755
--- a/python/psutil/examples/iotop.py
+++ b/python/psutil/examples/iotop.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: iotop.py 1236 2011-12-13 19:00:35Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """
 A clone of iotop (http://guichaz.free.fr/iotop/) showing real time
 disk I/O statistics.
 
old mode 100644
new mode 100755
--- a/python/psutil/examples/killall.py
+++ b/python/psutil/examples/killall.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: killall.py 1143 2011-10-05 19:11:59Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """
 Kill a process by name.
 """
 
old mode 100644
new mode 100755
--- a/python/psutil/examples/meminfo.py
+++ b/python/psutil/examples/meminfo.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: meminfo.py 1509 2012-08-13 12:31:18Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """
 Print system memory information.
 """
 
old mode 100644
new mode 100755
--- a/python/psutil/examples/netstat.py
+++ b/python/psutil/examples/netstat.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: netstat.py 1457 2012-07-14 18:09:36Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """
 A clone of 'netstat'.
 """
 
old mode 100644
new mode 100755
old mode 100644
new mode 100755
--- a/python/psutil/examples/pmap.py
+++ b/python/psutil/examples/pmap.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: pmap.py 1420 2012-07-08 12:12:01Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """
 A clone of 'pmap' utility on Linux, 'vmmap' on OSX and 'procstat -v' on BSD.
 Report memory map of a process.
 """
old mode 100644
new mode 100755
--- a/python/psutil/examples/process_detail.py
+++ b/python/psutil/examples/process_detail.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: process_detail.py 1498 2012-07-24 21:41:28Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """
 Print detailed information about a process.
 
 Author: Giampaolo Rodola' <g.rodola@gmail.com>
old mode 100644
new mode 100755
--- a/python/psutil/examples/top.py
+++ b/python/psutil/examples/top.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: top.py 1498 2012-07-24 21:41:28Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """
 A clone of top / htop.
 
 Author: Giampaolo Rodola' <g.rodola@gmail.com>
old mode 100644
new mode 100755
--- a/python/psutil/examples/who.py
+++ b/python/psutil/examples/who.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: who.py 1340 2012-06-09 13:42:21Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """
 A clone of 'who' command; print information about users who are
 currently logged in.
 """
--- a/python/psutil/psutil/__init__.py
+++ b/python/psutil/psutil/__init__.py
@@ -1,60 +1,61 @@
 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
-#
-# $Id: __init__.py 1525 2012-08-16 16:32:03Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """psutil is a module providing convenience functions for managing
 processes and gather system information in a portable way by using
 Python.
 """
 
 from __future__ import division
 
-__version__ = "0.6.1"
+__version__ = "0.7.1"
 version_info = tuple([int(num) for num in __version__.split('.')])
 
 __all__ = [
     # exceptions
     "Error", "NoSuchProcess", "AccessDenied", "TimeoutExpired",
     # constants
     "NUM_CPUS", "TOTAL_PHYMEM", "BOOT_TIME",
     "version_info", "__version__",
     "STATUS_RUNNING", "STATUS_IDLE", "STATUS_SLEEPING", "STATUS_DISK_SLEEP",
     "STATUS_STOPPED", "STATUS_TRACING_STOP", "STATUS_ZOMBIE", "STATUS_DEAD",
     "STATUS_WAKING", "STATUS_LOCKED",
     # classes
     "Process", "Popen",
     # functions
-    "test", "pid_exists", "get_pid_list", "process_iter", "get_process_list",
-    "virtual_memory", "swap_memory",
-    "cpu_times", "cpu_percent", "per_cpu_percent",
-    "network_io_counters", "disk_io_counters",
+    "pid_exists", "get_pid_list", "process_iter",                   # proc
+    "virtual_memory", "swap_memory",                                # memory
+    "cpu_times", "cpu_percent", "cpu_times_percent",                # cpu
+    "network_io_counters",                                          # network
+    "disk_io_counters", "disk_partitions", "disk_usage",            # disk
+    "get_users", "get_boot_time",                                   # others
     ]
 
 import sys
 import os
 import time
 import signal
 import warnings
 import errno
 import subprocess
 try:
     import pwd
 except ImportError:
     pwd = None
 
-from psutil.error import Error, NoSuchProcess, AccessDenied, TimeoutExpired
-from psutil._compat import property, callable, defaultdict
+from psutil._error import Error, NoSuchProcess, AccessDenied, TimeoutExpired
 from psutil._common import cached_property
+from psutil._compat import (property, callable, defaultdict, namedtuple,
+                            wraps as _wraps, PY3 as _PY3)
 from psutil._common import (deprecated as _deprecated,
                             nt_disk_iostat as _nt_disk_iostat,
                             nt_net_iostat as _nt_net_iostat,
                             nt_sysmeminfo as _nt_sysmeminfo,
                             isfile_strict as _isfile_strict)
 from psutil._common import (STATUS_RUNNING, STATUS_IDLE, STATUS_SLEEPING,
                             STATUS_DISK_SLEEP, STATUS_STOPPED,
                             STATUS_TRACING_STOP, STATUS_ZOMBIE, STATUS_DEAD,
@@ -92,25 +93,66 @@ else:
 
 __all__.extend(_psplatform.__extra__all__)
 
 NUM_CPUS = _psplatform.NUM_CPUS
 BOOT_TIME = _psplatform.BOOT_TIME
 TOTAL_PHYMEM = _psplatform.TOTAL_PHYMEM
 
 
+def _assert_pid_not_reused(fun):
+    """Decorator which raises NoSuchProcess in case a process is no
+    longer running or its PID has been reused.
+    """
+    @_wraps(fun)
+    def wrapper(self, *args, **kwargs):
+        if not self.is_running():
+            raise NoSuchProcess(self.pid, self._platform_impl._process_name)
+        return fun(self, *args, **kwargs)
+    return wrapper
+
+
 class Process(object):
     """Represents an OS process."""
 
     def __init__(self, pid):
         """Create a new Process object for the given pid.
         Raises NoSuchProcess if pid does not exist.
+
+        Note that most of the methods of this class do not make sure
+        the PID of the process being queried has been reused.
+        That means you might end up retrieving an information referring
+        to another process in case the original one this instance
+        refers to is gone in the meantime.
+
+        The only exceptions for which process identity is pre-emptively
+        checked are:
+         - parent
+         - get_children()
+         - set_nice()
+         - suspend()
+         - resume()
+         - send_signal()
+         - terminate()
+         - kill()
+
+        To prevent this problem for all other methods you can:
+          - use is_running() before querying the process
+          - if you're continuously iterating over a set of Process
+            instances use process_iter() which pre-emptively checks
+            process identity for every yielded instance
         """
+        if not _PY3:
+            if not isinstance(pid, (int, long)):
+                raise TypeError('pid must be an integer')
+        if pid < 0:
+            raise ValueError('pid must be a positive integer')
         self._pid = pid
         self._gone = False
+        self._ppid = None
         # platform-specific modules define an _psplatform.Process
         # implementation class
         self._platform_impl = _psplatform.Process(pid)
         self._last_sys_cpu_times = None
         self._last_proc_cpu_times = None
         # cache creation time for later use in is_running() method
         try:
             self.create_time
@@ -130,16 +172,18 @@ class Process(object):
         else:
             details = "(pid=%s, name=%s)" % (pid, name)
         return "%s.%s%s" % (self.__class__.__module__,
                             self.__class__.__name__, details)
 
     def __repr__(self):
         return "<%s at %s>" % (self.__str__(), id(self))
 
+    # --- utility methods
+
     def as_dict(self, attrs=[], ad_value=None):
         """Utility method returning process information as a hashable
         dictionary.
 
         If 'attrs' is specified it must be a list of strings reflecting
         available Process class's attribute names (e.g. ['get_cpu_times',
         'name']) else all public (read only) attributes are assumed.
 
@@ -180,36 +224,55 @@ class Process(object):
                 if name[3] == '_':
                     name = name[4:]
                 elif name == 'getcwd':
                     name = 'cwd'
             retdict[name] = ret
         return retdict
 
     @property
+    @_assert_pid_not_reused
+    def parent(self):
+        """Return the parent process as a Process object pre-emptively
+        checking whether PID has been reused.
+        If no parent is known return None.
+        """
+        ppid = self.ppid
+        if ppid is not None:
+            try:
+                parent = Process(ppid)
+                if parent.create_time <= self.create_time:
+                    return parent
+                # ...else ppid has been reused by another process
+            except NoSuchProcess:
+                pass
+
+    # --- actual API
+
+    @property
     def pid(self):
         """The process pid."""
         return self._pid
 
-    @cached_property
+    @property
     def ppid(self):
         """The process parent pid."""
-        return self._platform_impl.get_process_ppid()
+        # On POSIX we don't want to cache the ppid as it may unexpectedly
+        # change to 1 (init) in case this process turns into a zombie:
+        # https://code.google.com/p/psutil/issues/detail?id=321
+        # http://stackoverflow.com/questions/356722/
 
-    @property
-    def parent(self):
-        """Return the parent process as a Process object. If no parent
-        pid is known return None.
-        """
-        ppid = self.ppid
-        if ppid is not None:
-            try:
-                return Process(ppid)
-            except NoSuchProcess:
-                pass
+        # XXX should we check creation time here rather than in
+        # Process.parent?
+        if os.name == 'posix':
+            return self._platform_impl.get_process_ppid()
+        else:
+            if self._ppid is None:
+                self._ppid = self._platform_impl.get_process_ppid()
+            return self._ppid
 
     @cached_property
     def name(self):
         """The process name."""
         name = self._platform_impl.get_process_name()
         if os.name == 'posix':
             # On UNIX the name gets truncated to the first 15 characters.
             # If it matches the first part of the cmdline we return that
@@ -256,17 +319,17 @@ class Process(object):
                 # empty string; if that's the case we don't want to
                 # raise AD while guessing from the cmdline
                 try:
                     exe = guess_it(fallback=exe)
                 except AccessDenied:
                     pass
             return exe
 
-    @cached_property
+    @property
     def cmdline(self):
         """The command line process has been called with."""
         return self._platform_impl.get_process_cmdline()
 
     @property
     def status(self):
         """The process current status as a STATUS_* constant."""
         return self._platform_impl.get_process_status()
@@ -329,32 +392,47 @@ class Process(object):
             bytes read and written by the process.
             """
             return self._platform_impl.get_process_io_counters()
 
     def get_nice(self):
         """Get process niceness (priority)."""
         return self._platform_impl.get_process_nice()
 
+    @_assert_pid_not_reused
     def set_nice(self, value):
-        """Set process niceness (priority)."""
+        """Set process niceness (priority) pre-emptively checking
+        whether PID has been reused."""
         return self._platform_impl.set_process_nice(value)
 
-    # available only on Linux
+    # available only on Linux and Windows >= Vista
     if hasattr(_psplatform.Process, "get_process_ionice"):
 
         def get_ionice(self):
-            """Return process I/O niceness (priority) as a namedtuple."""
+            """Return process I/O niceness (priority).
+
+            On Linux this is a (ioclass, value) namedtuple.
+            On Windows it's an integer which can be equal to 2 (normal),
+            1 (low) or 0 (very low).
+
+            Available on Linux and Windows > Vista only.
+            """
             return self._platform_impl.get_process_ionice()
 
         def set_ionice(self, ioclass, value=None):
             """Set process I/O niceness (priority).
-            ioclass is one of the IOPRIO_CLASS_* constants.
-            iodata is a number which goes from 0 to 7. The higher the
+
+            On Linux 'ioclass' is one of the IOPRIO_CLASS_* constants.
+            'value' is a number which goes from 0 to 7. The higher the
             value, the lower the I/O priority of the process.
+
+            On Windows only 'ioclass' is used and it can be set to 2
+            (normal), 1 (low) or 0 (very low).
+
+            Available on Linux and Windows > Vista only.
             """
             return self._platform_impl.set_process_ionice(ioclass, value)
 
     # available on Windows and Linux only
     if hasattr(_psplatform.Process, "get_process_cpu_affinity"):
 
         def get_cpu_affinity(self):
             """Get process current CPU affinity."""
@@ -394,19 +472,20 @@ class Process(object):
         return self._platform_impl.get_process_num_threads()
 
     def get_threads(self):
         """Return threads opened by process as a list of namedtuples
         including thread id and thread CPU times (user/system).
         """
         return self._platform_impl.get_process_threads()
 
+    @_assert_pid_not_reused
     def get_children(self, recursive=False):
         """Return the children of this process as a list of Process
-        objects.
+        objects pre-emptively checking whether PID has been reused.
         If recursive is True return all the parent descendants.
 
         Example (A == this process):
 
          A ─┐

             ├─ B (child) ─┐
             │             └─ X (grandchild) ─┐
@@ -418,20 +497,16 @@ class Process(object):
         B, C, D
         >>> p.get_children(recursive=True)
         B, X, Y, C, D
 
         Note that in the example above if process X disappears
         process Y won't be returned either as the reference to
         process A is lost.
         """
-        if not self.is_running():
-            name = self._platform_impl._process_name
-            raise NoSuchProcess(self.pid, name)
-
         ret = []
         if not recursive:
             for p in process_iter():
                 try:
                     if p.ppid == self.pid:
                         # if child happens to be older than its parent
                         # (self) it means child's PID has been reused
                         if self.create_time <= p.create_time:
@@ -469,20 +544,32 @@ class Process(object):
 
     def get_cpu_percent(self, interval=0.1):
         """Return a float representing the current process CPU
         utilization as a percentage.
 
         When interval is > 0.0 compares process times to system CPU
         times elapsed before and after the interval (blocking).
 
-        When interval is 0.0 or None compares process times to system CPU
-        times elapsed since last call, returning immediately.
-        In this case is recommended for accuracy that this function be
-        called with at least 0.1 seconds between calls.
+        When interval is 0.0 or None compares process times to system
+        CPU times elapsed since last call, returning immediately
+        (non-blocking).
+        In this case is recommended for accuracy that this function
+        be called with at least 0.1 seconds between calls.
+
+        Examples:
+
+          >>> p = psutil.Process(os.getpid())
+          >>> # blocking
+          >>> p.get_cpu_percent(interval=1)
+          2.0
+          >>> # non-blocking (percentage since last call)
+          >>> p.get_cpu_percent(interval=0)
+          2.9
+          >>>
         """
         blocking = interval is not None and interval > 0.0
         if blocking:
             st1 = sum(cpu_times())
             pt1 = self._platform_impl.get_cpu_times()
             time.sleep(interval)
             st2 = sum(cpu_times())
             pt2 = self._platform_impl.get_cpu_times()
@@ -539,18 +626,18 @@ class Process(object):
     def get_ext_memory_info(self):
         """Return a namedtuple with variable fields depending on the
         platform representing extended memory information about
         the process. All numbers are expressed in bytes.
         """
         return self._platform_impl.get_ext_memory_info()
 
     def get_memory_percent(self):
-        """Compare physical system memory to process resident memory and
-        calculate process memory utilization as a percentage.
+        """Compare physical system memory to process resident memory
+        (RSS) and calculate process memory utilization as a percentage.
         """
         rss = self._platform_impl.get_memory_info()[0]
         try:
             return (rss / float(TOTAL_PHYMEM)) * 100
         except ZeroDivisionError:
             return 0.0
 
     def get_memory_maps(self, grouped=True):
@@ -602,98 +689,95 @@ class Process(object):
         udp4            UDP over IPv4
         udp6            UDP over IPv6
         unix            UNIX socket (both UDP and TCP protocols)
         all             the sum of all the possible families and protocols
         """
         return self._platform_impl.get_connections(kind)
 
     def is_running(self):
-        """Return whether this process is running."""
+        """Return whether this process is running.
+        It also checks if PID has been reused by another process in
+        which case returns False.
+        """
         if self._gone:
             return False
         try:
             # Checking if pid is alive is not enough as the pid might
             # have been reused by another process.
             # pid + creation time, on the other hand, is supposed to
             # identify a process univocally.
             return self.create_time == \
                    self._platform_impl.get_process_create_time()
         except NoSuchProcess:
             self._gone = True
             return False
 
+    @_assert_pid_not_reused
     def send_signal(self, sig):
-        """Send a signal to process (see signal module constants).
+        """Send a signal to process pre-emptively checking whether
+        PID has been reused (see signal module constants) .
         On Windows only SIGTERM is valid and is treated as an alias
         for kill().
         """
-        # safety measure in case the current process has been killed in
-        # meantime and the kernel reused its PID
-        if not self.is_running():
-            name = self._platform_impl._process_name
-            raise NoSuchProcess(self.pid, name)
         if os.name == 'posix':
             try:
                 os.kill(self.pid, sig)
             except OSError:
                 err = sys.exc_info()[1]
                 name = self._platform_impl._process_name
                 if err.errno == errno.ESRCH:
+                    self._gone = True
                     raise NoSuchProcess(self.pid, name)
                 if err.errno == errno.EPERM:
                     raise AccessDenied(self.pid, name)
                 raise
         else:
             if sig == signal.SIGTERM:
                 self._platform_impl.kill_process()
             else:
                 raise ValueError("only SIGTERM is supported on Windows")
 
+    @_assert_pid_not_reused
     def suspend(self):
-        """Suspend process execution."""
-        # safety measure in case the current process has been killed in
-        # meantime and the kernel reused its PID
-        if not self.is_running():
-            name = self._platform_impl._process_name
-            raise NoSuchProcess(self.pid, name)
-        # windows
+        """Suspend process execution with SIGSTOP pre-emptively checking
+        whether PID has been reused.
+        On Windows it suspends all process threads.
+        """
         if hasattr(self._platform_impl, "suspend_process"):
+            # windows
             self._platform_impl.suspend_process()
         else:
             # posix
             self.send_signal(signal.SIGSTOP)
 
+    @_assert_pid_not_reused
     def resume(self):
-        """Resume process execution."""
-        # safety measure in case the current process has been killed in
-        # meantime and the kernel reused its PID
-        if not self.is_running():
-            name = self._platform_impl._process_name
-            raise NoSuchProcess(self.pid, name)
-        # windows
+        """Resume process execution with SIGCONT pre-emptively checking
+        whether PID has been reused.
+        On Windows it resumes all process threads.
+        """
         if hasattr(self._platform_impl, "resume_process"):
+            # windows
             self._platform_impl.resume_process()
         else:
             # posix
             self.send_signal(signal.SIGCONT)
 
     def terminate(self):
-        """Terminate the process with SIGTERM.
+        """Terminate the process with SIGTERM pre-emptively checking
+        whether PID has been reused.
         On Windows this is an alias for kill().
         """
         self.send_signal(signal.SIGTERM)
 
+    @_assert_pid_not_reused
     def kill(self):
-        """Kill the current process."""
-        # safety measure in case the current process has been killed in
-        # meantime and the kernel reused its PID
-        if not self.is_running():
-            name = self._platform_impl._process_name
-            raise NoSuchProcess(self.pid, name)
+        """Kill the current process with SIGKILL pre-emptively checking
+        whether PID has been reused."""
         if os.name == 'posix':
             self.send_signal(signal.SIGKILL)
         else:
             self._platform_impl.kill_process()
 
     def wait(self, timeout=None):
         """Wait for process to terminate and, if process is a children
         of the current one also return its exit code, else None.
@@ -750,26 +834,27 @@ class Popen(Process):
     For a complete documentation refers to:
     http://docs.python.org/library/subprocess.html
     """
 
     def __init__(self, *args, **kwargs):
         self.__subproc = subprocess.Popen(*args, **kwargs)
         self._pid = self.__subproc.pid
         self._gone = False
+        self._ppid = None
         self._platform_impl = _psplatform.Process(self._pid)
         self._last_sys_cpu_times = None
         self._last_proc_cpu_times = None
         try:
             self.create_time
         except AccessDenied:
             pass
         except NoSuchProcess:
             raise NoSuchProcess(self._pid, None,
-                                "no process found with pid %s" % pid)
+                                "no process found with pid %s" % self._pid)
 
     def __dir__(self):
         return list(set(dir(Popen) + dir(subprocess.Popen)))
 
     def __getattribute__(self, name):
         try:
             return object.__getattribute__(self, name)
         except AttributeError:
@@ -791,16 +876,20 @@ pid_exists = _psplatform.pid_exists
 
 def process_iter():
     """Return a generator yielding a Process class instance for all
     running processes on the local machine.
 
     Every new Process instance is only created once and then cached
     into an internal table which is updated every time this is used.
 
+    Cached Process instances are checked for identity so that you're
+    safe in case a PID has been reused by another process, in which
+    case the cached instance is updated.
+
     The sorting order in which processes are yielded is based on
     their PIDs.
     """
     def add(pid):
         proc = Process(pid)
         _pmap[proc.pid] = proc
         return proc
 
@@ -845,16 +934,19 @@ def cpu_times(percpu=False):
     Here follows a list of all available attributes:
      - user
      - system
      - idle
      - nice (UNIX)
      - iowait (Linux)
      - irq (Linux, FreeBSD)
      - softirq (Linux)
+     - steal (Linux >= 2.6.11)
+     - guest (Linux >= 2.6.24)
+     - guest_nice (Linux >= 3.2.0)
 
     When percpu is True return a list of nameduples for each CPU.
     First element of the list refers to first CPU, second element
     to second CPU and so on.
     The order of the list is consistent across calls.
     """
     if not percpu:
         return _psplatform.get_system_cpu_times()
@@ -877,16 +969,31 @@ def cpu_percent(interval=0.1, percpu=Fal
     In this case is recommended for accuracy that this function be
     called with at least 0.1 seconds between calls.
 
     When percpu is True returns a list of floats representing the
     utilization as a percentage for each CPU.
     First element of the list refers to first CPU, second element
     to second CPU and so on.
     The order of the list is consistent across calls.
+
+    Examples:
+
+      >>> # blocking, system-wide
+      >>> psutil.cpu_percent(interval=1)
+      2.0
+      >>>
+      >>> # blocking, per-cpu
+      >>> psutil.cpu_percent(interval=1, percpu=True)
+      [2.0, 1.0]
+      >>>
+      >>> # non-blocking (percentage since last call)
+      >>> psutil.cpu_percent(interval=0)
+      2.9
+      >>>
     """
     global _last_cpu_times
     global _last_per_cpu_times
     blocking = interval is not None and interval > 0.0
 
     def calculate(t1, t2):
         t1_all = sum(t1)
         t1_busy = t1_all - t1.idle
@@ -920,16 +1027,78 @@ def cpu_percent(interval=0.1, percpu=Fal
             time.sleep(interval)
         else:
             tot1 = _last_per_cpu_times
         _last_per_cpu_times = cpu_times(percpu=True)
         for t1, t2 in zip(tot1, _last_per_cpu_times):
             ret.append(calculate(t1, t2))
         return ret
 
+
+# Use separate global vars for cpu_times_percent() so that it's
+# independent from cpu_percent() and they can both be used within
+# the same program.
+_last_cpu_times_2 = _last_cpu_times
+_last_per_cpu_times_2 = _last_per_cpu_times
+_ptime_cpu_perc_nt = None
+
+def cpu_times_percent(interval=0.1, percpu=False):
+    """Same as cpu_percent() but provides utilization percentages
+    for each specific CPU time as is returned by cpu_times().
+    For instance, on Linux we'll get:
+
+      >>> cpu_times_percent()
+      cpupercent(user=4.8, nice=0.0, system=4.8, idle=90.5, iowait=0.0,
+                 irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
+      >>>
+
+    interval and percpu arguments have the same meaning as in
+    cpu_percent().
+    """
+    global _last_cpu_times_2
+    global _last_per_cpu_times_2
+    blocking = interval is not None and interval > 0.0
+
+    def calculate(t1, t2):
+        global _ptime_cpu_perc_nt
+        nums = []
+        all_delta = sum(t2) - sum(t1)
+        for field in t1._fields:
+            field_delta = getattr(t2, field) - getattr(t1, field)
+            try:
+                field_perc = (100 * field_delta) / all_delta
+            except ZeroDivisionError:
+                field_perc = 0.0
+            nums.append(round(field_perc, 1))
+        if _ptime_cpu_perc_nt is None:
+            _ptime_cpu_perc_nt = namedtuple('cpupercent', ' '.join(t1._fields))
+        return _ptime_cpu_perc_nt(*nums)
+
+    # system-wide usage
+    if not percpu:
+        if blocking:
+            t1 = cpu_times()
+            time.sleep(interval)
+        else:
+            t1 = _last_cpu_times_2
+        _last_cpu_times_2 = cpu_times()
+        return calculate(t1, _last_cpu_times_2)
+    # per-cpu usage
+    else:
+        ret = []
+        if blocking:
+            tot1 = cpu_times(percpu=True)
+            time.sleep(interval)
+        else:
+            tot1 = _last_per_cpu_times_2
+        _last_per_cpu_times_2 = cpu_times(percpu=True)
+        for t1, t2 in zip(tot1, _last_per_cpu_times_2):
+            ret.append(calculate(t1, t2))
+        return ret
+
 # =====================================================================
 # --- system memory related functions
 # =====================================================================
 
 def virtual_memory():
     """Return statistics about system memory usage as a namedtuple
     including the following fields, expressed in bytes:
 
@@ -1030,16 +1199,19 @@ def disk_io_counters(perdisk=False):
      - write_bytes: number of bytes written
      - read_time:   time spent reading from disk (in milliseconds)
      - write_time:  time spent writing to disk (in milliseconds)
 
     If perdisk is True return the same information for every
     physical disk installed on the system as a dictionary
     with partition names as the keys and the namedutuple
     described above as the values.
+
+    On recent Windows versions 'diskperf -y' command may need to be
+    executed first otherwise this function won't find any disk.
     """
     rawdict = _psplatform.disk_io_counters()
     if not rawdict:
         raise RuntimeError("couldn't find any physical disk")
     if perdisk:
         for disk, fields in rawdict.items():
             rawdict[disk] = _nt_disk_iostat(*fields)
         return rawdict
@@ -1078,16 +1250,22 @@ def network_io_counters(pernic=False):
         return rawdict
     else:
         return _nt_net_iostat(*[sum(x) for x in zip(*rawdict.values())])
 
 # =====================================================================
 # --- other system related functions
 # =====================================================================
 
+def get_boot_time():
+    """Return the system boot time expressed in seconds since the epoch.
+    This is also available as psutil.BOOT_TIME.
+    """
+    return _psplatform.get_system_boot_time()
+
 def get_users():
     """Return users currently connected on the system as a list of
     namedtuples including the following attributes.
 
      - user: the name of the user
      - terminal: the tty or pseudo-tty associated with the user, if any.
      - host: the host name associated with the entry, if any.
      - started: the creation time as a floating point number expressed in
@@ -1161,16 +1339,18 @@ def test():
             pass
         else:
             if pinfo['create_time']:
                 ctime = datetime.datetime.fromtimestamp(pinfo['create_time'])
                 if ctime.date() == today_day:
                     ctime = ctime.strftime("%H:%M")
                 else:
                     ctime = ctime.strftime("%b%d")
+            else:
+                ctime = ''
             cputime = time.strftime("%M:%S", time.localtime(sum(pinfo['cpu_times'])))
             user = pinfo['username']
             if os.name == 'nt' and '\\' in user:
                 user = user.split('\\')[1]
             vms = pinfo['memory_info'] and \
                   int(pinfo['memory_info'].vms / 1024) or '?'
             rss = pinfo['memory_info'] and \
                   int(pinfo['memory_info'].rss / 1024) or '?'
--- a/python/psutil/psutil/_common.py
+++ b/python/psutil/psutil/_common.py
@@ -1,12 +1,10 @@
 #/usr/bin/env python
-#
-#$Id: _common.py 1524 2012-08-16 15:06:32Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """Common objects shared by all _ps* modules."""
 
 from __future__ import division
 import sys
@@ -164,17 +162,16 @@ if AF_UNIX is not None:
     })
 
 
 del AF_INET, AF_INET6, AF_UNIX, SOCK_STREAM, SOCK_DGRAM, socket
 
 # --- namedtuples
 
 # system
-nt_sys_cputimes = namedtuple('cputimes', 'user nice system idle iowait irq softirq')
 nt_sysmeminfo = namedtuple('usage', 'total used free percent')
 # XXX - would 'available' be better than 'free' as for virtual_memory() nt?
 nt_swapmeminfo = namedtuple('swap', 'total used free percent sin sout')
 nt_diskinfo = namedtuple('usage', 'total used free percent')
 nt_partition = namedtuple('partition',  'device mountpoint fstype opts')
 nt_net_iostat = namedtuple('iostat',
     'bytes_sent bytes_recv packets_sent packets_recv errin errout dropin dropout')
 nt_disk_iostat = namedtuple('iostat', 'read_count write_count read_bytes write_bytes read_time write_time')
--- a/python/psutil/psutil/_compat.py
+++ b/python/psutil/psutil/_compat.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: _compat.py 1524 2012-08-16 15:06:32Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """Module which provides compatibility with older Python versions."""
 
 __all__ = ["PY3", "int", "long", "xrange", "exec_", "callable",
            "namedtuple", "property", "defaultdict"]
new file mode 100644
--- /dev/null
+++ b/python/psutil/psutil/_error.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+
+# Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+"""psutil exception classes.
+Not supposed to be used / imported directly.
+Instead use psutil.NoSuchProcess, etc.
+"""
+
+
+class Error(Exception):
+    """Base exception class. All other psutil exceptions inherit
+    from this one.
+    """
+
+class NoSuchProcess(Error):
+    """Exception raised when a process with a certain PID doesn't
+    or no longer exists (zombie).
+    """
+
+    def __init__(self, pid, name=None, msg=None):
+        self.pid = pid
+        self.name = name
+        self.msg = msg
+        if msg is None:
+            if name:
+                details = "(pid=%s, name=%s)" % (self.pid, repr(self.name))
+            else:
+                details = "(pid=%s)" % self.pid
+            self.msg = "process no longer exists " + details
+
+    def __str__(self):
+        return self.msg
+
+
+class AccessDenied(Error):
+    """Exception raised when permission to perform an action is denied."""
+
+    def __init__(self, pid=None, name=None, msg=None):
+        self.pid = pid
+        self.name = name
+        self.msg = msg
+        if msg is None:
+            if (pid is not None) and (name is not None):
+                self.msg = "(pid=%s, name=%s)" % (pid, repr(name))
+            elif (pid is not None):
+                self.msg = "(pid=%s)" % self.pid
+            else:
+                self.msg = ""
+
+    def __str__(self):
+        return self.msg
+
+
+class TimeoutExpired(Error):
+    """Raised on Process.wait(timeout) if timeout expires and process
+    is still alive.
+    """
+
+    def __init__(self, pid=None, name=None):
+        self.pid = pid
+        self.name = name
+        if (pid is not None) and (name is not None):
+            self.msg = "(pid=%s, name=%s)" % (pid, repr(name))
+        elif (pid is not None):
+            self.msg = "(pid=%s)" % self.pid
+        else:
+            self.msg = ""
+
+    def __str__(self):
+        return self.msg
--- a/python/psutil/psutil/_psbsd.py
+++ b/python/psutil/psutil/_psbsd.py
@@ -1,42 +1,60 @@
 #!/usr/bin/env python
-#
-# $Id: _psbsd.py 1498 2012-07-24 21:41:28Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """FreeBSD platform implementation."""
 
 import errno
 import os
 import sys
+import warnings
 
 import _psutil_bsd
 import _psutil_posix
 from psutil import _psposix
-from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired
-from psutil._compat import namedtuple
+from psutil._error import AccessDenied, NoSuchProcess, TimeoutExpired
+from psutil._compat import namedtuple, wraps
 from psutil._common import *
 
 __extra__all__ = []
 
 # --- constants
 
-NUM_CPUS = _psutil_bsd.get_num_cpus()
-BOOT_TIME = _psutil_bsd.get_system_boot_time()
-TOTAL_PHYMEM = _psutil_bsd.get_virtual_mem()[0]
-_TERMINAL_MAP = _psposix._get_terminal_map()
+# Since these constants get determined at import time we do not want to
+# crash immediately; instead we'll set them to None and most likely
+# we'll crash later as they're used for determining process CPU stats
+# and creation_time
+try:
+    NUM_CPUS = _psutil_bsd.get_num_cpus()
+except Exception:
+    NUM_CPUS = None
+    warnings.warn("couldn't determine platform's NUM_CPUS", RuntimeWarning)
+try:
+    TOTAL_PHYMEM = _psutil_bsd.get_virtual_mem()[0]
+except Exception:
+    TOTAL_PHYMEM = None
+    warnings.warn("couldn't determine platform's TOTAL_PHYMEM", RuntimeWarning)
+try:
+    BOOT_TIME = _psutil_bsd.get_system_boot_time()
+except Exception:
+    BOOT_TIME = None
+    warnings.warn("couldn't determine platform's BOOT_TIME", RuntimeWarning)
+
+
 _PAGESIZE = os.sysconf("SC_PAGE_SIZE")
 _cputimes_ntuple = namedtuple('cputimes', 'user nice system idle irq')
 
 # --- public functions
 
+get_system_boot_time = _psutil_bsd.get_system_boot_time
+
 nt_virtmem_info = namedtuple('vmem', ' '.join([
     # all platforms
     'total', 'available', 'percent', 'used', 'free',
     # FreeBSD specific
     'active',
     'inactive',
     'buffers',
     'cached',
@@ -119,24 +137,24 @@ def get_system_users():
 
 get_pid_list = _psutil_bsd.get_pid_list
 pid_exists = _psposix.pid_exists
 get_disk_usage = _psposix.get_disk_usage
 network_io_counters = _psutil_bsd.get_network_io_counters
 disk_io_counters = _psutil_bsd.get_disk_io_counters
 
 
-def wrap_exceptions(method):
-    """Call method(self, pid) into a try/except clause so that if an
-    OSError "No such process" exception is raised we assume the process
-    has died and raise psutil.NoSuchProcess instead.
+def wrap_exceptions(fun):
+    """Decorator which translates bare OSError exceptions into
+    NoSuchProcess and AccessDenied.
     """
+    @wraps(fun)
     def wrapper(self, *args, **kwargs):
         try:
-            return method(self, *args, **kwargs)
+            return fun(self, *args, **kwargs)
         except OSError:
             err = sys.exc_info()[1]
             if err.errno == errno.ESRCH:
                 raise NoSuchProcess(self.pid, self._process_name)
             if err.errno in (errno.EPERM, errno.EACCES):
                 raise AccessDenied(self.pid, self._process_name)
             raise
     return wrapper
@@ -174,18 +192,19 @@ class Process(object):
     @wrap_exceptions
     def get_process_cmdline(self):
         """Return process cmdline as a list of arguments."""
         return _psutil_bsd.get_process_cmdline(self.pid)
 
     @wrap_exceptions
     def get_process_terminal(self):
         tty_nr = _psutil_bsd.get_process_tty_nr(self.pid)
+        tmap = _psposix._get_terminal_map()
         try:
-            return _TERMINAL_MAP[tty_nr]
+            return tmap[tty_nr]
         except KeyError:
             return None
 
     @wrap_exceptions
     def get_process_ppid(self):
         """Return process parent pid."""
         return _psutil_bsd.get_process_ppid(self.pid)
 
old mode 100755
new mode 100644
--- a/python/psutil/psutil/_pslinux.py
+++ b/python/psutil/psutil/_pslinux.py
@@ -1,57 +1,53 @@
 #!/usr/bin/env python
-#
-# $Id: _pslinux.py 1513 2012-08-14 11:01:37Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """Linux platform implementation."""
 
 from __future__ import division
 
 import os
 import errno
 import socket
 import struct
 import sys
 import base64
 import re
+import warnings
 
 import _psutil_posix
 import _psutil_linux
 from psutil import _psposix
-from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired
+from psutil._error import AccessDenied, NoSuchProcess, TimeoutExpired
 from psutil._common import *
-from psutil._compat import PY3, xrange, long, namedtuple
+from psutil._compat import PY3, xrange, long, namedtuple, wraps
 
 __extra__all__ = [
     "IOPRIO_CLASS_NONE", "IOPRIO_CLASS_RT", "IOPRIO_CLASS_BE",
     "IOPRIO_CLASS_IDLE",
     "phymem_buffers", "cached_phymem"]
 
 
-def _get_boot_time():
-    """Return system boot time (epoch in seconds)"""
+def get_system_boot_time():
+    """Return the system boot time expressed in seconds since the epoch."""
     f = open('/proc/stat', 'r')
     try:
         for line in f:
             if line.startswith('btime'):
                 return float(line.strip().split()[1])
-        raise RuntimeError("line not found")
+        raise RuntimeError("line 'btime' not found")
     finally:
         f.close()
 
 def _get_num_cpus():
     """Return the number of CPUs on the system"""
-    # we try to determine num CPUs by using different approaches.
-    # SC_NPROCESSORS_ONLN seems to be the safer and it is also
-    # used by multiprocessing module
     try:
         return os.sysconf("SC_NPROCESSORS_ONLN")
     except ValueError:
         # as a second fallback we try to parse /proc/cpuinfo
         num = 0
         f = open('/proc/cpuinfo', 'r')
         try:
             lines = f.readlines()
@@ -72,27 +68,45 @@ def _get_num_cpus():
             f.close()
         search = re.compile('cpu\d')
         for line in lines:
             line = line.split(' ')[0]
             if search.match(line):
                 num += 1
 
     if num == 0:
-        raise RuntimeError("can't determine number of CPUs")
+        raise RuntimeError("couldn't determine platform's NUM_CPUS")
     return num
 
 
 # Number of clock ticks per second
-_CLOCK_TICKS = os.sysconf(os.sysconf_names["SC_CLK_TCK"])
+_CLOCK_TICKS = os.sysconf("SC_CLK_TCK")
 _PAGESIZE = os.sysconf("SC_PAGE_SIZE")
-_TERMINAL_MAP = _psposix._get_terminal_map()
-BOOT_TIME = _get_boot_time()
-NUM_CPUS = _get_num_cpus()
-TOTAL_PHYMEM = _psutil_linux.get_sysinfo()[0]
+
+# Since these constants get determined at import time we do not want to
+# crash immediately; instead we'll set them to None and most likely
+# we'll crash later as they're used for determining process CPU stats
+# and creation_time
+try:
+    BOOT_TIME = get_system_boot_time()
+except Exception:
+    BOOT_TIME = None
+    warnings.warn("couldn't determine platform's BOOT_TIME", RuntimeWarning)
+try:
+    NUM_CPUS = _get_num_cpus()
+except Exception:
+    NUM_CPUS = None
+    warnings.warn("couldn't determine platform's NUM_CPUS", RuntimeWarning)
+try:
+    TOTAL_PHYMEM = _psutil_linux.get_sysinfo()[0]
+except Exception:
+    TOTAL_PHYMEM = None
+    warnings.warn("couldn't determine platform's TOTAL_PHYMEM", RuntimeWarning)
+
+
 # ioprio_* constants http://linux.die.net/man/2/ioprio_get
 IOPRIO_CLASS_NONE = 0
 IOPRIO_CLASS_RT = 1
 IOPRIO_CLASS_BE = 2
 IOPRIO_CLASS_IDLE = 3
 
 # http://students.mimuw.edu.pl/lxr/source/include/net/tcp_states.h
 _TCP_STATES_TABLE = {"01" : "ESTABLISHED",
@@ -131,17 +145,22 @@ def virtual_memory():
                 active = int(line.split()[1]) * 1024
             elif line.startswith('Inactive:'):
                 inactive = int(line.split()[1]) * 1024
             if cached is not None \
             and active is not None \
             and inactive is not None:
                 break
         else:
-            raise RuntimeError("line(s) not found")
+            # we might get here when dealing with exotic Linux flavors, see:
+            # http://code.google.com/p/psutil/issues/detail?id=313
+            msg = "'cached', 'active' and 'inactive' memory stats couldn't " \
+                  "be determined and were set to 0"
+            warnings.warn(msg, RuntimeWarning)
+            cached = active = inactive = 0
     finally:
         f.close()
     avail = free + buffers + cached
     used = total - free
     percent = usage_percent((total - avail), total, _round=1)
     return nt_virtmem_info(total, avail, percent, used, free,
                            active, inactive, buffers, cached)
 
@@ -157,17 +176,22 @@ def swap_memory():
             # values are expressed in 4 kilo bytes, we want bytes instead
             if line.startswith('pswpin'):
                 sin = int(line.split(' ')[1]) * 4 * 1024
             elif line.startswith('pswpout'):
                 sout = int(line.split(' ')[1])  * 4 * 1024
             if sin is not None and sout is not None:
                 break
         else:
-            raise RuntimeError("line(s) not found")
+            # we might get here when dealing with exotic Linux flavors, see:
+            # http://code.google.com/p/psutil/issues/detail?id=313
+            msg = "'sin' and 'sout' swap memory stats couldn't " \
+                  "be determined and were set to 0"
+            warnings.warn(msg, RuntimeWarning)
+            sin = sout = 0
     finally:
         f.close()
     return nt_swapmeminfo(total, used, free, percent, sin, sout)
 
 # --- XXX deprecated memory functions
 
 @deprecated('psutil.virtual_memory().cached')
 def cached_phymem():
@@ -175,44 +199,75 @@ def cached_phymem():
 
 @deprecated('psutil.virtual_memory().buffers')
 def phymem_buffers():
     return virtual_memory().buffers
 
 
 # --- system CPU functions
 
+@memoize
+def _get_cputimes_ntuple():
+    """ Return a (nt, rindex) tuple depending on the CPU times available
+    on this Linux kernel version which may be:
+    user, nice, system, idle, iowait, irq, softirq [steal, [guest, [guest_nice]]]
+    """
+    f = open('/proc/stat', 'r')
+    try:
+        values = f.readline().split()[1:]
+    finally:
+        f.close()
+    fields = ['user', 'nice', 'system', 'idle', 'iowait', 'irq', 'softirq']
+    rindex = 8
+    vlen = len(values)
+    if vlen >= 8:
+        # Linux >= 2.6.11
+        fields.append('steal')
+        rindex += 1
+    if vlen >= 9:
+        # Linux >= 2.6.24
+        fields.append('guest')
+        rindex += 1
+    if vlen >= 10:
+        # Linux >= 3.2.0
+        fields.append('guest_nice')
+        rindex += 1
+    return (namedtuple('cputimes', ' '.join(fields)), rindex)
+
 def get_system_cpu_times():
-    """Return a named tuple representing the following CPU times:
-    user, nice, system, idle, iowait, irq, softirq.
+    """Return a named tuple representing the following system-wide
+    CPU times:
+    user, nice, system, idle, iowait, irq, softirq [steal, [guest, [guest_nice]]]
+    Last 3 fields may not be available on all Linux kernel versions.
     """
     f = open('/proc/stat', 'r')
     try:
         values = f.readline().split()
     finally:
         f.close()
-
-    values = values[1:8]
-    values = tuple([float(x) / _CLOCK_TICKS for x in values])
-    return nt_sys_cputimes(*values[:7])
+    nt, rindex = _get_cputimes_ntuple()
+    fields = values[1:rindex]
+    fields = [float(x) / _CLOCK_TICKS for x in fields]
+    return nt(*fields)
 
 def get_system_per_cpu_times():
     """Return a list of namedtuple representing the CPU times
     for every CPU available on the system.
     """
+    nt, rindex = _get_cputimes_ntuple()
     cpus = []
     f = open('/proc/stat', 'r')
-    # get rid of the first line who refers to system wide CPU stats
     try:
+        # get rid of the first line which refers to system wide CPU stats
         f.readline()
-        for line in f.readlines():
+        for line in f:
             if line.startswith('cpu'):
-                values = line.split()[1:8]
-                values = tuple([float(x) / _CLOCK_TICKS for x in values])
-                entry = nt_sys_cputimes(*values[:7])
+                fields = line.split()[1:rindex]
+                fields = [float(x) / _CLOCK_TICKS for x in fields]
+                entry = nt(*fields)
                 cpus.append(entry)
         return cpus
     finally:
         f.close()
 
 
 # --- system disk functions
 
@@ -246,17 +301,17 @@ get_disk_usage = _psposix.get_disk_usage
 # --- other sysetm functions
 
 def get_system_users():
     """Return currently connected users as a list of namedtuples."""
     retlist = []
     rawlist = _psutil_linux.get_system_users()
     for item in rawlist:
         user, tty, hostname, tstamp, user_process = item
-        # XXX the underlying C function includes entries about
+        # note: the underlying C function includes entries about
         # system boot, run level and others.  We might want
         # to use them in the future.
         if not user_process:
             continue
         if hostname == ':0.0':
             hostname = 'localhost'
         nt = nt_user(user, tty or None, hostname, tstamp)
         retlist.append(nt)
@@ -312,37 +367,44 @@ def disk_io_counters():
 
     # determine partitions we want to look for
     partitions = []
     f = open("/proc/partitions", "r")
     try:
         lines = f.readlines()[2:]
     finally:
         f.close()
-    for line in lines:
+    for line in reversed(lines):
         _, _, _, name = line.split()
         if name[-1].isdigit():
+            # we're dealing with a partition (e.g. 'sda1'); 'sda' will
+            # also be around but we want to omit it
             partitions.append(name)
+        else:
+            if not partitions or not partitions[-1].startswith(name):
+                # we're dealing with a disk entity for which no
+                # partitions have been defined (e.g. 'sda' but
+                # 'sda1' was not around), see:
+                # http://code.google.com/p/psutil/issues/detail?id=338
+                partitions.append(name)
     #
     retdict = {}
     f = open("/proc/diskstats", "r")
     try:
         lines = f.readlines()
     finally:
         f.close()
     for line in lines:
         _, _, name, reads, _, rbytes, rtime, writes, _, wbytes, wtime = \
             line.split()[:11]
         if name in partitions:
             rbytes = int(rbytes) * SECTOR_SIZE
             wbytes = int(wbytes) * SECTOR_SIZE
             reads = int(reads)
             writes = int(writes)
-            # TODO: times are expressed in milliseconds while OSX/BSD has
-            # these expressed in nanoseconds; figure this out.
             rtime = int(rtime)
             wtime = int(wtime)
             retdict[name] = (reads, writes, rbytes, wbytes, rtime, wtime)
     return retdict
 
 
 # taken from /fs/proc/array.c
 _status_map = {"R" : STATUS_RUNNING,
@@ -353,23 +415,24 @@ def disk_io_counters():
                "Z" : STATUS_ZOMBIE,
                "X" : STATUS_DEAD,
                "x" : STATUS_DEAD,
                "K" : STATUS_WAKE_KILL,
                "W" : STATUS_WAKING}
 
 # --- decorators
 
-def wrap_exceptions(callable):
-    """Call callable into a try/except clause and translate ENOENT,
-    EACCES and EPERM in NoSuchProcess or AccessDenied exceptions.
+def wrap_exceptions(fun):
+    """Decorator which translates bare OSError and IOError exceptions
+    into NoSuchProcess and AccessDenied.
     """
+    @wraps(fun)
     def wrapper(self, *args, **kwargs):
         try:
-            return callable(self, *args, **kwargs)
+            return fun(self, *args, **kwargs)
         except EnvironmentError:
             # ENOENT (no such file or directory) gets raised on open().
             # ESRCH (no such process) can get raised on read() if
             # process is gone in meantime.
             err = sys.exc_info()[1]
             if err.errno in (errno.ENOENT, errno.ESRCH):
                 raise NoSuchProcess(self.pid, self._process_name)
             if err.errno in (errno.EPERM, errno.EACCES):
@@ -379,18 +442,16 @@ def wrap_exceptions(callable):
 
 
 class Process(object):
     """Linux process implementation."""
 
     __slots__ = ["pid", "_process_name"]
 
     def __init__(self, pid):
-        if not isinstance(pid, int):
-            raise TypeError('pid must be an integer')
         self.pid = pid
         self._process_name = None
 
     @wrap_exceptions
     def get_process_name(self):
         f = open("/proc/%s/stat" % self.pid)
         try:
             name = f.read().split(' ')[1].replace('(', '').replace(')', '')
@@ -435,23 +496,24 @@ class Process(object):
         try:
             # return the args as a list
             return [x for x in f.read().split('\x00') if x]
         finally:
             f.close()
 
     @wrap_exceptions
     def get_process_terminal(self):
+        tmap = _psposix._get_terminal_map()
         f = open("/proc/%s/stat" % self.pid)
         try:
             tty_nr = int(f.read().split(' ')[6])
         finally:
             f.close()
         try:
-            return _TERMINAL_MAP[tty_nr]
+            return tmap[tty_nr]
         except KeyError:
             return None
 
     @wrap_exceptions
     def get_process_io_counters(self):
         f = open("/proc/%s/io" % self.pid)
         try:
             for line in f:
@@ -464,17 +526,18 @@ class Process(object):
                 elif line.startswith("write_bytes"):
                     write_bytes = int(line.split()[1])
             return nt_io(read_count, write_count, read_bytes, write_bytes)
         finally:
             f.close()
 
     if not os.path.exists('/proc/%s/io' % os.getpid()):
         def get_process_io_counters(self):
-            raise NotImplementedError('/proc/PID/io is not available')
+            raise NotImplementedError("couldn't find /proc/%s/io (kernel " \
+                                      "too old?)" % self.pid)
 
     @wrap_exceptions
     def get_cpu_times(self):
         f = open("/proc/%s/stat" % self.pid)
         try:
             st = f.read().strip()
         finally:
             f.close()
@@ -578,23 +641,25 @@ class Process(object):
                     except ValueError:
                         addr, perms, offset, dev, inode, path = hfields + ['']
                     if not path:
                         path = '[anon]'
                     else:
                         path = path.strip()
                     yield (addr, perms, path,
                            data['Rss:'],
-                           data['Size:'],
+                           data.get('Size:', 0),
                            data.get('Pss:', 0),
-                           data['Shared_Clean:'], data['Shared_Clean:'],
-                           data['Private_Clean:'], data['Private_Dirty:'],
-                           data['Referenced:'],
-                           data['Anonymous:'],
-                           data['Swap:'])
+                           data.get('Shared_Clean:', 0),
+                           data.get('Shared_Dirty:', 0),
+                           data.get('Private_Clean:', 0),
+                           data.get('Private_Dirty:', 0),
+                           data.get('Referenced:', 0),
+                           data.get('Anonymous:', 0),
+                           data.get('Swap:', 0))
             f.close()
         except EnvironmentError:
             # XXX - Can't use wrap_exceptions decorator as we're
             # returning a generator;  this probably needs some
             # refactoring in order to avoid this code duplication.
             if f is not None:
                 f.close()
             err = sys.exc_info()[1]
@@ -602,22 +667,22 @@ class Process(object):
                 raise NoSuchProcess(self.pid, self._process_name)
             if err.errno in (errno.EPERM, errno.EACCES):
                 raise AccessDenied(self.pid, self._process_name)
             raise
         except:
             if f is not None:
                 f.close()
             raise
+        f.close()
 
     if not os.path.exists('/proc/%s/smaps' % os.getpid()):
         def get_shared_libs(self, ext):
-            msg = "this Linux version does not support /proc/PID/smaps " \
-                  "(kernel < 2.6.14 or CONFIG_MMU kernel configuration " \
-                  "option is not enabled)"
+            msg = "couldn't find /proc/%s/smaps; kernel < 2.6.14 or CONFIG_MMU " \
+                  "kernel configuration option is not enabled" % self.pid
             raise NotImplementedError(msg)
 
     @wrap_exceptions
     def get_process_cwd(self):
         # readlink() might return paths containing null bytes causing
         # problems when used with other fs-related functions (os.*,
         # open(), ...)
         path = os.readlink("/proc/%s/cwd" % self.pid)
@@ -630,28 +695,31 @@ class Process(object):
         try:
             for line in f:
                 if line.startswith("voluntary_ctxt_switches"):
                     vol = int(line.split()[1])
                 elif line.startswith("nonvoluntary_ctxt_switches"):
                     unvol = int(line.split()[1])
                 if vol is not None and unvol is not None:
                     return nt_ctxsw(vol, unvol)
-            raise RuntimeError("line not found")
+            raise NotImplementedError("the 'voluntary_ctxt_switches' and " \
+                "'nonvoluntary_ctxt_switches' fields were not found in " \
+                "/proc/%s/status; the kernel is probably older than 2.6.23" \
+                % self.pid)
         finally:
             f.close()
 
     @wrap_exceptions
     def get_process_num_threads(self):
         f = open("/proc/%s/status" % self.pid)
         try:
             for line in f:
                 if line.startswith("Threads:"):
                     return int(line.split()[1])
-            raise RuntimeError("line not found")
+            raise NotImplementedError("line not found")
         finally:
             f.close()
 
     @wrap_exceptions
     def get_process_threads(self):
         thread_ids = os.listdir("/proc/%s/task" % self.pid)
         thread_ids.sort()
         retlist = []
@@ -931,41 +999,41 @@ class Process(object):
     @wrap_exceptions
     def get_process_ppid(self):
         f = open("/proc/%s/status" % self.pid)
         try:
             for line in f:
                 if line.startswith("PPid:"):
                     # PPid: nnnn
                     return int(line.split()[1])
-            raise RuntimeError("line not found")
+            raise NotImplementedError("line not found")
         finally:
             f.close()
 
     @wrap_exceptions
     def get_process_uids(self):
         f = open("/proc/%s/status" % self.pid)
         try:
             for line in f:
                 if line.startswith('Uid:'):
                     _, real, effective, saved, fs = line.split()
                     return nt_uids(int(real), int(effective), int(saved))
-            raise RuntimeError("line not found")
+            raise NotImplementedError("line not found")
         finally:
             f.close()
 
     @wrap_exceptions
     def get_process_gids(self):
         f = open("/proc/%s/status" % self.pid)
         try:
             for line in f:
                 if line.startswith('Gid:'):
                     _, real, effective, saved, fs = line.split()
                     return nt_gids(int(real), int(effective), int(saved))
-            raise RuntimeError("line not found")
+            raise NotImplementedError("line not found")
         finally:
             f.close()
 
     @staticmethod
     def _decode_address(addr, family):
         """Accept an "ip:port" address as displayed in /proc/net/*
         and convert it into a human readable form, like:
 
--- a/python/psutil/psutil/_psmswindows.py
+++ b/python/psutil/psutil/_psmswindows.py
@@ -1,40 +1,56 @@
 #!/usr/bin/env python
-#
-# $Id: _psmswindows.py 1514 2012-08-14 11:16:56Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """Windows platform implementation."""
 
 import errno
 import os
 import sys
 import platform
+import warnings
 
 import _psutil_mswindows
 from _psutil_mswindows import ERROR_ACCESS_DENIED
-from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired
+from psutil._error import AccessDenied, NoSuchProcess, TimeoutExpired
 from psutil._common import *
-from psutil._compat import PY3, xrange, long
+from psutil._compat import PY3, xrange, long, wraps
 
 # Windows specific extended namespace
 __extra__all__ = ["ABOVE_NORMAL_PRIORITY_CLASS", "BELOW_NORMAL_PRIORITY_CLASS",
                   "HIGH_PRIORITY_CLASS", "IDLE_PRIORITY_CLASS",
                   "NORMAL_PRIORITY_CLASS", "REALTIME_PRIORITY_CLASS"]
 
 
 # --- module level constants (gets pushed up to psutil module)
 
-NUM_CPUS = _psutil_mswindows.get_num_cpus()
-BOOT_TIME = _psutil_mswindows.get_system_uptime()
-TOTAL_PHYMEM = _psutil_mswindows.get_virtual_mem()[0]
+# Since these constants get determined at import time we do not want to
+# crash immediately; instead we'll set them to None and most likely
+# we'll crash later as they're used for determining process CPU stats
+# and creation_time
+try:
+    NUM_CPUS = _psutil_mswindows.get_num_cpus()
+except Exception:
+    NUM_CPUS = None
+    warnings.warn("couldn't determine platform's NUM_CPUS", RuntimeWarning)
+try:
+    BOOT_TIME = _psutil_mswindows.get_system_boot_time()
+except Exception:
+    BOOT_TIME = None
+    warnings.warn("couldn't determine platform's BOOT_TIME", RuntimeWarning)
+try:
+    TOTAL_PHYMEM = _psutil_mswindows.get_virtual_mem()[0]
+except Exception:
+    TOTAL_PHYMEM = None
+    warnings.warn("couldn't determine platform's TOTAL_PHYMEM", RuntimeWarning)
+
 WAIT_TIMEOUT = 0x00000102 # 258 in decimal
 ACCESS_DENIED_SET = frozenset([errno.EPERM, errno.EACCES, ERROR_ACCESS_DENIED])
 
 # process priority constants:
 # http://msdn.microsoft.com/en-us/library/ms686219(v=vs.85).aspx
 from _psutil_mswindows import (ABOVE_NORMAL_PRIORITY_CLASS,
                                BELOW_NORMAL_PRIORITY_CLASS,
                                HIGH_PRIORITY_CLASS,
@@ -55,16 +71,18 @@ def _convert_raw_path(s):
         s = s.decode('utf8')
     rawdrive = '\\'.join(s.split('\\')[:3])
     driveletter = _win32_QueryDosDevice(rawdrive)
     return os.path.join(driveletter, s[len(rawdrive):])
 
 
 # --- public functions
 
+get_system_boot_time = _psutil_mswindows.get_system_boot_time
+
 nt_virtmem_info = namedtuple('vmem', ' '.join([
     # all platforms
     'total', 'available', 'percent', 'used', 'free']))
 
 def virtual_memory():
     """System virtual memory as a namedtuple."""
     mem = _psutil_mswindows.get_virtual_mem()
     totphys, availphys, totpagef, availpagef, totvirt, freevirt = mem
@@ -137,24 +155,24 @@ def get_system_users():
 
 get_pid_list = _psutil_mswindows.get_pid_list
 pid_exists = _psutil_mswindows.pid_exists
 network_io_counters = _psutil_mswindows.get_network_io_counters
 disk_io_counters = _psutil_mswindows.get_disk_io_counters
 
 # --- decorator
 
-def wrap_exceptions(callable):
-    """Call callable into a try/except clause so that if a
-    WindowsError 5 AccessDenied exception is raised we translate it
-    into psutil.AccessDenied
+def wrap_exceptions(fun):
+    """Decorator which translates bare OSError and WindowsError
+    exceptions into NoSuchProcess and AccessDenied.
     """
+    @wraps(fun)
     def wrapper(self, *args, **kwargs):
         try:
-            return callable(self, *args, **kwargs)
+            return fun(self, *args, **kwargs)
         except OSError:
             err = sys.exc_info()[1]
             if err.errno in ACCESS_DENIED_SET:
                 raise AccessDenied(self.pid, self._process_name)
             if err.errno == errno.ESRCH:
                 raise NoSuchProcess(self.pid, self._process_name)
             raise
     return wrapper
@@ -354,16 +372,32 @@ class Process(object):
     @wrap_exceptions
     def get_process_nice(self):
         return _psutil_mswindows.get_process_priority(self.pid)
 
     @wrap_exceptions
     def set_process_nice(self, value):
         return _psutil_mswindows.set_process_priority(self.pid, value)
 
+    # available on Windows >= Vista
+    if hasattr(_psutil_mswindows, "get_process_io_priority"):
+        @wrap_exceptions
+        def get_process_ionice(self):
+            return _psutil_mswindows.get_process_io_priority(self.pid)
+
+        @wrap_exceptions
+        def set_process_ionice(self, value, _):
+            if _:
+                raise TypeError("set_process_ionice() on Windows takes only " \
+                                "1 argument (2 given)")
+            if value not in (2, 1, 0):
+                raise ValueError("value must be 2 (normal), 1 (low) or 0 " \
+                                 "(very low); got %r" % value)
+            return _psutil_mswindows.set_process_io_priority(self.pid, value)
+
     @wrap_exceptions
     def get_process_io_counters(self):
         try:
             ret = _psutil_mswindows.get_process_io_counters(self.pid)
         except OSError:
             err = sys.exc_info()[1]
             if err.errno in ACCESS_DENIED_SET:
                 ret = _psutil_mswindows.get_process_io_counters_2(self.pid)
@@ -387,28 +421,26 @@ class Process(object):
 
     @wrap_exceptions
     def set_process_cpu_affinity(self, value):
         def to_bitmask(l):
             if not l:
                 raise ValueError("invalid argument %r" % l)
             out = 0
             for b in l:
-                if not isinstance(b, (int, long)) or b < 0:
-                    raise ValueError("invalid argument %r" % b)
                 out |= 2**b
             return out
 
         # SetProcessAffinityMask() states that ERROR_INVALID_PARAMETER
         # is returned for an invalid CPU but this seems not to be true,
         # therefore we check CPUs validy beforehand.
         allcpus = list(range(len(get_system_per_cpu_times())))
         for cpu in value:
             if cpu not in allcpus:
-                raise ValueError("invalid CPU %i" % cpu)
+                raise ValueError("invalid CPU %r" % cpu)
 
         bitmask = to_bitmask(value)
         _psutil_mswindows.set_process_cpu_affinity(self.pid, bitmask)
 
     @wrap_exceptions
     def get_num_handles(self):
         try:
             return _psutil_mswindows.get_process_num_handles(self.pid)
--- a/python/psutil/psutil/_psosx.py
+++ b/python/psutil/psutil/_psosx.py
@@ -1,42 +1,59 @@
 #!/usr/bin/env python
-#
-# $Id: _psosx.py 1498 2012-07-24 21:41:28Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """OSX platform implementation."""
 
 import errno
 import os
 import sys
+import warnings
 
 import _psutil_osx
 import _psutil_posix
 from psutil import _psposix
-from psutil.error import AccessDenied, NoSuchProcess, TimeoutExpired
-from psutil._compat import namedtuple
+from psutil._error import AccessDenied, NoSuchProcess, TimeoutExpired
+from psutil._compat import namedtuple, wraps
 from psutil._common import *
 
 __extra__all__ = []
 
 # --- constants
 
-NUM_CPUS = _psutil_osx.get_num_cpus()
-BOOT_TIME = _psutil_osx.get_system_boot_time()
-TOTAL_PHYMEM = _psutil_osx.get_virtual_mem()[0]
+# Since these constants get determined at import time we do not want to
+# crash immediately; instead we'll set them to None and most likely
+# we'll crash later as they're used for determining process CPU stats
+# and creation_time
+try:
+    NUM_CPUS = _psutil_osx.get_num_cpus()
+except Exception:
+    NUM_CPUS = None
+    warnings.warn("couldn't determine platform's NUM_CPUS", RuntimeWarning)
+try:
+    BOOT_TIME = _psutil_osx.get_system_boot_time()
+except Exception:
+    BOOT_TIME = None
+    warnings.warn("couldn't determine platform's BOOT_TIME", RuntimeWarning)
+try:
+    TOTAL_PHYMEM = _psutil_osx.get_virtual_mem()[0]
+except Exception:
+    TOTAL_PHYMEM = None
+    warnings.warn("couldn't determine platform's TOTAL_PHYMEM", RuntimeWarning)
+
 _PAGESIZE = os.sysconf("SC_PAGE_SIZE")
-_TERMINAL_MAP = _psposix._get_terminal_map()
 _cputimes_ntuple = namedtuple('cputimes', 'user nice system idle')
 
 # --- functions
 
+get_system_boot_time = _psutil_osx.get_system_boot_time
+
 nt_virtmem_info = namedtuple('vmem', ' '.join([
     # all platforms
     'total', 'available', 'percent', 'used', 'free',
     # OSX specific
     'active',
     'inactive',
     'wired']))
 
@@ -101,24 +118,24 @@ def get_system_users():
 get_pid_list = _psutil_osx.get_pid_list
 pid_exists = _psposix.pid_exists
 get_disk_usage = _psposix.get_disk_usage
 network_io_counters = _psutil_osx.get_network_io_counters
 disk_io_counters = _psutil_osx.get_disk_io_counters
 
 # --- decorator
 
-def wrap_exceptions(callable):
-    """Call callable into a try/except clause so that if an
-    OSError EPERM exception is raised we translate it into
-    psutil.AccessDenied.
+def wrap_exceptions(fun):
+    """Decorator which translates bare OSError exceptions into
+    NoSuchProcess and AccessDenied.
     """
+    @wraps(fun)
     def wrapper(self, *args, **kwargs):
         try:
-            return callable(self, *args, **kwargs)
+            return fun(self, *args, **kwargs)
         except OSError:
             err = sys.exc_info()[1]
             if err.errno == errno.ESRCH:
                 raise NoSuchProcess(self.pid, self._process_name)
             if err.errno in (errno.EPERM, errno.EACCES):
                 raise AccessDenied(self.pid, self._process_name)
             raise
     return wrapper
@@ -174,18 +191,19 @@ class Process(object):
     @wrap_exceptions
     def get_process_gids(self):
         real, effective, saved = _psutil_osx.get_process_gids(self.pid)
         return nt_gids(real, effective, saved)
 
     @wrap_exceptions
     def get_process_terminal(self):
         tty_nr = _psutil_osx.get_process_tty_nr(self.pid)
+        tmap = _psposix._get_terminal_map()
         try:
-            return _TERMINAL_MAP[tty_nr]
+            return tmap[tty_nr]
         except KeyError:
             return None
 
     @wrap_exceptions
     def get_memory_info(self):
         """Return a tuple with the process' RSS and VMS size."""
         rss, vms = _psutil_osx.get_process_memory_info(self.pid)[:2]
         return nt_meminfo(rss, vms)
--- a/python/psutil/psutil/_psposix.py
+++ b/python/psutil/psutil/_psposix.py
@@ -1,33 +1,29 @@
 #!/usr/bin/env python
-#
-# $Id: _psposix.py 1409 2012-07-04 08:21:06Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """Routines common to all posix systems."""
 
 import os
 import errno
 import psutil
 import sys
 import time
 import glob
 
-from psutil.error import TimeoutExpired
-from psutil._common import nt_diskinfo, usage_percent
+from psutil._error import TimeoutExpired
+from psutil._common import nt_diskinfo, usage_percent, memoize
 
 
 def pid_exists(pid):
     """Check whether pid exists in the current process table."""
-    if not isinstance(pid, int):
-        raise TypeError('an integer is required')
     if pid < 0:
         return False
     try:
         os.kill(pid, 0)
     except OSError:
         e = sys.exc_info()[1]
         return e.errno == errno.EPERM
     else:
@@ -41,24 +37,25 @@ def wait_pid(pid, timeout=None):
     waits until the process disappears and return None.
 
     If pid does not exist at all return None immediately.
 
     Raise TimeoutExpired on timeout expired.
     """
     def check_timeout(delay):
         if timeout is not None:
-            if time.time() >= stop_at:
+            if timer() >= stop_at:
                 raise TimeoutExpired(pid)
         time.sleep(delay)
         return min(delay * 2, 0.04)
 
+    timer = getattr(time, 'monotonic', time.time)
     if timeout is not None:
         waitcall = lambda: os.waitpid(pid, os.WNOHANG)
-        stop_at = time.time() + timeout
+        stop_at = timer() + timeout
     else:
         waitcall = lambda: os.waitpid(pid, 0)
 
     delay = 0.0001
     while 1:
         try:
             retpid, status = waitcall()
         except OSError:
@@ -104,15 +101,21 @@ def get_disk_usage(path):
     total = (st.f_blocks * st.f_frsize)
     used = (st.f_blocks - st.f_bfree) * st.f_frsize
     percent = usage_percent(used, total, _round=1)
     # NB: the percentage is -5% than what shown by df due to
     # reserved blocks that we are currently not considering:
     # http://goo.gl/sWGbH
     return nt_diskinfo(total, used, free, percent)
 
+@memoize
 def _get_terminal_map():
     ret = {}
     ls = glob.glob('/dev/tty*') + glob.glob('/dev/pts/*')
     for name in ls:
         assert name not in ret
-        ret[os.stat(name).st_rdev] = name
+        try:
+            ret[os.stat(name).st_rdev] = name
+        except OSError:
+            err = sys.exc_info()[1]
+            if err.errno != errno.ENOENT:
+                raise
     return ret
--- a/python/psutil/psutil/_psutil_bsd.c
+++ b/python/psutil/psutil/_psutil_bsd.c
@@ -1,47 +1,41 @@
 /*
- * $Id: _psutil_bsd.c 1513 2012-08-14 11:01:37Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * FreeBSD platform-specific module methods for _psutil_bsd
  */
 
+
 #include <Python.h>
 #include <assert.h>
 #include <errno.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <signal.h>
 #include <fcntl.h>
+#include <paths.h>
 #include <sys/types.h>
 #include <sys/sysctl.h>
 #include <sys/param.h>
 #include <sys/user.h>
 #include <sys/proc.h>
 #include <sys/file.h>
 #include <net/route.h>
 
 #include <sys/socket.h>
-#include <sys/socketvar.h>    /* for struct socket */
-#include <sys/protosw.h>      /* for struct proto */
-#include <sys/domain.h>       /* for struct domain */
-
-#include <sys/un.h>           /* for unpcb struct (UNIX sockets) */
-#include <sys/unpcb.h>        /* for unpcb struct (UNIX sockets) */
-#include <sys/mbuf.h>         /* for mbuf struct (UNIX sockets) */
-/* for in_pcb struct */
+#include <sys/socketvar.h>    /* for struct xsocket */
+/* for xinpcb struct */
 #include <netinet/in.h>
 #include <netinet/in_systm.h>
 #include <netinet/ip.h>
 #include <netinet/in_pcb.h>
-#include <netinet/tcp_var.h>   /* for struct tcpcb */
+#include <netinet/tcp_var.h>   /* for struct xtcpcb */
 #include <netinet/tcp_fsm.h>   /* for TCP connection states */
 #include <arpa/inet.h>         /* for inet_ntop() */
 
 #if __FreeBSD_version < 900000
     #include <utmp.h>         /* system users */
 #else
     #include <utmpx.h>
 #endif
@@ -65,17 +59,17 @@
 // convert a timeval struct to a double
 #define TV2DOUBLE(t)    ((t).tv_sec + (t).tv_usec / 1000000.0)
 
 
 /*
  * Utility function which fills a kinfo_proc struct based on process pid
  */
 static int
-get_kinfo_proc(const pid_t pid, struct kinfo_proc *proc)
+psutil_get_kinfo_proc(const pid_t pid, struct kinfo_proc *proc)
 {
     int mib[4];
     size_t size;
     mib[0] = CTL_KERN;
     mib[1] = KERN_PROC;
     mib[2] = KERN_PROC_PID;
     mib[3] = pid;
 
@@ -105,17 +99,20 @@ get_pid_list(PyObject* self, PyObject* a
 {
     kinfo_proc *proclist = NULL;
     kinfo_proc *orig_address = NULL;
     size_t num_processes;
     size_t idx;
     PyObject* retlist = PyList_New(0);
     PyObject* pid = NULL;
 
-    if (get_proc_list(&proclist, &num_processes) != 0) {
+    if (retlist == NULL) {
+        return NULL;
+    }
+    if (psutil_get_proc_list(&proclist, &num_processes) != 0) {
         PyErr_SetString(PyExc_RuntimeError, "failed to retrieve process list.");
         goto error;
     }
 
     if (num_processes > 0) {
         orig_address = proclist; // save so we can free it after we're done
         for (idx=0; idx < num_processes; idx++) {
             pid = Py_BuildValue("i", proclist->ki_pid);
@@ -145,41 +142,39 @@ error:
  * Return a Python float indicating the system boot time expressed in
  * seconds since the epoch.
  */
 static PyObject*
 get_system_boot_time(PyObject* self, PyObject* args)
 {
     /* fetch sysctl "kern.boottime" */
     static int request[2] = { CTL_KERN, KERN_BOOTTIME };
-    struct timeval result;
-    size_t result_len = sizeof result;
-    time_t boot_time = 0;
+    struct timeval boottime;
+    size_t len = sizeof(boottime);
 
-    if (sysctl(request, 2, &result, &result_len, NULL, 0) == -1) {
+    if (sysctl(request, 2, &boottime, &len, NULL, 0) == -1) {
         PyErr_SetFromErrno(0);
         return NULL;
     }
-    boot_time = result.tv_sec;
-    return Py_BuildValue("f", (float)boot_time);
+    return Py_BuildValue("d", (double)boottime.tv_sec);
 }
 
 
 /*
  * Return process name from kinfo_proc as a Python string.
  */
 static PyObject*
 get_process_name(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("s", kp.ki_comm);
 }
 
 
 /*
  * Return process pathname executable.
@@ -193,33 +188,36 @@ get_process_exe(PyObject* self, PyObject
     char pathname[PATH_MAX];
     int error;
     int mib[4];
     size_t size;
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (pid == 0) {
-        // ...otherwise we'd get '\x98\xd5\xbf\xbf\xfb\xf3\x10\x08H\x01'
-        return Py_BuildValue("s", "");
-    }
 
     mib[0] = CTL_KERN;
     mib[1] = KERN_PROC;
     mib[2] = KERN_PROC_PATHNAME;
     mib[3] = pid;
 
     size = sizeof(pathname);
     error = sysctl(mib, 4, pathname, &size, NULL, 0);
     if (error == -1) {
         PyErr_SetFromErrno(PyExc_OSError);
         return NULL;
     }
-
+    if (size == 0 || strlen(pathname) == 0) {
+        if (psutil_pid_exists(pid) == 0) {
+            return NoSuchProcess();
+        }
+        else {
+            strcpy(pathname, "");
+        }
+    }
     return Py_BuildValue("s", pathname);
 }
 
 
 /*
  * Return process cmdline as a Python list of cmdline arguments.
  */
 static PyObject*
@@ -228,19 +226,19 @@ get_process_cmdline(PyObject* self, PyOb
     long pid;
     PyObject* arglist = NULL;
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
 
     // get the commandline, defined in arch/bsd/process_info.c
-    arglist = get_arg_list(pid);
+    arglist = psutil_get_arg_list(pid);
 
-    // get_arg_list() returns NULL only if getcmdargs failed with ESRCH
+    // psutil_get_arg_list() returns NULL only if psutil_get_cmd_args failed with ESRCH
     // (no process with that PID)
     if (NULL == arglist) {
         return PyErr_SetFromErrno(PyExc_OSError);
     }
     return Py_BuildValue("N", arglist);
 }
 
 
@@ -250,17 +248,17 @@ get_process_cmdline(PyObject* self, PyOb
 static PyObject*
 get_process_ppid(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("l", (long)kp.ki_ppid);
 }
 
 
 /*
  * Return process status as a Python integer.
@@ -268,17 +266,17 @@ get_process_ppid(PyObject* self, PyObjec
 static PyObject*
 get_process_status(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("i", (int)kp.ki_stat);
 }
 
 
 /*
  * Return process real, effective and saved user ids from kinfo_proc
@@ -287,17 +285,17 @@ get_process_status(PyObject* self, PyObj
 static PyObject*
 get_process_uids(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("lll", (long)kp.ki_ruid,
                                 (long)kp.ki_uid,
                                 (long)kp.ki_svuid);
 }
 
 
@@ -308,17 +306,17 @@ get_process_uids(PyObject* self, PyObjec
 static PyObject*
 get_process_gids(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("lll", (long)kp.ki_rgid,
                                 (long)kp.ki_groups[0],
                                 (long)kp.ki_svuid);
 }
 
 
@@ -329,17 +327,17 @@ get_process_gids(PyObject* self, PyObjec
 static PyObject*
 get_process_tty_nr(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("i", kp.ki_tdev);
 }
 
 
 /*
  * Return the number of context switches performed by process as a tuple.
@@ -347,17 +345,17 @@ get_process_tty_nr(PyObject* self, PyObj
 static PyObject*
 get_process_num_ctx_switches(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("(ll)", kp.ki_rusage.ru_nvcsw,
                                  kp.ki_rusage.ru_nivcsw);
 }
 
 
 
@@ -367,17 +365,17 @@ get_process_num_ctx_switches(PyObject* s
 static PyObject*
 get_process_num_threads(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("l", (long)kp.ki_numthreads);
 }
 
 
 /*
  * Retrieves all threads used by process returning a list of tuples
@@ -393,19 +391,20 @@ get_process_threads(PyObject* self, PyOb
     struct kinfo_proc *kip = NULL;
     struct kinfo_proc *kipp;
     int error;
     unsigned int i;
     size_t size;
     PyObject* retList = PyList_New(0);
     PyObject* pyTuple = NULL;
 
-    if (! PyArg_ParseTuple(args, "l", &pid)) {
+    if (retList == NULL)
+        return NULL;
+    if (! PyArg_ParseTuple(args, "l", &pid))
         goto error;
-    }
 
     /*
      * We need to re-query for thread information, so don't use *kipp.
      */
     mib[0] = CTL_KERN;
     mib[1] = KERN_PROC;
     mib[2] = KERN_PROC_PID | KERN_PROC_INC_THREAD;
     mib[3] = pid;
@@ -418,17 +417,17 @@ get_process_threads(PyObject* self, PyOb
     }
     if (size == 0) {
         NoSuchProcess();
         goto error;
     }
 
     kip = malloc(size);
     if (kip == NULL) {
-        PyErr_SetFromErrno(PyExc_OSError);
+        PyErr_NoMemory();
         goto error;
     }
 
     error = sysctl(mib, 4, kip, &size, NULL, 0);
     if (error == -1) {
         PyErr_SetFromErrno(PyExc_OSError);
         goto error;
     }
@@ -469,17 +468,17 @@ static PyObject*
 get_process_cpu_times(PyObject* self, PyObject* args)
 {
     long pid;
     double user_t, sys_t;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     // convert from microseconds to seconds
     user_t = TV2DOUBLE(kp.ki_rusage.ru_utime);
     sys_t = TV2DOUBLE(kp.ki_rusage.ru_stime);
     return Py_BuildValue("(dd)", user_t, sys_t);
 }
 
@@ -514,17 +513,17 @@ get_num_cpus(PyObject* self, PyObject* a
 static PyObject*
 get_process_create_time(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("d", TV2DOUBLE(kp.ki_start));
 }
 
 
 /*
  * Return a Python float indicating the process create time expressed in
@@ -533,17 +532,17 @@ get_process_create_time(PyObject* self, 
 static PyObject*
 get_process_io_counters(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     // there's apparently no way to determine bytes count, hence return -1.
     return Py_BuildValue("(llll)", kp.ki_rusage.ru_inblock,
                                    kp.ki_rusage.ru_oublock,
                                    -1, -1);
 }
 
@@ -554,52 +553,58 @@ get_process_io_counters(PyObject* self, 
 static PyObject*
 get_process_memory_info(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("(lllll)", ptoa(kp.ki_rssize),    // rss
                                     (long)kp.ki_size,      // vms
                                     ptoa(kp.ki_tsize),     // text
                                     ptoa(kp.ki_dsize),     // data
                                     ptoa(kp.ki_ssize));    // stack
 }
 
 
 /*
  * Return virtual memory usage statistics.
  */
 static PyObject*
 get_virtual_mem(PyObject* self, PyObject* args)
 {
-    unsigned int   total, active, inactive, wired, cached, free, buffers;
-    size_t		   size = sizeof(total);
-	struct vmtotal vm;
-	int            mib[] = {CTL_VM, VM_METER};
-	long           pagesize = getpagesize();
+    unsigned int   total, active, inactive, wired, cached, free;
+    size_t         size = sizeof(total);
+    struct vmtotal vm;
+    int            mib[] = {CTL_VM, VM_METER};
+    long           pagesize = getpagesize();
+#if __FreeBSD_version > 702101
+    long buffers;
+#else
+    int buffers;
+#endif
+    size_t buffers_size = sizeof(buffers);
 
     if (sysctlbyname("vm.stats.vm.v_page_count", &total, &size, NULL, 0))
         goto error;
     if (sysctlbyname("vm.stats.vm.v_active_count", &active, &size, NULL, 0))
         goto error;
     if (sysctlbyname("vm.stats.vm.v_inactive_count", &inactive, &size, NULL, 0))
         goto error;
     if (sysctlbyname("vm.stats.vm.v_wire_count", &wired, &size, NULL, 0))
         goto error;
     if (sysctlbyname("vm.stats.vm.v_cache_count", &cached, &size, NULL, 0))
         goto error;
     if (sysctlbyname("vm.stats.vm.v_free_count", &free, &size, NULL, 0))
         goto error;
-    if (sysctlbyname("vfs.bufspace", &buffers, &size, NULL, 0))
+    if (sysctlbyname("vfs.bufspace", &buffers, &buffers_size, NULL, 0))
         goto error;
 
     size = sizeof(vm);
     if (sysctl(mib, 2, &vm, &size, NULL, 0) != 0)
         goto error;
 
     return Py_BuildValue("KKKKKKKK",
         (unsigned long long) total    * pagesize,
@@ -613,32 +618,45 @@ get_virtual_mem(PyObject* self, PyObject
     );
 
 error:
     PyErr_SetFromErrno(0);
     return NULL;
 }
 
 
+#ifndef _PATH_DEVNULL
+#define _PATH_DEVNULL "/dev/null"
+#endif
+
 /*
  * Return swap memory stats (see 'swapinfo' cmdline tool)
  */
 static PyObject*
 get_swap_mem(PyObject* self, PyObject* args)
 {
     kvm_t *kd;
     struct kvm_swap kvmsw[1];
     unsigned int swapin, swapout, nodein, nodeout;
     size_t size = sizeof(unsigned int);
 
+    kd = kvm_open(NULL, _PATH_DEVNULL, NULL, O_RDONLY, "kvm_open failed");
+    if (kd == NULL) {
+        PyErr_SetString(PyExc_RuntimeError, "kvm_open failed");
+        return NULL;
+    }
+
     if (kvm_getswapinfo(kd, kvmsw, 1, 0) < 0) {
+        kvm_close(kd);
         PyErr_SetString(PyExc_RuntimeError, "kvm_getswapinfo failed");
         return NULL;
     }
 
+    kvm_close(kd);
+
     if (sysctlbyname("vm.stats.vm.v_swapin", &swapin, &size, NULL, 0) == -1)
         goto sbn_error;
     if (sysctlbyname("vm.stats.vm.v_swapout", &swapout, &size, NULL, 0) == -1)
         goto sbn_error;
     if (sysctlbyname("vm.stats.vm.v_vnodein", &nodein, &size, NULL, 0) == -1)
         goto sbn_error;
     if (sysctlbyname("vm.stats.vm.v_vnodeout", &nodeout, &size, NULL, 0) == -1)
         goto sbn_error;
@@ -693,31 +711,32 @@ get_system_cpu_times(PyObject* self, PyO
 /*
  * Return files opened by process as a list of (path, fd) tuples
  */
 static PyObject*
 get_process_open_files(PyObject* self, PyObject* args)
 {
     long pid;
     int i, cnt;
+    struct kinfo_file *freep = NULL;
+    struct kinfo_file *kif;
+    struct kinfo_proc kipp;
     PyObject *retList = PyList_New(0);
     PyObject *tuple = NULL;
 
-    struct kinfo_file *freep = NULL;
-    struct kinfo_file *kif;
-    struct kinfo_proc kipp;
-
+    if (retList == NULL)
+        return NULL;
     if (! PyArg_ParseTuple(args, "l", &pid))
         goto error;
-    if (get_kinfo_proc(pid, &kipp) == -1)
+    if (psutil_get_kinfo_proc(pid, &kipp) == -1)
         goto error;
 
     freep = kinfo_getfile(pid, &cnt);
     if (freep == NULL) {
-        PyErr_SetFromErrno(0);
+        psutil_raise_ad_or_nsp(pid);
         goto error;
     }
 
     for (i = 0; i < cnt; i++) {
         kif = &freep[i];
         if ((kif->kf_type == KF_TYPE_VNODE) &&
             (kif->kf_vnode_type == KF_VTYPE_VREG))
         {
@@ -750,22 +769,22 @@ get_process_num_fds(PyObject* self, PyOb
     long pid;
     int cnt;
 
     struct kinfo_file *freep;
     struct kinfo_proc kipp;
 
     if (! PyArg_ParseTuple(args, "l", &pid))
         return NULL;
-    if (get_kinfo_proc(pid, &kipp) == -1)
+    if (psutil_get_kinfo_proc(pid, &kipp) == -1)
         return NULL;
 
     freep = kinfo_getfile(pid, &cnt);
     if (freep == NULL) {
-        PyErr_SetFromErrno(0);
+        psutil_raise_ad_or_nsp(pid);
         return NULL;
     }
     free(freep);
 
     return Py_BuildValue("i", cnt);
 }
 
 
@@ -780,22 +799,22 @@ get_process_cwd(PyObject* self, PyObject
     struct kinfo_file *freep = NULL;
     struct kinfo_file *kif;
     struct kinfo_proc kipp;
 
     int i, cnt;
 
     if (! PyArg_ParseTuple(args, "l", &pid))
         goto error;
-    if (get_kinfo_proc(pid, &kipp) == -1)
+    if (psutil_get_kinfo_proc(pid, &kipp) == -1)
         goto error;
 
     freep = kinfo_getfile(pid, &cnt);
     if (freep == NULL) {
-        PyErr_SetFromErrno(0);
+        psutil_raise_ad_or_nsp(pid);
         goto error;
     }
 
     for (i = 0; i < cnt; i++) {
         kif = &freep[i];
         if (kif->kf_fd == KF_FD_TYPE_CWD) {
             path = Py_BuildValue("s", kif->kf_path);
             if (!path)
@@ -851,281 +870,296 @@ get_connection_status(int st) {
             return "LAST_ACK";
         case TCPS_TIME_WAIT:
             return "TIME_WAIT";
         default:
             return "?";
     }
 }
 
-// a kvm_read that returns true if everything is read
-#define KVM_READ(kaddr, paddr, len) \
-    ((len) < SSIZE_MAX && \
-    kvm_read(kd, (u_long)(kaddr), (char *)(paddr), (len)) == (ssize_t)(len))
+/* The tcplist fetching and walking is borrowed from netstat/inet.c. */
+static char *
+psutil_fetch_tcplist(void)
+{
+    char *buf;
+    size_t len;
+    int error;
+
+    for (;;) {
+        if (sysctlbyname("net.inet.tcp.pcblist", NULL, &len, NULL, 0) < 0) {
+            PyErr_SetFromErrno(0);
+            return NULL;
+        }
+        buf = malloc(len);
+        if (buf == NULL) {
+            PyErr_NoMemory();
+            return NULL;
+        }
+        if (sysctlbyname("net.inet.tcp.pcblist", buf, &len, NULL, 0) < 0) {
+            free(buf);
+            PyErr_SetFromErrno(0);
+            return NULL;
+        }
+        return buf;
+    }
+}
+
+static int
+psutil_sockaddr_port(int family, struct sockaddr_storage *ss)
+{
+    struct sockaddr_in6 *sin6;
+    struct sockaddr_in *sin;
+
+    if (family == AF_INET) {
+        sin = (struct sockaddr_in *)ss;
+        return (sin->sin_port);
+    } else {
+        sin6 = (struct sockaddr_in6 *)ss;
+        return (sin6->sin6_port);
+    }
+}
+
+static void *
+psutil_sockaddr_addr(int family, struct sockaddr_storage *ss)
+{
+    struct sockaddr_in6 *sin6;
+    struct sockaddr_in *sin;
+
+    if (family == AF_INET) {
+        sin = (struct sockaddr_in *)ss;
+        return (&sin->sin_addr);
+    } else {
+        sin6 = (struct sockaddr_in6 *)ss;
+        return (&sin6->sin6_addr);
+    }
+}
 
-// XXX - copied from sys/file.h to make compiler happy
-struct file {
-    void        *f_data;    /* file descriptor specific data */
-    struct fileops  *f_ops;     /* File operations */
-    struct ucred    *f_cred;    /* associated credentials. */
-    struct vnode    *f_vnode;   /* NULL or applicable vnode */
-    short       f_type;     /* descriptor type */
-    short       f_vnread_flags; /* (f) Sleep lock for f_offset */
-    volatile u_int  f_flag;     /* see fcntl.h */
-    volatile u_int  f_count;    /* reference count */
-    int     f_seqcount; /* Count of sequential accesses. */
-    off_t       f_nextoff;  /* next expected read/write offset. */
-    struct cdev_privdata *f_cdevpriv; /* (d) Private data for the cdev. */
-    off_t       f_offset;
-    void        *f_label;   /* Place-holder for MAC label. */
-};
+static socklen_t
+psutil_sockaddr_addrlen(int family)
+{
+    if (family == AF_INET)
+        return (sizeof(struct in_addr));
+    else
+        return (sizeof(struct in6_addr));
+}
+
+static int
+psutil_sockaddr_matches(int family, int port, void *pcb_addr,
+                        struct sockaddr_storage *ss)
+{
+    if (psutil_sockaddr_port(family, ss) != port)
+        return (0);
+    return (memcmp(psutil_sockaddr_addr(family, ss), pcb_addr,
+        psutil_sockaddr_addrlen(family)) == 0);
+}
+
+static struct tcpcb *
+psutil_search_tcplist(char *buf, struct kinfo_file *kif)
+{
+    struct tcpcb *tp;
+    struct inpcb *inp;
+    struct xinpgen *xig, *oxig;
+    struct xsocket *so;
 
+    oxig = xig = (struct xinpgen *)buf;
+    for (xig = (struct xinpgen *)((char *)xig + xig->xig_len);
+         xig->xig_len > sizeof(struct xinpgen);
+         xig = (struct xinpgen *)((char *)xig + xig->xig_len)) {
+        tp = &((struct xtcpcb *)xig)->xt_tp;
+        inp = &((struct xtcpcb *)xig)->xt_inp;
+        so = &((struct xtcpcb *)xig)->xt_socket;
+
+        if (so->so_type != kif->kf_sock_type ||
+            so->xso_family != kif->kf_sock_domain ||
+            so->xso_protocol != kif->kf_sock_protocol)
+                continue;
+
+        if (kif->kf_sock_domain == AF_INET) {
+            if (!psutil_sockaddr_matches(AF_INET, inp->inp_lport, &inp->inp_laddr,
+                &kif->kf_sa_local))
+                continue;
+            if (!psutil_sockaddr_matches(AF_INET, inp->inp_fport, &inp->inp_faddr,
+                &kif->kf_sa_peer))
+                continue;
+        } else {
+            if (!psutil_sockaddr_matches(AF_INET6, inp->inp_lport, &inp->in6p_laddr,
+                &kif->kf_sa_local))
+                continue;
+            if (!psutil_sockaddr_matches(AF_INET6, inp->inp_fport, &inp->in6p_faddr,
+                &kif->kf_sa_peer))
+                continue;
+        }
+
+        return (tp);
+    }
+    return NULL;
+}
 
 /*
  * Return connections opened by process.
- * fstat.c source code was used as an example.
  */
 static PyObject*
 get_process_connections(PyObject* self, PyObject* args)
 {
     long pid;
-    struct kinfo_proc *p;
-    struct file **ofiles = NULL;
-    char buf[_POSIX2_LINE_MAX];
-    char path[PATH_MAX];
-    int cnt;
-    int i;
-    kvm_t *kd = NULL;
-    struct file file;
-    struct filedesc filed;
-    struct nlist nl[] = {{ "" },};
-    struct socket   so;
-    struct protosw  proto;
-    struct domain   dom;
-    struct inpcb    inpcb;
-    struct tcpcb    tcpcb;
-    struct unpcb    unpcb;
+    int i, cnt;
+
+    struct kinfo_file *freep = NULL;
+    struct kinfo_file *kif;
+    struct kinfo_proc kipp;
+    char *tcplist = NULL;
+    struct tcpcb *tcp;
 
     PyObject *retList = PyList_New(0);
     PyObject *tuple = NULL;
     PyObject *laddr = NULL;
     PyObject *raddr = NULL;
     PyObject *af_filter = NULL;
     PyObject *type_filter = NULL;
     PyObject* _family = NULL;
     PyObject* _type = NULL;
 
+    if (retList == NULL) {
+        return NULL;
+    }
     if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter)) {
         goto error;
     }
     if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
         PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
         goto error;
     }
 
-    kd = kvm_openfiles(NULL, NULL, NULL, O_RDONLY, buf);
-    if (kd == NULL) {
-        AccessDenied();
+    if (psutil_get_kinfo_proc(pid, &kipp) == -1) {
         goto error;
     }
 
-    if (kvm_nlist(kd, nl) != 0) {
-        PyErr_SetString(PyExc_RuntimeError, "kvm_nlist() failed");
+    freep = kinfo_getfile(pid, &cnt);
+    if (freep == NULL) {
+        psutil_raise_ad_or_nsp(pid);
         goto error;
     }
 
-    p = kvm_getprocs(kd, KERN_PROC_PID, pid, &cnt);
-    if (p == NULL) {
-        NoSuchProcess();
-        goto error;
-    }
-    if (cnt != 1) {
-        NoSuchProcess();
-        goto error;
-    }
-    if (p->ki_fd == NULL) {
-        PyErr_SetString(PyExc_RuntimeError, "no usable fd found");
-        goto error;
-    }
-    if (!KVM_READ(p->ki_fd, &filed, sizeof(filed))) {
-        PyErr_SetString(PyExc_RuntimeError, "kvm_read() failed");
+    tcplist = psutil_fetch_tcplist();
+    if (tcplist == NULL) {
+        PyErr_SetFromErrno(0);
         goto error;
     }
 
-    ofiles = malloc((filed.fd_lastfile+1) * sizeof(struct file *));
-    if (ofiles == NULL) {
-        PyErr_SetString(PyExc_RuntimeError, "malloc() failed");
-        goto error;
-    }
-
-    if (!KVM_READ(filed.fd_ofiles, ofiles,
-                  (filed.fd_lastfile+1) * sizeof(struct file *))) {
-        PyErr_SetString(PyExc_RuntimeError, "kvm_read() failed");
-        goto error;
-    }
-
-    for (i = 0; i <= filed.fd_lastfile; i++) {
+    for (i = 0; i < cnt; i++) {
         int lport, rport;
         char lip[200], rip[200];
+        char path[PATH_MAX];
         char *state;
         int inseq;
         tuple = NULL;
         laddr = NULL;
         raddr = NULL;
 
-        if (ofiles[i] == NULL) {
-            continue;
-        }
-        if (!KVM_READ(ofiles[i], &file, sizeof (struct file))) {
-            PyErr_SetString(PyExc_RuntimeError, "kvm_read() file failed");
-            goto error;
-        }
-        if (file.f_type == DTYPE_SOCKET) {
-            // fill in socket
-            if (!KVM_READ(file.f_data, &so, sizeof(struct socket))) {
-                PyErr_SetString(PyExc_RuntimeError, "kvm_read() socket failed");
-                goto error;
-            }
-            // fill in protosw entry
-            if (!KVM_READ(so.so_proto, &proto, sizeof(struct protosw))) {
-                PyErr_SetString(PyExc_RuntimeError, "kvm_read() proto failed");
-                goto error;
-            }
-            // fill in domain
-            if (!KVM_READ(proto.pr_domain, &dom, sizeof(struct domain))) {
-                PyErr_SetString(PyExc_RuntimeError, "kvm_read() domain failed");
-                goto error;
-            }
-
+        kif = &freep[i];
+        if (kif->kf_type == KF_TYPE_SOCKET)
+        {
             // apply filters
-            _family = PyLong_FromLong((long)dom.dom_family);
+            _family = PyLong_FromLong((long)kif->kf_sock_domain);
             inseq = PySequence_Contains(af_filter, _family);
             Py_DECREF(_family);
             if (inseq == 0) {
                 continue;
             }
-            _type = PyLong_FromLong((long)proto.pr_type);
+            _type = PyLong_FromLong((long)kif->kf_sock_type);
             inseq = PySequence_Contains(type_filter, _type);
             Py_DECREF(_type);
             if (inseq == 0) {
                 continue;
             }
 
             // IPv4 / IPv6 socket
-            if ((dom.dom_family == AF_INET) || (dom.dom_family == AF_INET6)) {
-                // fill inpcb
-                if (kvm_read(kd, (u_long)so.so_pcb, (char *)&inpcb,
-                             sizeof(struct inpcb)) != sizeof(struct inpcb)) {
-                    PyErr_SetString(PyExc_RuntimeError, "kvm_read() addr failed");
-                    goto error;
-                }
-
+            if ((kif->kf_sock_domain == AF_INET) ||
+                (kif->kf_sock_domain == AF_INET6)) {
                 // fill status
-                if (proto.pr_type == SOCK_STREAM) {
-                    if (kvm_read(kd, (u_long)inpcb.inp_ppcb, (char *)&tcpcb,
-                                 sizeof(struct tcpcb)) != sizeof(struct tcpcb)) {
-                        PyErr_SetString(PyExc_RuntimeError, "kvm_read() state failed");
-                        goto error;
-                    }
-                    state = get_connection_status((int)tcpcb.t_state);
-                }
-                else {
-                    state = "";
+                state = "";
+                if (kif->kf_sock_type == SOCK_STREAM) {
+                    tcp = psutil_search_tcplist(tcplist, kif);
+                    if (tcp != NULL)
+                        state = get_connection_status((int)tcp->t_state);
                 }
 
                 // build addr and port
-                if (dom.dom_family == AF_INET) {
-                    inet_ntop(AF_INET, &inpcb.inp_laddr.s_addr, lip, sizeof(lip));
-                    inet_ntop(AF_INET, &inpcb.inp_faddr.s_addr, rip, sizeof(rip));
-                }
-                else {
-                    inet_ntop(AF_INET6, &inpcb.in6p_laddr.s6_addr, lip, sizeof(lip));
-                    inet_ntop(AF_INET6, &inpcb.in6p_faddr.s6_addr, rip, sizeof(rip));
-                }
-                lport = ntohs(inpcb.inp_lport);
-                rport = ntohs(inpcb.inp_fport);
+                inet_ntop(kif->kf_sock_domain,
+                    psutil_sockaddr_addr(kif->kf_sock_domain, &kif->kf_sa_local),
+                    lip, sizeof(lip));
+                inet_ntop(kif->kf_sock_domain,
+                    psutil_sockaddr_addr(kif->kf_sock_domain, &kif->kf_sa_peer),
+                    rip, sizeof(rip));
+                lport = htons(psutil_sockaddr_port(kif->kf_sock_domain,
+                                                   &kif->kf_sa_local));
+                rport = htons(psutil_sockaddr_port(kif->kf_sock_domain,
+                                                   &kif->kf_sa_peer));
 
-                // contruct python tuple/list
+                // construct python tuple/list
                 laddr = Py_BuildValue("(si)", lip, lport);
                 if (!laddr)
                     goto error;
                 if (rport != 0) {
                     raddr = Py_BuildValue("(si)", rip, rport);
                 }
                 else {
                     raddr = Py_BuildValue("()");
                 }
                 if (!raddr)
                     goto error;
-                tuple = Py_BuildValue("(iiiNNs)", i,
-                                                  dom.dom_family,
-                                                  proto.pr_type,
+                tuple = Py_BuildValue("(iiiNNs)", kif->kf_fd,
+                                                  kif->kf_sock_domain,
+                                                  kif->kf_sock_type,
                                                   laddr,
                                                   raddr,
                                                   state);
                 if (!tuple)
                     goto error;
                 if (PyList_Append(retList, tuple))
                     goto error;
                 Py_DECREF(tuple);
             }
             // UNIX socket
-            else if (dom.dom_family == AF_UNIX) {
-                struct sockaddr_un sun;
-                path[0] = '\0';
+            else if (kif->kf_sock_domain == AF_UNIX) {
+                struct sockaddr_un *sun;
 
-                if (kvm_read(kd, (u_long)so.so_pcb, (char *)&unpcb,
-                             sizeof(struct unpcb)) != sizeof(struct unpcb)) {
-                    PyErr_SetString(PyExc_RuntimeError, "kvm_read() unpcb failed");
-                    goto error;
-                }
-                if (unpcb.unp_addr) {
-                    if (kvm_read(kd, (u_long)unpcb.unp_addr, (char *)&sun,
-                                 sizeof(sun)) != sizeof(sun)) {
-                        PyErr_SetString(PyExc_RuntimeError,
-                                        "kvm_read() sockaddr_un failed");
-                        goto error;
-                    }
-                    sprintf(path, "%.*s",
-                            (sun.sun_len - (sizeof(sun) - sizeof(sun.sun_path))),
-                             sun.sun_path);
-                }
+                sun = (struct sockaddr_un *)&kif->kf_sa_local;
+                snprintf(path, sizeof(path), "%.*s",
+                        (sun->sun_len - (sizeof(*sun) - sizeof(sun->sun_path))),
+                         sun->sun_path);
 
-                tuple = Py_BuildValue("(iiisOs)", i,
-                                                  dom.dom_family,
-                                                  proto.pr_type,
+                tuple = Py_BuildValue("(iiisOs)", kif->kf_fd,
+                                                  kif->kf_sock_domain,
+                                                  kif->kf_sock_type,
                                                   path,
                                                   Py_None,
                                                   "");
                 if (!tuple)
                     goto error;
                 if (PyList_Append(retList, tuple))
                     goto error;
                 Py_DECREF(tuple);
                 Py_INCREF(Py_None);
             }
         }
     }
-
-    free(ofiles);
-    kvm_close(kd);
+    free(freep);
+    free(tcplist);
     return retList;
 
 error:
     Py_XDECREF(tuple);
     Py_XDECREF(laddr);
     Py_XDECREF(raddr);
     Py_DECREF(retList);
-
-    if (kd != NULL) {
-        kvm_close(kd);
-    }
-    if (ofiles != NULL) {
-        free(ofiles);
-    }
+    if (freep != NULL)
+        free(freep);
+    if (tcplist != NULL)
+        free(tcplist);
     return NULL;
 }
 
 
 /*
  * Return a Python list of tuple representing per-cpu times
  */
 static PyObject*
@@ -1135,16 +1169,19 @@ get_system_per_cpu_times(PyObject* self,
     int mib[2];
     int ncpu;
     size_t len;
     size_t size;
     int i;
     PyObject* py_retlist = PyList_New(0);
     PyObject* py_cputime = NULL;
 
+    if (py_retlist == NULL)
+        return NULL;
+
     // retrieve maxcpus value
     size = sizeof(maxcpus);
     if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) {
         Py_DECREF(py_retlist);
         PyErr_SetFromErrno(0);
         return NULL;
     }
     long cpu_time[maxcpus][CPUSTATES];
@@ -1184,63 +1221,77 @@ get_system_per_cpu_times(PyObject* self,
 
 error:
     Py_XDECREF(py_cputime);
     Py_DECREF(py_retlist);
     return NULL;
 }
 
 
+// remove spaces from string
+void remove_spaces(char *str) {
+    char *p1 = str;
+    char *p2 = str;
+    do
+        while (*p2 == ' ')
+            p2++;
+    while (*p1++ = *p2++);
+}
+
 /*
  * Return a list of tuples for every process memory maps.
  * 'procstat' cmdline utility has been used as an example.
  */
 static PyObject*
 get_process_memory_maps(PyObject* self, PyObject* args)
 {
     long pid;
     int ptrwidth;
     int i, cnt;
     char addr[30];
-    char perms[10];
+    char perms[4];
     const char *path;
     struct kinfo_proc kp;
     struct kinfo_vmentry *freep = NULL;
     struct kinfo_vmentry *kve;
+    ptrwidth = 2*sizeof(void *);
     PyObject* pytuple = NULL;
     PyObject* retlist = PyList_New(0);
 
-    ptrwidth = 2*sizeof(void *);
-
+    if (retlist == NULL) {
+        return NULL;
+    }
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         goto error;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         goto error;
     }
 
     freep = kinfo_getvmmap(pid, &cnt);
     if (freep == NULL) {
-        PyErr_SetString(PyExc_RuntimeError, "kinfo_getvmmap() failed");
+        psutil_raise_ad_or_nsp(pid);
         goto error;
     }
     for (i = 0; i < cnt; i++) {
         pytuple = NULL;
         kve = &freep[i];
         addr[0] = '\0';
         perms[0] = '\0';
         sprintf(addr, "%#*jx-%#*jx", ptrwidth, (uintmax_t)kve->kve_start,
                                      ptrwidth, (uintmax_t)kve->kve_end);
+        remove_spaces(addr);
         strlcat(perms, kve->kve_protection & KVME_PROT_READ ? "r" : "-",
                 sizeof(perms));
         strlcat(perms, kve->kve_protection & KVME_PROT_WRITE ? "w" : "-",
                 sizeof(perms));
         strlcat(perms, kve->kve_protection & KVME_PROT_EXEC ? "x" : "-",
                 sizeof(perms));
 
+
         if (strlen(kve->kve_path) == 0) {
             switch (kve->kve_type) {
             case KVME_TYPE_NONE:
                 path = "[none]";
                 break;
             case KVME_TYPE_DEFAULT:
                 path = "[default]";
                 break;
@@ -1313,27 +1364,34 @@ get_disk_partitions(PyObject* self, PyOb
     int i;
     long len;
     uint64_t flags;
     char opts[200];
     struct statfs *fs = NULL;
     PyObject* py_retlist = PyList_New(0);
     PyObject* py_tuple = NULL;
 
+    if (py_retlist == NULL)
+        return NULL;
+
     // get the number of mount points
     Py_BEGIN_ALLOW_THREADS
     num = getfsstat(NULL, 0, MNT_NOWAIT);
     Py_END_ALLOW_THREADS
     if (num == -1) {
         PyErr_SetFromErrno(0);
         goto error;
     }
 
     len = sizeof(*fs) * num;
     fs = malloc(len);
+    if (fs == NULL) {
+        PyErr_NoMemory();
+        goto error;
+    }
 
     Py_BEGIN_ALLOW_THREADS
     num = getfsstat(fs, len, MNT_NOWAIT);
     Py_END_ALLOW_THREADS
     if (num == -1) {
         PyErr_SetFromErrno(0);
         goto error;
     }
@@ -1403,38 +1461,42 @@ error:
 
 
 /*
  * Return a Python list of named tuples with overall network I/O information
  */
 static PyObject*
 get_network_io_counters(PyObject* self, PyObject* args)
 {
-    PyObject* py_retdict = PyDict_New();
-    PyObject* py_ifc_info = NULL;
-
     char *buf = NULL, *lim, *next;
     struct if_msghdr *ifm;
     int mib[6];
     size_t len;
+    PyObject* py_retdict = PyDict_New();
+    PyObject* py_ifc_info = NULL;
+    if (py_retdict == NULL)
+        return NULL;
 
     mib[0] = CTL_NET;          // networking subsystem
     mib[1] = PF_ROUTE;         // type of information
     mib[2] = 0;                // protocol (IPPROTO_xxx)
     mib[3] = 0;                // address family
     mib[4] = NET_RT_IFLIST;   // operation
     mib[5] = 0;
 
     if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
         PyErr_SetFromErrno(0);
         goto error;
     }
 
-
     buf = malloc(len);
+    if (buf == NULL) {
+        PyErr_NoMemory();
+        goto error;
+    }
 
     if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
         PyErr_SetFromErrno(0);
         goto error;
     }
 
     lim = buf + len;
 
@@ -1445,16 +1507,22 @@ get_network_io_counters(PyObject* self, 
 
         if (ifm->ifm_type == RTM_IFINFO) {
             struct if_msghdr *if2m = (struct if_msghdr *)ifm;
             struct sockaddr_dl *sdl = (struct sockaddr_dl *)(if2m + 1);
             char ifc_name[32];
 
             strncpy(ifc_name, sdl->sdl_data, sdl->sdl_nlen);
             ifc_name[sdl->sdl_nlen] = 0;
+            // XXX: ignore usbus interfaces:
+            // http://lists.freebsd.org/pipermail/freebsd-current/2011-October/028752.html
+            // 'ifconfig -a' doesn't show them, nor do we.
+            if (strncmp(ifc_name, "usbus", 5) == 0) {
+                continue;
+            }
 
             py_ifc_info = Py_BuildValue("(kkkkkkki)",
                                         if2m->ifm_data.ifi_obytes,
                                         if2m->ifm_data.ifi_ibytes,
                                         if2m->ifm_data.ifi_opackets,
                                         if2m->ifm_data.ifi_ipackets,
                                         if2m->ifm_data.ifi_ierrors,
                                         if2m->ifm_data.ifi_oerrors,
@@ -1484,28 +1552,34 @@ error:
 
 
 /*
  * Return a Python dict of tuples for disk I/O information
  */
 static PyObject*
 get_disk_io_counters(PyObject* self, PyObject* args)
 {
+    int i;
+    struct statinfo stats;
+
     PyObject* py_retdict = PyDict_New();
     PyObject* py_disk_info = NULL;
-
-    int i;
-    struct statinfo stats;
+    if (py_retdict == NULL)
+        return NULL;
 
     if (devstat_checkversion(NULL) < 0) {
         PyErr_Format(PyExc_RuntimeError, "devstat_checkversion() failed");
         goto error;
     }
 
     stats.dinfo = (struct devinfo *)malloc(sizeof(struct devinfo));
+    if (stats.dinfo == NULL) {
+        PyErr_NoMemory();
+        goto error;
+    }
     bzero(stats.dinfo, sizeof(struct devinfo));
 
     if (devstat_getdevs(NULL, &stats) == -1) {
         PyErr_Format(PyExc_RuntimeError, "devstat_getdevs() failed");
         goto error;
     }
 
     for (i = 0; i < stats.dinfo->numdevs; i++) {
@@ -1553,16 +1627,19 @@ error:
  * Return currently connected users as a list of tuples.
  */
 static PyObject*
 get_system_users(PyObject* self, PyObject* args)
 {
     PyObject *ret_list = PyList_New(0);
     PyObject *tuple = NULL;
 
+    if (ret_list == NULL)
+        return NULL;
+
 #if __FreeBSD_version < 900000
     struct utmp ut;
     FILE *fp;
 
     fp = fopen(_PATH_UTMP, "r");
     if (fp == NULL) {
         PyErr_SetFromErrno(0);
         goto error;
@@ -1687,18 +1764,17 @@ PsutilMethods[] =
          "Return swap mem stats"},
      {"get_system_cpu_times", get_system_cpu_times, METH_VARARGS,
          "Return system cpu times as a tuple (user, system, nice, idle, irc)"},
 #if defined(__FreeBSD_version) && __FreeBSD_version >= 800000
      {"get_system_per_cpu_times", get_system_per_cpu_times, METH_VARARGS,
          "Return system per-cpu times as a list of tuples"},
 #endif
      {"get_system_boot_time", get_system_boot_time, METH_VARARGS,
-         "Return a float indicating the system boot time expressed in "
-         "seconds since the epoch"},
+         "Return the system boot time expressed in seconds since the epoch."},
      {"get_disk_partitions", get_disk_partitions, METH_VARARGS,
          "Return a list of tuples including device, mount point and "
          "fs type for all partitions mounted on the system."},
      {"get_network_io_counters", get_network_io_counters, METH_VARARGS,
          "Return dict of tuples of networks I/O information."},
      {"get_disk_io_counters", get_disk_io_counters, METH_VARARGS,
          "Return a Python dict of tuples for disk I/O information"},
      {"get_system_users", get_system_users, METH_VARARGS,
--- a/python/psutil/psutil/_psutil_bsd.h
+++ b/python/psutil/psutil/_psutil_bsd.h
@@ -1,11 +1,9 @@
 /*
- * $Id: _psutil_bsd.h 1498 2012-07-24 21:41:28Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * BSD platform-specific module methods for _psutil_bsd
  */
 
 #include <Python.h>
--- a/python/psutil/psutil/_psutil_common.c
+++ b/python/psutil/psutil/_psutil_common.c
@@ -1,11 +1,9 @@
 /*
- * $Id: _psutil_common.c 1142 2011-10-05 18:45:49Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * Routines common to all platforms.
  */
 
 #include <Python.h>
@@ -31,9 +29,8 @@ PyObject *
 AccessDenied(void) {
     PyObject *exc;
     char *msg = strerror(EACCES);
     exc = PyObject_CallFunction(PyExc_OSError, "(is)", EACCES, msg);
     PyErr_SetObject(PyExc_OSError, exc);
     Py_XDECREF(exc);
     return NULL;
 }
-
--- a/python/psutil/psutil/_psutil_common.h
+++ b/python/psutil/psutil/_psutil_common.h
@@ -1,11 +1,9 @@
 /*
- * $Id: _psutil_common.h 1142 2011-10-05 18:45:49Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
 
 #include <Python.h>
 
 PyObject* NoSuchProcess(void);
--- a/python/psutil/psutil/_psutil_linux.c
+++ b/python/psutil/psutil/_psutil_linux.c
@@ -1,11 +1,9 @@
 /*
- * $Id: _psutil_linux.c 1498 2012-07-24 21:41:28Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * Linux-specific functions.
  */
 
 #include <Python.h>
@@ -102,16 +100,19 @@ linux_ioprio_set(PyObject* self, PyObjec
 static PyObject*
 get_disk_partitions(PyObject* self, PyObject* args)
 {
     FILE *file = NULL;
     struct mntent *entry;
     PyObject* py_retlist = PyList_New(0);
     PyObject* py_tuple = NULL;
 
+    if (py_retlist == NULL)
+        return NULL;
+
     // MOUNTED constant comes from mntent.h and it's == '/etc/mtab'
     Py_BEGIN_ALLOW_THREADS
     file = setmntent(MOUNTED, "r");
     Py_END_ALLOW_THREADS
     if ((file == 0) || (file == NULL)) {
         PyErr_SetFromErrno(PyExc_OSError);
         goto error;
     }
@@ -148,24 +149,25 @@ error:
  */
 static PyObject*
 get_sysinfo(PyObject* self, PyObject* args)
 {
     struct sysinfo info;
     if (sysinfo(&info) != 0) {
         return PyErr_SetFromErrno(PyExc_OSError);
     }
+
+    // note: BOOT_TIME might also be determined from here
     return Py_BuildValue("(KKKKKK)",
         (unsigned long long)info.totalram  * info.mem_unit,   // total
         (unsigned long long)info.freeram   * info.mem_unit,   // free
         (unsigned long long)info.bufferram * info.mem_unit,   // buffer
         (unsigned long long)info.sharedram * info.mem_unit,   // shared
         (unsigned long long)info.totalswap * info.mem_unit,   // swap tot
         (unsigned long long)info.freeswap  * info.mem_unit);  // swap free
-    // TODO: we can also determine BOOT_TIME here
 }
 
 
 /*
  * Return process CPU affinity as a Python long (the bitmask)
  */
 static PyObject*
 get_process_cpu_affinity(PyObject* self, PyObject* args)
@@ -211,16 +213,19 @@ set_process_cpu_affinity(PyObject* self,
 static PyObject*
 get_system_users(PyObject* self, PyObject* args)
 {
     PyObject *ret_list = PyList_New(0);
     PyObject *tuple = NULL;
     PyObject *user_proc = NULL;
     struct utmp *ut;
 
+    if (ret_list == NULL)
+        return NULL;
+
     setutent();
     while (NULL != (ut = getutent())) {
         tuple = NULL;
         user_proc = NULL;
         if (ut->ut_type == USER_PROCESS)
             user_proc = Py_True;
         else
             user_proc = Py_False;
--- a/python/psutil/psutil/_psutil_linux.h
+++ b/python/psutil/psutil/_psutil_linux.h
@@ -1,11 +1,9 @@
 /*
- * $Id: _psutil_linux.h 1498 2012-07-24 21:41:28Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * LINUX specific module methods for _psutil_linux
  */
 
 #include <Python.h>
--- a/python/psutil/psutil/_psutil_mswindows.c
+++ b/python/psutil/psutil/_psutil_mswindows.c
@@ -1,11 +1,9 @@
 /*
- * $Id: _psutil_mswindows.c 1525 2012-08-16 16:32:03Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * Windows platform-specific module methods for _psutil_mswindows
  */
 
 // Fixes clash between winsock2.h and windows.h
@@ -34,17 +32,17 @@
 #include "arch/mswindows/ntextapi.h"
 
 
 /*
  * Return a Python float representing the system uptime expressed in seconds
  * since the epoch.
  */
 static PyObject*
-get_system_uptime(PyObject* self, PyObject* args)
+get_system_boot_time(PyObject* self, PyObject* args)
 {
     double uptime;
     time_t pt;
     FILETIME fileTime;
     long long ll;
 
     GetSystemTimeAsFileTime(&fileTime);
 
@@ -79,19 +77,19 @@ pid_exists(PyObject* self, PyObject* arg
 {
     long pid;
     int status;
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
 
-    status = pid_is_running(pid);
+    status = psutil_pid_is_running(pid);
     if (-1 == status) {
-        return NULL; // exception raised in pid_is_running()
+        return NULL; // exception raised in psutil_pid_is_running()
     }
     return PyBool_FromLong(status);
 }
 
 
 /*
  * Return a Python list of all the PIDs running on the system.
  */
@@ -99,17 +97,20 @@ static PyObject*
 get_pid_list(PyObject* self, PyObject* args)
 {
     DWORD *proclist = NULL;
     DWORD numberOfReturnedPIDs;
     DWORD i;
     PyObject* pid = NULL;
     PyObject* retlist = PyList_New(0);
 
-    proclist = get_pids(&numberOfReturnedPIDs);
+    if (retlist == NULL) {
+        return NULL;
+    }
+    proclist = psutil_get_pids(&numberOfReturnedPIDs);
     if (NULL == proclist) {
         goto error;
     }
 
     for (i = 0; i < numberOfReturnedPIDs; i++) {
         pid = Py_BuildValue("I", proclist[i]);
         if (!pid)
             goto error;
@@ -243,17 +244,17 @@ get_process_cpu_times(PyObject* self, Py
     long        pid;
     HANDLE      hProcess;
     FILETIME    ftCreate, ftExit, ftKernel, ftUser;
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
 
-    hProcess = handle_from_pid(pid);
+    hProcess = psutil_handle_from_pid(pid);
     if (hProcess == NULL) {
         return NULL;
     }
 
     if (! GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) {
         CloseHandle(hProcess);
         if (GetLastError() == ERROR_ACCESS_DENIED) {
             // usually means the process has died so we throw a NoSuchProcess
@@ -330,20 +331,20 @@ get_process_create_time(PyObject* self, 
     FILETIME    ftCreate, ftExit, ftKernel, ftUser;
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
 
     // special case for PIDs 0 and 4, return BOOT_TIME
     if (0 == pid || 4 == pid) {
-        return get_system_uptime(NULL, NULL);
+        return get_system_boot_time(NULL, NULL);
     }
 
-    hProcess = handle_from_pid(pid);
+    hProcess = psutil_handle_from_pid(pid);
     if (hProcess == NULL) {
         return NULL;
     }
 
     if (! GetProcessTimes(hProcess, &ftCreate, &ftExit, &ftKernel, &ftUser)) {
         CloseHandle(hProcess);
         if (GetLastError() == ERROR_ACCESS_DENIED) {
             // usually means the process has died so we throw a NoSuchProcess here
@@ -402,17 +403,17 @@ get_process_create_time_2(PyObject* self
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
     if (! get_process_info(pid, &process, &buffer)) {
         return NULL;
     }
     // special case for PIDs 0 and 4, return BOOT_TIME
     if (0 == pid || 4 == pid) {
-        return get_system_uptime(NULL, NULL);
+        return get_system_boot_time(NULL, NULL);
     }
     /*
     Convert the LARGE_INTEGER union to a Unix time.
     It's the best I could find by googling and borrowing code here and there.
     The time returned has a precision of 1 second.
     */
     unix_time = ((LONGLONG)process->CreateTime.HighPart) << 32;
     unix_time += process->CreateTime.LowPart - 116444736000000000LL;
@@ -454,27 +455,27 @@ get_process_name(PyObject* self, PyObjec
 
     if (pid == 0) {
         return Py_BuildValue("s", "System Idle Process");
     }
     else if (pid == 4) {
         return Py_BuildValue("s", "System");
     }
 
-    pid_return = pid_is_running(pid);
+    pid_return = psutil_pid_is_running(pid);
     if (pid_return == 0) {
         return NoSuchProcess();
     }
     if (pid_return == -1) {
         return NULL;
     }
 
-    name = get_name(pid);
+    name = psutil_get_name(pid);
     if (name == NULL) {
-        return NULL;  // exception set in get_name()
+        return NULL;  // exception set in psutil_get_name()
     }
     return name;
 }
 
 
 /*
  * Return process parent pid as a Python integer.
  */
@@ -486,27 +487,27 @@ get_process_ppid(PyObject* self, PyObjec
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
     if ((pid == 0) || (pid == 4)) {
         return Py_BuildValue("l", 0);
     }
 
-    pid_return = pid_is_running(pid);
+    pid_return = psutil_pid_is_running(pid);
     if (pid_return == 0) {
         return NoSuchProcess();
     }
     if (pid_return == -1) {
         return NULL;
     }
 
-    ppid = get_ppid(pid);
+    ppid = psutil_get_ppid(pid);
     if (ppid == NULL) {
-        return NULL;  // exception set in get_ppid()
+        return NULL;  // exception set in psutil_get_ppid()
     }
     return ppid;
 }
 
 /*
  * Return process cmdline as a Python list of cmdline arguments.
  */
 static PyObject*
@@ -517,29 +518,29 @@ get_process_cmdline(PyObject* self, PyOb
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
     if ((pid == 0) || (pid == 4)) {
         return Py_BuildValue("[]");
     }
 
-    pid_return = pid_is_running(pid);
+    pid_return = psutil_pid_is_running(pid);
     if (pid_return == 0) {
         return NoSuchProcess();
     }
     if (pid_return == -1) {
         return NULL;
     }
 
     // XXX the assumptio below probably needs to go away
 
     // May fail any of several ReadProcessMemory calls etc. and not indicate
     // a real problem so we ignore any errors and just live without commandline
-    arglist = get_arg_list(pid);
+    arglist = psutil_get_arg_list(pid);
     if ( NULL == arglist ) {
         // carry on anyway, clear any exceptions too
         PyErr_Clear();
         return Py_BuildValue("[]");
     }
 
     return arglist;
 }
@@ -554,17 +555,17 @@ get_process_exe(PyObject* self, PyObject
     HANDLE hProcess;
     wchar_t exe[MAX_PATH];
     DWORD nSize = MAX_PATH;
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
 
-    hProcess = handle_from_pid_waccess(pid, PROCESS_QUERY_INFORMATION);
+    hProcess = psutil_handle_from_pid_waccess(pid, PROCESS_QUERY_INFORMATION);
     if (NULL == hProcess) {
         return NULL;
     }
 
     if (GetProcessImageFileName(hProcess, &exe, nSize) == 0) {
         CloseHandle(hProcess);
         return PyErr_SetFromWindowsErr(0);
     }
@@ -588,17 +589,17 @@ get_process_memory_info(PyObject* self, 
     PROCESS_MEMORY_COUNTERS cnt;
 #endif
     SIZE_T private = 0;
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
 
-    hProcess = handle_from_pid(pid);
+    hProcess = psutil_handle_from_pid(pid);
     if (NULL == hProcess) {
         return NULL;
     }
 
     if (! GetProcessMemoryInfo(hProcess, &cnt, sizeof(cnt)) ) {
         CloseHandle(hProcess);
         return PyErr_SetFromWindowsErr(0);
     }
@@ -727,16 +728,19 @@ get_system_cpu_times(PyObject* self, PyO
     NTQSI_PROC NtQuerySystemInformation;
     HINSTANCE hNtDll;
     SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION *sppi = NULL;
     SYSTEM_INFO si;
     UINT i;
     PyObject *arg = NULL;
     PyObject *retlist = PyList_New(0);
 
+    if (retlist == NULL)
+        return NULL;
+
     // dynamic linking is mandatory to use NtQuerySystemInformation
     hNtDll = LoadLibrary(TEXT("ntdll.dll"));
     if (hNtDll != NULL) {
         // gets NtQuerySystemInformation address
         NtQuerySystemInformation = (NTQSI_PROC)GetProcAddress(
                                     hNtDll, "NtQuerySystemInformation");
 
         if (NtQuerySystemInformation != NULL)
@@ -822,22 +826,22 @@ get_process_cwd(PyObject* self, PyObject
     PyObject *returnPyObj = NULL;
     PyObject *cwd_from_wchar = NULL;
     PyObject *cwd = NULL;
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
 
-    processHandle = handle_from_pid(pid);
+    processHandle = psutil_handle_from_pid(pid);
     if (processHandle == NULL) {
         return NULL;
     }
 
-    pebAddress = GetPebAddress(processHandle);
+    pebAddress = psutil_get_peb_address(processHandle);
 
     // get the address of ProcessParameters
 #ifdef _WIN64
     if (!ReadProcessMemory(processHandle, (PCHAR)pebAddress + 32,
         &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
 #else
     if (!ReadProcessMemory(processHandle, (PCHAR)pebAddress + 0x10,
         &rtlUserProcParamsAddress, sizeof(PVOID), NULL))
@@ -873,16 +877,21 @@ get_process_cwd(PyObject* self, PyObject
         }
         else {
             return PyErr_SetFromWindowsErr(0);
         }
     }
 
     // allocate memory to hold cwd
     currentDirectoryContent = (WCHAR *)malloc(currentDirectory.Length+1);
+    if (currentDirectoryContent == NULL) {
+        PyErr_NoMemory();
+        goto error;
+    }
+
 
     // read cwd
     if (!ReadProcessMemory(processHandle, currentDirectory.Buffer,
         currentDirectoryContent, currentDirectory.Length, NULL))
     {
         if (GetLastError() == ERROR_PARTIAL_COPY) {
             // this occurs quite often with system processes
             AccessDenied();
@@ -1060,37 +1069,40 @@ get_process_num_threads(PyObject* self, 
     free(buffer);
     return Py_BuildValue("i", num);
 }
 
 
 static PyObject*
 get_process_threads(PyObject* self, PyObject* args)
 {
-    PyObject* retList = PyList_New(0);
-    PyObject* pyTuple = NULL;
-    HANDLE hThreadSnap = NULL;
     HANDLE hThread;
     THREADENTRY32 te32 = {0};
     long pid;
     int pid_return;
     int rc;
     FILETIME ftDummy, ftKernel, ftUser;
-
+    PyObject* retList = PyList_New(0);
+    PyObject* pyTuple = NULL;
+    HANDLE hThreadSnap = NULL;
+
+    if (retList == NULL) {
+        return NULL;
+    }
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         goto error;
     }
     if (pid == 0) {
         // raise AD instead of returning 0 as procexp is able to
         // retrieve useful information somehow
         AccessDenied();
         goto error;
     }
 
-    pid_return = pid_is_running(pid);
+    pid_return = psutil_pid_is_running(pid);
     if (pid_return == 0) {
         NoSuchProcess();
         goto error;
     }
     if (pid_return == -1) {
         goto error;
     }
 
@@ -1178,22 +1190,22 @@ get_process_open_files(PyObject* self, P
     HANDLE     processHandle;
     DWORD      access = PROCESS_DUP_HANDLE | PROCESS_QUERY_INFORMATION;
     PyObject*  filesList;
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
 
-    processHandle = handle_from_pid_waccess(pid, access);
+    processHandle = psutil_handle_from_pid_waccess(pid, access);
     if (processHandle == NULL) {
         return NULL;
     }
 
-    filesList = get_open_files(pid, processHandle);
+    filesList = psutil_get_open_files(pid, processHandle);
     CloseHandle(processHandle);
     if (filesList == NULL) {
         return PyErr_SetFromWindowsErr(0);
     }
     return filesList;
 }
 
 
@@ -1247,42 +1259,48 @@ get_process_username(PyObject* self, PyO
     SID_NAME_USE nameUse;
     PTSTR fullName;
     PyObject* returnObject;
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
 
-    processHandle = handle_from_pid_waccess(pid, PROCESS_QUERY_INFORMATION);
+    processHandle = psutil_handle_from_pid_waccess(pid, PROCESS_QUERY_INFORMATION);
     if (processHandle == NULL) {
         return NULL;
     }
 
     if (!OpenProcessToken(processHandle, TOKEN_QUERY, &tokenHandle)) {
         CloseHandle(processHandle);
         return PyErr_SetFromWindowsErr(0);
     }
 
     CloseHandle(processHandle);
 
     /* Get the user SID. */
 
     bufferSize = 0x100;
     user = malloc(bufferSize);
+    if (user == NULL) {
+        return PyErr_NoMemory();
+    }
 
     if (!GetTokenInformation(tokenHandle,
                              TokenUser,
                              user,
                              bufferSize,
                              &bufferSize))
     {
         free(user);
         user = malloc(bufferSize);
-
+        if (user == NULL) {
+            CloseHandle(tokenHandle);
+            return PyErr_NoMemory();
+        }
         if (!GetTokenInformation(tokenHandle,
                                  TokenUser,
                                  user,
                                  bufferSize,
                                  &bufferSize))
         {
             free(user);
             CloseHandle(tokenHandle);
@@ -1293,42 +1311,55 @@ get_process_username(PyObject* self, PyO
     CloseHandle(tokenHandle);
 
     /* Resolve the SID to a name. */
 
     nameSize = 0x100;
     domainNameSize = 0x100;
 
     name = malloc(nameSize * sizeof(TCHAR));
+    if (name == NULL)
+        return PyErr_NoMemory();
     domainName = malloc(domainNameSize * sizeof(TCHAR));
+    if (domainName == NULL)
+        return PyErr_NoMemory();
 
     if (!LookupAccountSid(NULL, user->User.Sid, name, &nameSize, domainName,
                           &domainNameSize, &nameUse))
     {
         free(name);
         free(domainName);
         name = malloc(nameSize * sizeof(TCHAR));
+        if (name == NULL)
+            return PyErr_NoMemory();
         domainName = malloc(domainNameSize * sizeof(TCHAR));
-
+        if (domainName == NULL)
+            return PyErr_NoMemory();
         if (!LookupAccountSid(NULL, user->User.Sid, name, &nameSize, domainName,
                               &domainNameSize, &nameUse))
         {
             free(name);
             free(domainName);
             free(user);
 
             return PyErr_SetFromWindowsErr(0);
         }
     }
 
     nameSize = _tcslen(name);
     domainNameSize = _tcslen(domainName);
 
     /* Build the full username string. */
     fullName = malloc((domainNameSize + 1 + nameSize + 1) * sizeof(TCHAR));
+    if (fullName == NULL) {
+        free(name);
+        free(domainName);
+        free(user);
+        return PyErr_NoMemory();
+    }
     memcpy(fullName, domainName, domainNameSize);
     fullName[domainNameSize] = '\\';
     memcpy(&fullName[domainNameSize + 1], name, nameSize);
     fullName[domainNameSize + 1 + nameSize] = '\0';
 
     returnObject = Py_BuildValue("s", fullName);
 
     free(fullName);
@@ -1497,17 +1528,17 @@ get_process_connections(PyObject* self, 
     }
 
     if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
         ConnDecrefPyObjs();
         PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
         return NULL;
     }
 
-    if (pid_is_running(pid) == 0) {
+    if (psutil_pid_is_running(pid) == 0) {
         ConnDecrefPyObjs();
         return NoSuchProcess();
     }
 
     /* Import some functions. */
     {
         HMODULE ntdll;
         HMODULE iphlpapi;
@@ -1531,31 +1562,39 @@ get_process_connections(PyObject* self, 
     if ((getExtendedTcpTable == NULL) || (getExtendedUdpTable == NULL)) {
         PyErr_SetString(PyExc_NotImplementedError,
                         "feature not supported on this Windows version");
         ConnDecrefPyObjs();
         return NULL;
     }
 
     connectionsList = PyList_New(0);
+    if (connectionsList == NULL) {
+        ConnDecrefPyObjs();
+        return NULL;
+    }
 
     /* TCP IPv4 */
 
     if ((PySequence_Contains(af_filter, _AF_INET) == 1) &&
         (PySequence_Contains(type_filter, _SOCK_STREAM) == 1))
     {
         table = NULL;
         connectionTuple = NULL;
         addressTupleLocal = NULL;
         addressTupleRemote = NULL;
         tableSize = 0;
         getExtendedTcpTable(NULL, &tableSize, FALSE, AF_INET,
                             TCP_TABLE_OWNER_PID_ALL, 0);
 
         table = malloc(tableSize);
+        if (table == NULL) {
+            PyErr_NoMemory();
+            goto error;
+        }
 
         if (getExtendedTcpTable(table, &tableSize, FALSE, AF_INET,
                                 TCP_TABLE_OWNER_PID_ALL, 0) == 0)
         {
             tcp4Table = table;
 
             for (i = 0; i < tcp4Table->dwNumEntries; i++)
             {
@@ -1630,16 +1669,20 @@ get_process_connections(PyObject* self, 
         connectionTuple = NULL;
         addressTupleLocal = NULL;
         addressTupleRemote = NULL;
         tableSize = 0;
         getExtendedTcpTable(NULL, &tableSize, FALSE, AF_INET6,
                             TCP_TABLE_OWNER_PID_ALL, 0);
 
         table = malloc(tableSize);
+        if (table == NULL) {
+            PyErr_NoMemory();
+            goto error;
+        }
 
         if (getExtendedTcpTable(table, &tableSize, FALSE, AF_INET6,
                                  TCP_TABLE_OWNER_PID_ALL, 0) == 0)
         {
             tcp6Table = table;
 
             for (i = 0; i < tcp6Table->dwNumEntries; i++)
             {
@@ -1714,16 +1757,20 @@ get_process_connections(PyObject* self, 
         connectionTuple = NULL;
         addressTupleLocal = NULL;
         addressTupleRemote = NULL;
         tableSize = 0;
         getExtendedUdpTable(NULL, &tableSize, FALSE, AF_INET,
                             UDP_TABLE_OWNER_PID, 0);
 
         table = malloc(tableSize);
+        if (table == NULL) {
+            PyErr_NoMemory();
+            goto error;
+        }
 
         if (getExtendedUdpTable(table, &tableSize, FALSE, AF_INET,
                                  UDP_TABLE_OWNER_PID, 0) == 0)
         {
             udp4Table = table;
 
             for (i = 0; i < udp4Table->dwNumEntries; i++)
             {
@@ -1777,16 +1824,20 @@ get_process_connections(PyObject* self, 
         connectionTuple = NULL;
         addressTupleLocal = NULL;
         addressTupleRemote = NULL;
         tableSize = 0;
         getExtendedUdpTable(NULL, &tableSize, FALSE,
                             AF_INET6, UDP_TABLE_OWNER_PID, 0);
 
         table = malloc(tableSize);
+        if (table == NULL) {
+            PyErr_NoMemory();
+            goto error;
+        }
 
         if (getExtendedUdpTable(table, &tableSize, FALSE, AF_INET6,
                                  UDP_TABLE_OWNER_PID, 0) == 0)
         {
             udp6Table = table;
 
             for (i = 0; i < udp6Table->dwNumEntries; i++)
             {
@@ -1854,17 +1905,17 @@ get_process_priority(PyObject* self, PyO
 {
     long pid;
     DWORD priority;
     HANDLE hProcess;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
 
-    hProcess = handle_from_pid(pid);
+    hProcess = psutil_handle_from_pid(pid);
     if (hProcess == NULL) {
         return NULL;
     }
 
     priority = GetPriorityClass(hProcess);
     CloseHandle(hProcess);
     if (priority == 0) {
         PyErr_SetFromWindowsErr(0);
@@ -1884,46 +1935,123 @@ set_process_priority(PyObject* self, PyO
     int priority;
     int retval;
     HANDLE hProcess;
     DWORD dwDesiredAccess = PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION;
     if (! PyArg_ParseTuple(args, "li", &pid, &priority)) {
         return NULL;
     }
 
-    hProcess = handle_from_pid_waccess(pid, dwDesiredAccess);
+    hProcess = psutil_handle_from_pid_waccess(pid, dwDesiredAccess);
     if (hProcess == NULL) {
         return NULL;
     }
 
     retval = SetPriorityClass(hProcess, priority);
     CloseHandle(hProcess);
     if (retval == 0) {
         PyErr_SetFromWindowsErr(0);
         return NULL;
     }
     Py_INCREF(Py_None);
     return Py_None;
 }
 
 
+#if (_WIN32_WINNT >= 0x0600)  // Windows Vista
+/*
+ * Get process IO priority as a Python integer.
+ */
+static PyObject*
+get_process_io_priority(PyObject* self, PyObject* args)
+{
+    long pid;
+    HANDLE hProcess;
+    PULONG IoPriority;
+
+    _NtQueryInformationProcess NtQueryInformationProcess =
+        (_NtQueryInformationProcess)GetProcAddress(
+        GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");
+
+    if (! PyArg_ParseTuple(args, "l", &pid)) {
+        return NULL;
+    }
+    hProcess = psutil_handle_from_pid(pid);
+    if (hProcess == NULL) {
+        return NULL;
+    }
+
+    NtQueryInformationProcess(
+        hProcess,
+        ProcessIoPriority,
+        &IoPriority,
+        sizeof(ULONG),
+        NULL
+    );
+    CloseHandle(hProcess);
+    return Py_BuildValue("i", IoPriority);
+}
+
+
+/*
+ * Set process IO priority.
+ */
+static PyObject*
+set_process_io_priority(PyObject* self, PyObject* args)
+{
+    long pid;
+    int prio;
+    HANDLE hProcess;
+
+    _NtSetInformationProcess NtSetInformationProcess =
+        (_NtSetInformationProcess)GetProcAddress(
+        GetModuleHandleA("ntdll.dll"), "NtSetInformationProcess");
+
+    if (NtSetInformationProcess == NULL) {
+        PyErr_SetString(PyExc_RuntimeError,
+                        "couldn't get NtSetInformationProcess");
+        return NULL;
+    }
+
+    if (! PyArg_ParseTuple(args, "li", &pid, &prio)) {
+        return NULL;
+    }
+    hProcess = psutil_handle_from_pid_waccess(pid, PROCESS_ALL_ACCESS);
+    if (hProcess == NULL) {
+        return NULL;
+    }
+
+    NtSetInformationProcess(
+        hProcess,
+        ProcessIoPriority,
+        (PVOID)&prio,
+        sizeof((PVOID)prio)
+    );
+
+    CloseHandle(hProcess);
+    Py_INCREF(Py_None);
+    return Py_None;
+}
+#endif
+
+
 /*
  * Return a Python tuple referencing process I/O counters.
  */
 static PyObject*
 get_process_io_counters(PyObject* self, PyObject* args)
 {
     DWORD pid;
     HANDLE hProcess;
     IO_COUNTERS IoCounters;
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    hProcess = handle_from_pid(pid);
+    hProcess = psutil_handle_from_pid(pid);
     if (NULL == hProcess) {
         return NULL;
     }
     if (! GetProcessIoCounters(hProcess, &IoCounters)) {
         CloseHandle(hProcess);
         return PyErr_SetFromWindowsErr(0);
     }
     CloseHandle(hProcess);
@@ -1969,45 +2097,54 @@ get_process_cpu_affinity(PyObject* self,
     DWORD pid;
     HANDLE hProcess;
     PDWORD_PTR proc_mask;
     PDWORD_PTR system_mask;
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    hProcess = handle_from_pid(pid);
+    hProcess = psutil_handle_from_pid(pid);
     if (hProcess == NULL) {
         return NULL;
     }
     if (GetProcessAffinityMask(hProcess, &proc_mask, &system_mask) == 0) {
         CloseHandle(hProcess);
         return PyErr_SetFromWindowsErr(0);
     }
 
     CloseHandle(hProcess);
+#ifdef _WIN64
+    return Py_BuildValue("K", (unsigned long long)proc_mask);
+#else
     return Py_BuildValue("k", (unsigned long)proc_mask);
+#endif
 }
 
 
 /*
  * Set process CPU affinity
  */
 static PyObject*
 set_process_cpu_affinity(PyObject* self, PyObject* args)
 {
     DWORD pid;
     HANDLE hProcess;
     DWORD dwDesiredAccess = PROCESS_QUERY_INFORMATION | PROCESS_SET_INFORMATION;
     DWORD_PTR mask;
 
-    if (! PyArg_ParseTuple(args, "lk", &pid, &mask)) {
+#ifdef _WIN64
+    if (! PyArg_ParseTuple(args, "lK", &pid, &mask))
+#else
+    if (! PyArg_ParseTuple(args, "lk", &pid, &mask))
+#endif
+    {
         return NULL;
     }
-    hProcess = handle_from_pid_waccess(pid, dwDesiredAccess);
+    hProcess = psutil_handle_from_pid_waccess(pid, dwDesiredAccess);
     if (hProcess == NULL) {
         return NULL;
     }
 
     if (SetProcessAffinityMask(hProcess, mask) == 0) {
         CloseHandle(hProcess);
         return PyErr_SetFromWindowsErr(0);
     }
@@ -2075,35 +2212,37 @@ get_disk_usage(PyObject* self, PyObject*
 
 
 /*
  * Return a Python list of named tuples with overall network I/O information
  */
 static PyObject*
 get_network_io_counters(PyObject* self, PyObject* args)
 {
-    PyObject* py_retdict = PyDict_New();
-    PyObject* py_nic_info = NULL;
-    PyObject* py_pre_nic_name = NULL;
-    PyObject* py_nic_name = NULL;
-
     int attempts = 0;
     int outBufLen = 15000;
     DWORD dwRetVal = 0;
     MIB_IFROW *pIfRow = NULL;
     ULONG flags = 0;
     ULONG family = AF_UNSPEC;
     PIP_ADAPTER_ADDRESSES pAddresses = NULL;
     PIP_ADAPTER_ADDRESSES pCurrAddresses = NULL;
 
+    PyObject* py_retdict = PyDict_New();
+    PyObject* py_nic_info = NULL;
+    PyObject* py_pre_nic_name = NULL;
+    PyObject* py_nic_name = NULL;
+
+    if (py_retdict == NULL) {
+        return NULL;
+    }
     do {
         pAddresses = (IP_ADAPTER_ADDRESSES *) malloc(outBufLen);
         if (pAddresses == NULL) {
-            PyErr_SetString(PyExc_RuntimeError,
-                "memory allocation failed for IP_ADAPTER_ADDRESSES struct.");
+            PyErr_NoMemory();
             goto error;
         }
 
         dwRetVal = GetAdaptersAddresses(family, flags, NULL, pAddresses,
                                         &outBufLen);
         if (dwRetVal == ERROR_BUFFER_OVERFLOW) {
             free(pAddresses);
             pAddresses = NULL;
@@ -2123,18 +2262,17 @@ get_network_io_counters(PyObject* self, 
     pCurrAddresses = pAddresses;
     while (pCurrAddresses) {
         py_pre_nic_name = NULL;
         py_nic_name = NULL;
         py_nic_info = NULL;
         pIfRow = (MIB_IFROW *) malloc(sizeof(MIB_IFROW));
 
         if (pIfRow == NULL) {
-            PyErr_SetString(PyExc_RuntimeError,
-                "memory allocation failed for MIB_IFROW struct.");
+            PyErr_NoMemory();
             goto error;
         }
 
         pIfRow->dwIndex = pCurrAddresses->IfIndex;
         dwRetVal = GetIfEntry(pIfRow);
         if (dwRetVal != NO_ERROR) {
             PyErr_SetString(PyExc_RuntimeError, "GetIfEntry() failed.");
             goto error;
@@ -2180,50 +2318,69 @@ error:
     Py_DECREF(py_retdict);
     if (pAddresses != NULL)
         free(pAddresses);
     if (pIfRow != NULL)
         free(pIfRow);
     return NULL;
 }
 
+// fix for mingw32, see
+// https://code.google.com/p/psutil/issues/detail?id=351#c2
+typedef struct _DISK_PERFORMANCE_WIN_2008 {
+       LARGE_INTEGER BytesRead;
+       LARGE_INTEGER BytesWritten;
+       LARGE_INTEGER ReadTime;
+       LARGE_INTEGER WriteTime;
+       LARGE_INTEGER IdleTime;
+       DWORD         ReadCount;
+       DWORD         WriteCount;
+       DWORD         QueueDepth;
+       DWORD         SplitCount;
+       LARGE_INTEGER QueryTime;
+       DWORD         StorageDeviceNumber;
+       WCHAR         StorageManagerName[8];
+} DISK_PERFORMANCE_WIN_2008;
 
 /*
  * Return a Python dict of tuples for disk I/O information
  */
 static PyObject*
 get_disk_io_counters(PyObject* self, PyObject* args)
 {
-    PyObject* py_retdict = PyDict_New();
-    PyObject* py_disk_info = NULL;
-
-    DISK_PERFORMANCE diskPerformance;
+    DISK_PERFORMANCE_WIN_2008 diskPerformance;
     DWORD dwSize;
     HANDLE hDevice = NULL;
     char szDevice[MAX_PATH];
     char szDeviceDisplay[MAX_PATH];
     int devNum;
-
-    for (devNum = 0;; devNum++) {
+    PyObject* py_retdict = PyDict_New();
+    PyObject* py_disk_info = NULL;
+    if (py_retdict == NULL) {
+        return NULL;
+    }
+
+    // Apparently there's no way to figure out how many times we have
+    // to iterate in order to find valid drives.
+    // Let's assume 32, which is higher than 26, the number of letters
+    // in the alphabet (from A:\ to Z:\).
+    for (devNum=0; devNum <= 32; ++devNum) {
         py_disk_info = NULL;
-        sprintf (szDevice, "\\\\.\\PhysicalDrive%d", devNum);
-        hDevice = CreateFile (szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
-                              NULL, OPEN_EXISTING, 0, NULL);
+        sprintf(szDevice, "\\\\.\\PhysicalDrive%d", devNum);
+        hDevice = CreateFile(szDevice, 0, FILE_SHARE_READ | FILE_SHARE_WRITE,
+                             NULL, OPEN_EXISTING, 0, NULL);
 
         if (hDevice == INVALID_HANDLE_VALUE) {
-            // what happens if we get an invalid handle on the first disk?
-            // we might end up with an empty dict incorrectly in some cases
-            break;
+            continue;
         }
-
         if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0,
-                            &diskPerformance, sizeof(DISK_PERFORMANCE),
+                            &diskPerformance, sizeof(diskPerformance),
                             &dwSize, NULL))
         {
-            sprintf (szDeviceDisplay, "PhysicalDrive%d", devNum);
+            sprintf(szDeviceDisplay, "PhysicalDrive%d", devNum);
             py_disk_info = Py_BuildValue("(IILLLL)",
                                          diskPerformance.ReadCount,
                                          diskPerformance.WriteCount,
                                          diskPerformance.BytesRead,
                                          diskPerformance.BytesWritten,
                                          (diskPerformance.ReadTime.QuadPart
                                             * 10) / 1000,
                                          (diskPerformance.WriteTime.QuadPart
@@ -2295,16 +2452,24 @@ get_disk_partitions(PyObject* self, PyOb
     int ret;
     char opts[20];
     LPTSTR fs_type[MAX_PATH + 1] = { 0 };
     DWORD pflags = 0;
     PyObject* py_all;
     PyObject* py_retlist = PyList_New(0);
     PyObject* py_tuple = NULL;
 
+    if (py_retlist == NULL) {
+        return NULL;
+    }
+
+    // avoid to visualize a message box in case something goes wrong
+    // see http://code.google.com/p/psutil/issues/detail?id=264
+    SetErrorMode(SEM_FAILCRITICALERRORS);
+
     if (! PyArg_ParseTuple(args, "O", &py_all)) {
         goto error;
     }
     all = PyObject_IsTrue(py_all);
 
     Py_BEGIN_ALLOW_THREADS
     num_bytes = GetLogicalDriveStrings(254, drive_letter);
     Py_END_ALLOW_THREADS
@@ -2377,19 +2542,21 @@ get_disk_partitions(PyObject* self, PyOb
             goto error;
         Py_DECREF(py_tuple);
         goto next;
 
         next:
             drive_letter = strchr(drive_letter, 0) + 1;
     }
 
+    SetErrorMode(0);
     return py_retlist;
 
 error:
+    SetErrorMode(0);
     Py_XDECREF(py_tuple);
     Py_DECREF(py_retlist);
     return NULL;
 }
 
 
 #ifdef UNICODE
 #define WTSOpenServer WTSOpenServerW
@@ -2399,20 +2566,16 @@ error:
 
 
 /*
  * Return a Python dict of tuples for disk I/O information
  */
 static PyObject*
 get_system_users(PyObject* self, PyObject* args)
 {
-    PyObject* py_retlist = PyList_New(0);
-    PyObject* py_tuple = NULL;
-    PyObject* py_address = NULL;
-
     HANDLE hServer = NULL;
     LPTSTR buffer_user = NULL;
     LPTSTR buffer_addr = NULL;
     PWTS_SESSION_INFO sessions = NULL;
     DWORD count;
     DWORD i;
     DWORD sessionId;
     DWORD bytes;
@@ -2420,16 +2583,23 @@ get_system_users(PyObject* self, PyObjec
     char address_str[50];
     long long unix_time;
 
     PWINSTATIONQUERYINFORMATIONW WinStationQueryInformationW;
     WINSTATION_INFO station_info;
     HINSTANCE hInstWinSta = NULL;
     ULONG returnLen;
 
+    PyObject* py_retlist = PyList_New(0);
+    PyObject* py_tuple = NULL;
+    PyObject* py_address = NULL;
+    if (py_retlist == NULL) {
+        return NULL;
+    }
+
     hInstWinSta = LoadLibraryA("winsta.dll");
     WinStationQueryInformationW = (PWINSTATIONQUERYINFORMATIONW)
         GetProcAddress(hInstWinSta, "WinStationQueryInformationW");
 
     hServer = WTSOpenServer('\0');
     if (hServer == NULL) {
         PyErr_SetFromWindowsErr(0);
         goto error;
@@ -2552,17 +2722,17 @@ get_process_num_handles(PyObject* self, 
 {
     DWORD pid;
     HANDLE hProcess;
     DWORD handleCount;
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    hProcess = handle_from_pid(pid);
+    hProcess = psutil_handle_from_pid(pid);
     if (NULL == hProcess) {
         return NULL;
     }
     if (! GetProcessHandleCount(hProcess, &handleCount)) {
         CloseHandle(hProcess);
         return PyErr_SetFromWindowsErr(0);
     }
     CloseHandle(hProcess);
@@ -2655,20 +2825,23 @@ get_process_memory_maps(PyObject* self, 
     PVOID baseAddress;
     PVOID previousAllocationBase;
     CHAR mappedFileName[MAX_PATH];
     SYSTEM_INFO system_info;
     LPVOID maxAddr;
     PyObject* py_list = PyList_New(0);
     PyObject* py_tuple = NULL;
 
+    if (py_list == NULL) {
+        return NULL;
+    }
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         goto error;
     }
-    hProcess = handle_from_pid(pid);
+    hProcess = psutil_handle_from_pid(pid);
     if (NULL == hProcess) {
         goto error;
     }
 
     GetSystemInfo(&system_info);
     maxAddr = system_info.lpMaximumApplicationAddress;
     baseAddress = NULL;
     previousAllocationBase = NULL;
@@ -2751,16 +2924,22 @@ PsutilMethods[] =
     {"get_process_threads", get_process_threads, METH_VARARGS,
         "Return process threads information as a list of tuple"},
     {"process_wait", process_wait, METH_VARARGS,
         "Wait for process to terminate and return its exit code."},
     {"get_process_priority", get_process_priority, METH_VARARGS,
         "Return process priority."},
     {"set_process_priority", set_process_priority, METH_VARARGS,
         "Set process priority."},
+#if (_WIN32_WINNT >= 0x0600)  // Windows Vista
+    {"get_process_io_priority", get_process_io_priority, METH_VARARGS,
+        "Return process IO priority."},
+    {"set_process_io_priority", set_process_io_priority, METH_VARARGS,
+        "Set process IO priority."},
+#endif
     {"get_process_cpu_affinity", get_process_cpu_affinity, METH_VARARGS,
         "Return process CPU affinity as a bitmask."},
     {"set_process_cpu_affinity", set_process_cpu_affinity, METH_VARARGS,
         "Set process CPU affinity."},
     {"get_process_io_counters", get_process_io_counters, METH_VARARGS,
         "Get process I/O counters."},
     {"is_process_suspended", is_process_suspended, METH_VARARGS,
         "Return True if one of the process threads is in a suspended state"},
@@ -2786,18 +2965,18 @@ PsutilMethods[] =
     // --- system-related functions
 
     {"get_pid_list", get_pid_list, METH_VARARGS,
         "Returns a list of PIDs currently running on the system"},
     {"pid_exists", pid_exists, METH_VARARGS,
         "Determine if the process exists in the current process list."},
     {"get_num_cpus", get_num_cpus, METH_VARARGS,
         "Returns the number of CPUs on the system"},
-    {"get_system_uptime", get_system_uptime, METH_VARARGS,
-        "Return system uptime"},
+    {"get_system_boot_time", get_system_boot_time, METH_VARARGS,
+        "Return the system boot time expressed in seconds since the epoch."},
     {"get_virtual_mem", get_virtual_mem, METH_VARARGS,
         "Return the total amount of physical memory, in bytes"},
     {"get_system_cpu_times", get_system_cpu_times, METH_VARARGS,
         "Return system per-cpu times as a list of tuples"},
     {"get_disk_usage", get_disk_usage, METH_VARARGS,
         "Return path's disk total and free as a Python tuple."},
     {"get_network_io_counters", get_network_io_counters, METH_VARARGS,
         "Return dict of tuples of networks I/O information."},
--- a/python/psutil/psutil/_psutil_mswindows.h
+++ b/python/psutil/psutil/_psutil_mswindows.h
@@ -1,11 +1,9 @@
 /*
- * $Id: _psutil_mswindows.h 1498 2012-07-24 21:41:28Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * Windows platform-specific module methods for _psutil_mswindows
  */
 
 #include <Python.h>
@@ -23,16 +21,20 @@ static PyObject* get_process_memory_info
 static PyObject* get_process_cwd(PyObject* self, PyObject* args);
 static PyObject* get_process_open_files(PyObject* self, PyObject* args);
 static PyObject* get_process_username(PyObject* self, PyObject* args);
 static PyObject* get_process_connections(PyObject* self, PyObject* args);
 static PyObject* get_process_num_threads(PyObject* self, PyObject* args);
 static PyObject* get_process_threads(PyObject* self, PyObject* args);
 static PyObject* get_process_priority(PyObject* self, PyObject* args);
 static PyObject* set_process_priority(PyObject* self, PyObject* args);
+#if (_WIN32_WINNT >= 0x0600)  // Windows Vista
+static PyObject* get_process_io_priority(PyObject* self, PyObject* args);
+static PyObject* set_process_io_priority(PyObject* self, PyObject* args);
+#endif
 static PyObject* get_process_io_counters(PyObject* self, PyObject* args);
 static PyObject* get_process_cpu_affinity(PyObject* self, PyObject* args);
 static PyObject* set_process_cpu_affinity(PyObject* self, PyObject* args);
 static PyObject* get_process_num_handles(PyObject* self, PyObject* args);
 static PyObject* get_process_num_ctx_switches(PyObject* self, PyObject* args);
 static PyObject* get_process_memory_maps(PyObject* self, PyObject* args);
 
 static PyObject* get_process_cpu_times_2(PyObject* self, PyObject* args);
@@ -46,17 +48,17 @@ static PyObject* resume_process(PyObject
 static PyObject* is_process_suspended(PyObject* self, PyObject* args);
 static PyObject* process_wait(PyObject* self, PyObject* args);
 static PyObject* kill_process(PyObject* self, PyObject* args);
 
 // --- system-related functions
 
 static PyObject* get_pid_list(PyObject* self, PyObject* args);
 static PyObject* get_num_cpus(PyObject* self, PyObject* args);
-static PyObject* get_system_uptime(PyObject* self, PyObject* args);
+static PyObject* get_system_boot_time(PyObject* self, PyObject* args);
 static PyObject* get_virtual_mem(PyObject* self, PyObject* args);
 static PyObject* get_system_cpu_times(PyObject* self, PyObject* args);
 static PyObject* pid_exists(PyObject* self, PyObject* args);
 static PyObject* get_disk_usage(PyObject* self, PyObject* args);
 static PyObject* get_disk_partitions(PyObject* self, PyObject* args);
 static PyObject* get_network_io_counters(PyObject* self, PyObject* args);
 static PyObject* get_disk_io_counters(PyObject* self, PyObject* args);
 static PyObject* get_system_users(PyObject* self, PyObject* args);
--- a/python/psutil/psutil/_psutil_osx.c
+++ b/python/psutil/psutil/_psutil_osx.c
@@ -1,11 +1,9 @@
 /*
- * $Id: _psutil_osx.c 1501 2012-07-25 12:57:34Z g.rodola@gmail.com $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * OS X platform-specific module methods for _psutil_osx
  */
 
 #include <Python.h>
@@ -26,17 +24,17 @@
 
 #include <mach/mach.h>
 #include <mach/task.h>
 #include <mach/mach_init.h>
 #include <mach/host_info.h>
 #include <mach/mach_host.h>
 #include <mach/mach_traps.h>
 #include <mach/mach_vm.h>
-#include <mach/shared_memory_server.h>
+#include <mach/shared_region.h>
 
 #include <mach-o/loader.h>
 
 #include <CoreFoundation/CoreFoundation.h>
 #include <IOKit/IOKitLib.h>
 #include <IOKit/storage/IOBlockStorageDriver.h>
 #include <IOKit/storage/IOMedia.h>
 #include <IOKit/IOBSD.h>
@@ -57,16 +55,17 @@ psutil_sys_vminfo(vm_statistics_data_t *
     mach_port_t mport = mach_host_self();
 
     ret = host_statistics(mport, HOST_VM_INFO, (host_info_t)vmstat, &count);
     if (ret != KERN_SUCCESS) {
         PyErr_Format(PyExc_RuntimeError,
                      "host_statistics() failed: %s", mach_error_string(ret));
         return 0;
     }
+    mach_port_deallocate(mach_task_self(), mport);
     return 1;
 }
 
 
 /*
  * Return a Python list of all the PIDs running on the system.
  */
 static PyObject*
@@ -74,17 +73,20 @@ get_pid_list(PyObject* self, PyObject* a
 {
     kinfo_proc *proclist = NULL;
     kinfo_proc *orig_address = NULL;
     size_t num_processes;
     size_t idx;
     PyObject *pid = NULL;
     PyObject *retlist = PyList_New(0);
 
-    if (get_proc_list(&proclist, &num_processes) != 0) {
+    if (retlist == NULL)
+        return NULL;
+
+    if (psutil_get_proc_list(&proclist, &num_processes) != 0) {
         PyErr_SetString(PyExc_RuntimeError, "failed to retrieve process list.");
         goto error;
     }
 
     if (num_processes > 0) {
         // save the address of proclist so we can free it later
         orig_address = proclist;
         for (idx=0; idx < num_processes; idx++) {
@@ -115,17 +117,17 @@ error:
 static PyObject*
 get_process_name(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("s", kp.kp_proc.p_comm);
 }
 
 
 /*
  * Return process current working directory.
@@ -159,17 +161,17 @@ get_process_exe(PyObject* self, PyObject
     char buf[PATH_MAX];
     int ret;
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
     ret = proc_pidpath(pid, &buf, sizeof(buf));
     if (ret == 0) {
-        if (! pid_exists(pid)) {
+        if (! psutil_pid_exists(pid)) {
             return NoSuchProcess();
         }
         else {
             return AccessDenied();
         }
     }
     return Py_BuildValue("s", buf);
 }
@@ -183,33 +185,33 @@ get_process_cmdline(PyObject* self, PyOb
     long pid;
     PyObject* arglist = NULL;
 
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
 
     // get the commandline, defined in arch/osx/process_info.c
-    arglist = get_arg_list(pid);
+    arglist = psutil_get_arg_list(pid);
     return arglist;
 }
 
 
 /*
  * Return process parent pid from kinfo_proc as a Python integer.
  */
 static PyObject*
 get_process_ppid(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("l", (long)kp.kp_eproc.e_ppid);
 }
 
 
 /*
  * Return process real uid from kinfo_proc as a Python integer.
@@ -217,17 +219,17 @@ get_process_ppid(PyObject* self, PyObjec
 static PyObject*
 get_process_uids(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("lll", (long)kp.kp_eproc.e_pcred.p_ruid,
                                 (long)kp.kp_eproc.e_ucred.cr_uid,
                                 (long)kp.kp_eproc.e_pcred.p_svuid);
 }
 
 
@@ -237,17 +239,17 @@ get_process_uids(PyObject* self, PyObjec
 static PyObject*
 get_process_gids(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("lll", (long)kp.kp_eproc.e_pcred.p_rgid,
                                 (long)kp.kp_eproc.e_ucred.cr_groups[0],
                                 (long)kp.kp_eproc.e_pcred.p_svgid);
 }
 
 
@@ -257,17 +259,17 @@ get_process_gids(PyObject* self, PyObjec
 static PyObject*
 get_process_tty_nr(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("i", kp.kp_eproc.e_tdev);
 }
 
 
 /*
  * Return a list of tuples for every process memory maps.
@@ -285,24 +287,27 @@ get_process_memory_maps(PyObject* self, 
     mach_port_t task;
     uint32_t depth = 1;
     vm_address_t address = 0;
     vm_size_t size = 0;
 
     PyObject* py_tuple = NULL;
     PyObject* py_list = PyList_New(0);
 
+    if (py_list == NULL)
+        return NULL;
+
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         goto error;
     }
 
     err = task_for_pid(mach_task_self(), pid, &task);
 
     if (err != KERN_SUCCESS) {
-        if (! pid_exists(pid)) {
+        if (! psutil_pid_exists(pid)) {
             NoSuchProcess();
         }
         else {
             // pid exists, so return AccessDenied error since task_for_pid()
             // failed
             AccessDenied();
         }
         goto error;
@@ -324,17 +329,17 @@ get_process_memory_maps(PyObject* self, 
             depth++;
         }
         else {
             // Free/Reset the char[]s to avoid weird paths
             memset(buf, 0, sizeof(buf));
             memset(addr_str, 0, sizeof(addr_str));
             memset(perms, 0, sizeof(perms));
 
-            sprintf(addr_str, "%016x-%016x", address, address + size);
+            sprintf(addr_str, "%016lx-%016lx", address, address + size);
             sprintf(perms, "%c%c%c/%c%c%c",
                     (info.protection & VM_PROT_READ) ? 'r' : '-',
                     (info.protection & VM_PROT_WRITE) ? 'w' : '-',
                     (info.protection & VM_PROT_EXECUTE) ? 'x' : '-',
                     (info.max_protection & VM_PROT_READ) ? 'r' : '-',
                     (info.max_protection & VM_PROT_WRITE) ? 'w' : '-',
                     (info.max_protection & VM_PROT_EXECUTE) ? 'x' : '-');
 
@@ -392,19 +397,24 @@ get_process_memory_maps(PyObject* self, 
             if (!py_tuple)
                 goto error;
             if (PyList_Append(py_list, py_tuple))
                 goto error;
             Py_DECREF(py_tuple);
         }
     }
 
+    if (task != MACH_PORT_NULL)
+        mach_port_deallocate(mach_task_self(), task);
+
     return py_list;
 
 error:
+    if (task != MACH_PORT_NULL)
+        mach_port_deallocate(mach_task_self(), task);
     Py_XDECREF(py_tuple);
     Py_DECREF(py_list);
     return NULL;
 }
 
 
 /*
  * Return a Python integer indicating the number of CPUs on the system.
@@ -458,17 +468,17 @@ get_process_cpu_times(PyObject* self, Py
 static PyObject*
 get_process_create_time(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("d", TV2DOUBLE(kp.kp_proc.p_starttime));
 }
 
 
 /*
  * Return extended memory info about a process.
@@ -618,21 +628,23 @@ get_swap_mem(PyObject* self, PyObject* a
  */
 static PyObject*
 get_system_cpu_times(PyObject* self, PyObject* args)
 {
     mach_msg_type_number_t  count = HOST_CPU_LOAD_INFO_COUNT;
     kern_return_t error;
     host_cpu_load_info_data_t r_load;
 
-    error = host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&r_load, &count);
+    mach_port_t host_port = mach_host_self();
+    error = host_statistics(host_port, HOST_CPU_LOAD_INFO, (host_info_t)&r_load, &count);
     if (error != KERN_SUCCESS) {
         return PyErr_Format(PyExc_RuntimeError,
                 "Error in host_statistics(): %s", mach_error_string(error));
     }
+    mach_port_deallocate(mach_task_self(), host_port);
 
     return Py_BuildValue("(dddd)",
                          (double)r_load.cpu_ticks[CPU_STATE_USER] / CLK_TCK,
                          (double)r_load.cpu_ticks[CPU_STATE_NICE] / CLK_TCK,
                          (double)r_load.cpu_ticks[CPU_STATE_SYSTEM] / CLK_TCK,
                          (double)r_load.cpu_ticks[CPU_STATE_IDLE] / CLK_TCK
                          );
 }
@@ -644,27 +656,32 @@ get_system_cpu_times(PyObject* self, PyO
 static PyObject*
 get_system_per_cpu_times(PyObject* self, PyObject* args)
 {
     natural_t cpu_count;
     processor_info_array_t info_array;
     mach_msg_type_number_t info_count;
     kern_return_t error;
     processor_cpu_load_info_data_t* cpu_load_info = NULL;
+    int i, ret;
     PyObject* py_retlist = PyList_New(0);
     PyObject* py_cputime = NULL;
-    int i, ret;
 
-    error = host_processor_info(mach_host_self(), PROCESSOR_CPU_LOAD_INFO,
+    if (py_retlist == NULL)
+        return NULL;
+
+    mach_port_t host_port = mach_host_self();
+    error = host_processor_info(host_port, PROCESSOR_CPU_LOAD_INFO,
                                 &cpu_count, &info_array, &info_count);
     if (error != KERN_SUCCESS) {
         PyErr_Format(PyExc_RuntimeError, "Error in host_processor_info(): %s",
                      mach_error_string(error));
         goto error;
     }
+    mach_port_deallocate(mach_task_self(), host_port);
 
     cpu_load_info = (processor_cpu_load_info_data_t*) info_array;
 
     for (i = 0; i < cpu_count; i++) {
         py_cputime = Py_BuildValue("(dddd)",
                (double)cpu_load_info[i].cpu_ticks[CPU_STATE_USER] / CLK_TCK,
                (double)cpu_load_info[i].cpu_ticks[CPU_STATE_NICE] / CLK_TCK,
                (double)cpu_load_info[i].cpu_ticks[CPU_STATE_SYSTEM] / CLK_TCK,
@@ -731,27 +748,34 @@ get_disk_partitions(PyObject* self, PyOb
     int i;
     long len;
     uint64_t flags;
     char opts[400];
     struct statfs *fs = NULL;
     PyObject* py_retlist = PyList_New(0);
     PyObject* py_tuple = NULL;
 
+    if (py_retlist == NULL)
+        return NULL;
+
     // get the number of mount points
     Py_BEGIN_ALLOW_THREADS
     num = getfsstat(NULL, 0, MNT_NOWAIT);
     Py_END_ALLOW_THREADS
     if (num == -1) {
         PyErr_SetFromErrno(0);
         goto error;
     }
 
     len = sizeof(*fs) * num;
     fs = malloc(len);
+    if (fs == NULL) {
+        PyErr_NoMemory();
+        goto error;
+    }
 
     Py_BEGIN_ALLOW_THREADS
     num = getfsstat(fs, len, MNT_NOWAIT);
     Py_END_ALLOW_THREADS
     if (num == -1) {
         PyErr_SetFromErrno(0);
         goto error;
     }
@@ -841,17 +865,17 @@ error:
 static PyObject*
 get_process_status(PyObject* self, PyObject* args)
 {
     long pid;
     struct kinfo_proc kp;
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         return NULL;
     }
-    if (get_kinfo_proc(pid, &kp) == -1) {
+    if (psutil_get_kinfo_proc(pid, &kp) == -1) {
         return NULL;
     }
     return Py_BuildValue("i", (int)kp.kp_proc.p_stat);
 }
 
 
 /*
  * Return process threads
@@ -868,25 +892,28 @@ get_process_threads(PyObject* self, PyOb
     thread_act_port_array_t thread_list = NULL;
     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;
 
+    if (retList == NULL)
+        return NULL;
+
     // the argument passed should be a process id
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         goto error;
     }
 
     // task_for_pid() requires special privileges
     err = task_for_pid(mach_task_self(), pid, &task);
     if (err != KERN_SUCCESS) {
-        if (! pid_exists(pid)) {
+        if (! psutil_pid_exists(pid)) {
             NoSuchProcess();
         }
         else {
             AccessDenied();
         }
         goto error;
     }
 
@@ -934,19 +961,23 @@ get_process_threads(PyObject* self, PyOb
     }
 
     ret = vm_deallocate(task, (vm_address_t)thread_list,
                         thread_count * sizeof(int));
     if (ret != KERN_SUCCESS) {
         PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2);
     }
 
+    mach_port_deallocate(mach_task_self(), task);
+
     return retList;
 
 error:
+    if (task != MACH_PORT_NULL)
+        mach_port_deallocate(mach_task_self(), task);
     Py_XDECREF(pyTuple);
     Py_DECREF(retList);
     if (thread_list != NULL) {
         ret = vm_deallocate(task, (vm_address_t)thread_list,
                             thread_count * sizeof(int));
         if (ret != KERN_SUCCESS) {
             PyErr_WarnEx(PyExc_RuntimeWarning, "vm_deallocate() failed", 2);
         }
@@ -972,28 +1003,35 @@ get_process_open_files(PyObject* self, P
 
     struct proc_fdinfo *fds_pointer = NULL;
     struct proc_fdinfo *fdp_pointer;
     struct vnode_fdinfowithpath vi;
 
     PyObject *retList = PyList_New(0);
     PyObject *tuple = NULL;
 
+    if (retList == NULL)
+        return NULL;
+
     if (! PyArg_ParseTuple(args, "l", &pid)) {
         goto error;
     }
 
     pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
     if (pidinfo_result <= 0) {
         // may be be ignored later if errno != 0
         PyErr_Format(PyExc_RuntimeError, "proc_pidinfo(PROC_PIDLISTFDS) failed");
         goto error;
     }
 
     fds_pointer = malloc(pidinfo_result);
+    if (fds_pointer == NULL) {
+        PyErr_NoMemory();
+        goto error;
+    }
     pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds_pointer,
                                   pidinfo_result);
     if (pidinfo_result <= 0) {
         // may be be ignored later if errno != 0
         PyErr_Format(PyExc_RuntimeError, "proc_pidinfo(PROC_PIDLISTFDS) failed");
         goto error;
     }
 
@@ -1049,17 +1087,17 @@ error:
     Py_XDECREF(tuple);
     Py_DECREF(retList);
     if (fds_pointer != NULL) {
         free(fds_pointer);
     }
     if (errno != 0) {
         return PyErr_SetFromErrno(PyExc_OSError);
     }
-    else if (! pid_exists(pid)) {
+    else if (! psutil_pid_exists(pid)) {
         return NoSuchProcess();
     }
     else {
         // exception has already been set earlier
         return NULL;
     }
 }
 
@@ -1120,16 +1158,19 @@ get_process_connections(PyObject* self, 
 
     PyObject *retList = PyList_New(0);
     PyObject *tuple = NULL;
     PyObject *laddr = NULL;
     PyObject *raddr = NULL;
     PyObject *af_filter = NULL;
     PyObject *type_filter = NULL;
 
+    if (retList == NULL)
+        return NULL;
+
     if (! PyArg_ParseTuple(args, "lOO", &pid, &af_filter, &type_filter)) {
         goto error;
     }
 
     if (!PySequence_Check(af_filter) || !PySequence_Check(type_filter)) {
         PyErr_SetString(PyExc_TypeError, "arg 2 or 3 is not a sequence");
         goto error;
     }
@@ -1139,16 +1180,20 @@ get_process_connections(PyObject* self, 
     }
 
     pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
     if (pidinfo_result <= 0) {
         goto error;
     }
 
     fds_pointer = malloc(pidinfo_result);
+    if (fds_pointer == NULL) {
+        PyErr_NoMemory();
+        goto error;
+    }
     pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds_pointer,
                                   pidinfo_result);
 
     if (pidinfo_result <= 0) {
         goto error;
     }
 
     iterations = (pidinfo_result / PROC_PIDLISTFD_SIZE);
@@ -1301,17 +1346,17 @@ error:
     Py_DECREF(retList);
 
     if (fds_pointer != NULL) {
         free(fds_pointer);
     }
     if (errno != 0) {
         return PyErr_SetFromErrno(PyExc_OSError);
     }
-    else if (! pid_exists(pid) ) {
+    else if (! psutil_pid_exists(pid) ) {
         return NoSuchProcess();
     }
     else {
         return PyErr_Format(PyExc_RuntimeError,
                             "proc_pidinfo(PROC_PIDLISTFDS) failed");
     }
 }
 
@@ -1332,16 +1377,19 @@ get_process_num_fds(PyObject* self, PyOb
     }
 
     pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, NULL, 0);
     if (pidinfo_result <= 0) {
         return PyErr_SetFromErrno(PyExc_OSError);
     }
 
     fds_pointer = malloc(pidinfo_result);
+    if (fds_pointer == NULL) {
+        return PyErr_NoMemory();
+    }
     pidinfo_result = proc_pidinfo(pid, PROC_PIDLISTFDS, 0, fds_pointer,
                                   pidinfo_result);
     if (pidinfo_result <= 0) {
         free(fds_pointer);
         return PyErr_SetFromErrno(PyExc_OSError);
     }
 
     num = (pidinfo_result / PROC_PIDLISTFD_SIZE);
@@ -1351,37 +1399,43 @@ get_process_num_fds(PyObject* self, PyOb
 
 
 /*
  * Return a Python list of named tuples with overall network I/O information
  */
 static PyObject*
 get_network_io_counters(PyObject* self, PyObject* args)
 {
-    PyObject* py_retdict = PyDict_New();
-    PyObject* py_ifc_info = NULL;
-
     char *buf = NULL, *lim, *next;
     struct if_msghdr *ifm;
     int mib[6];
     size_t len;
+    PyObject* py_retdict = PyDict_New();
+    PyObject* py_ifc_info = NULL;
+
+    if (py_retdict == NULL)
+        return NULL;
 
     mib[0] = CTL_NET;          // networking subsystem
     mib[1] = PF_ROUTE;         // type of information
     mib[2] = 0;                // protocol (IPPROTO_xxx)
     mib[3] = 0;                // address family
     mib[4] = NET_RT_IFLIST2;   // operation
     mib[5] = 0;
 
     if (sysctl(mib, 6, NULL, &len, NULL, 0) < 0) {
         PyErr_SetFromErrno(0);
         goto error;
     }
 
     buf = malloc(len);
+    if (buf == NULL) {
+        PyErr_NoMemory();
+        goto error;
+    }
 
     if (sysctl(mib, 6, buf, &len, NULL, 0) < 0) {
         PyErr_SetFromErrno(0);
         goto error;
     }
 
     lim = buf + len;
 
@@ -1432,25 +1486,27 @@ error:
 
 
 /*
  * Return a Python dict of tuples for disk I/O information
  */
 static PyObject*
 get_disk_io_counters(PyObject* self, PyObject* args)
 {
-    PyObject* py_retdict = PyDict_New();
-    PyObject* py_disk_info = NULL;
-
     CFDictionaryRef parent_dict;
     CFDictionaryRef props_dict;
     CFDictionaryRef stats_dict;
     io_registry_entry_t parent;
     io_registry_entry_t disk;
     io_iterator_t disk_list;
+    PyObject* py_retdict = PyDict_New();
+    PyObject* py_disk_info = NULL;
+
+    if (py_retdict == NULL)
+        return NULL;
 
     /* Get list of disks */
     if (IOServiceGetMatchingServices(kIOMasterPortDefault,
                                      IOServiceMatching(kIOMediaClass),
                                      &disk_list) != kIOReturnSuccess) {
         PyErr_SetString(PyExc_RuntimeError, "Unable to get the list of disks.");
         goto error;
     }
@@ -1557,19 +1613,20 @@ get_disk_io_counters(PyObject* self, PyO
                     stats_dict,
                     CFSTR(kIOBlockStorageDriverStatisticsTotalWriteTimeKey)))) {
                 CFNumberGetValue(number, kCFNumberSInt64Type, &write_time);
             }
 
             // Read/Write time on OS X comes back in nanoseconds and in psutil
             // we've standardized on milliseconds so do the conversion.
             py_disk_info = Py_BuildValue("(KKKKKK)",
-                                         reads, writes,
-                                         read_bytes, write_bytes,
-                                         read_time / 1000, write_time / 1000);
+                reads, writes,
+                read_bytes, write_bytes,
+                read_time / 1000 / 1000, write_time / 1000 / 1000
+            );
             if (!py_disk_info)
                 goto error;
             if (PyDict_SetItemString(py_retdict, disk_name, py_disk_info))
                 goto error;
             Py_DECREF(py_disk_info);
 
             CFRelease(parent_dict);
             IOObjectRelease(parent);
@@ -1590,58 +1647,48 @@ error:
 
 
 /*
  * Return currently connected users as a list of tuples.
  */
 static PyObject*
 get_system_users(PyObject* self, PyObject* args)
 {
+    struct utmpx *utx;
     PyObject *ret_list = PyList_New(0);
     PyObject *tuple = NULL;
-    struct utmpx ut;
-    FILE *fp = NULL;
 
-    fp = fopen(_PATH_UTMPX, "r");
-    if (fp == NULL) {
-        // man fopen says errno is set but it seems it's not (OSX 10.6)
-        PyErr_SetFromErrnoWithFilename(PyExc_OSError, _PATH_UTMPX);
-        goto error;
-    }
-
-    while (fread(&ut, sizeof(ut), 1, fp) == 1) {
-        if (*ut.ut_user == '\0') {
+    if (ret_list == NULL)
+        return NULL;
+    while ((utx = getutxent()) != NULL) {
+        if (utx->ut_type != USER_PROCESS)
             continue;
+        tuple = Py_BuildValue("(sssf)",
+            utx->ut_user,             // username
+            utx->ut_line,             // tty
+            utx->ut_host,             // hostname
+            (float)utx->ut_tv.tv_sec  // start time
+        );
+        if (!tuple) {
+            endutxent();
+            goto error;
         }
-#ifdef UTMPX_USER_PROCESS
-        if (ut.ut_type != UTMPX_USER_PROCESS) {
-            continue;
+        if (PyList_Append(ret_list, tuple)) {
+            endutxent();
+            goto error;
         }
-#endif
-        tuple = Py_BuildValue("(sssf)",
-            ut.ut_user,              // username
-            ut.ut_line,              // tty
-            ut.ut_host,              // hostname
-            (float)ut.ut_tv.tv_sec   // login time
-        );
-        if (!tuple)
-            goto error;
-        if (PyList_Append(ret_list, tuple))
-            goto error;
         Py_DECREF(tuple);
     }
 
-    fclose(fp);
+    endutxent();
     return ret_list;
 
 error:
     Py_XDECREF(tuple);
     Py_DECREF(ret_list);
-    if (fp != NULL)
-        fclose(fp);
     return NULL;
 }
 
 
 /*
  * define the psutil C module methods and initialize the module.
  */
 static PyMethodDef
@@ -1699,18 +1746,17 @@ PsutilMethods[] =
          "Return system virtual memory stats"},
      {"get_swap_mem", get_swap_mem, METH_VARARGS,
          "Return stats about swap memory, in bytes"},
      {"get_system_cpu_times", get_system_cpu_times, METH_VARARGS,
          "Return system cpu times as a tuple (user, system, nice, idle, irc)"},
      {"get_system_per_cpu_times", get_system_per_cpu_times, METH_VARARGS,
          "Return system per-cpu times as a list of tuples"},
      {"get_system_boot_time", get_system_boot_time, METH_VARARGS,
-         "Return a float indicating the system boot time expressed in "
-         "seconds since the epoch"},
+         "Return the system boot time expressed in seconds since the epoch."},
      {"get_disk_partitions", get_disk_partitions, METH_VARARGS,
          "Return a list of tuples including device, mount point and "
          "fs type for all partitions mounted on the system."},
      {"get_network_io_counters", get_network_io_counters, METH_VARARGS,
          "Return dict of tuples of networks I/O information."},
      {"get_disk_io_counters", get_disk_io_counters, METH_VARARGS,
          "Return dict of tuples of disks I/O information."},
      {"get_system_users", get_system_users, METH_VARARGS,
--- a/python/psutil/psutil/_psutil_osx.h
+++ b/python/psutil/psutil/_psutil_osx.h
@@ -1,11 +1,9 @@
 /*
- * $Id: _psutil_osx.h 1498 2012-07-24 21:41:28Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * OS X platform-specific module methods for _psutil_osx
  */
 
 #include <Python.h>
--- a/python/psutil/psutil/_psutil_posix.c
+++ b/python/psutil/psutil/_psutil_posix.c
@@ -1,11 +1,9 @@
 /*
- * $Id: _psutil_posix.c 1223 2011-11-09 23:47:55Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * Functions specific to all POSIX compliant platforms.
  */
 
 #include <Python.h>
--- a/python/psutil/psutil/_psutil_posix.h
+++ b/python/psutil/psutil/_psutil_posix.h
@@ -1,11 +1,9 @@
 /*
- * $Id: _psutil_posix.h 1223 2011-11-09 23:47:55Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * POSIX specific module methods for _psutil_posix
  */
 
 #include <Python.h>
--- a/python/psutil/psutil/arch/bsd/process_info.c
+++ b/python/psutil/psutil/arch/bsd/process_info.c
@@ -1,11 +1,9 @@
 /*
- * $Id: process_info.c 1462 2012-07-18 03:12:08Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * Helper functions related to fetching process information. Used by _psutil_bsd
  * module methods.
  */
 
@@ -29,17 +27,17 @@
  * Returns a list of all BSD processes on the system.  This routine
  * allocates the list and puts it in *procList and a count of the
  * number of entries in *procCount.  You are responsible for freeing
  * this list (use "free" from System framework).
  * On success, the function returns 0.
  * On error, the function returns a BSD errno value.
  */
 int
-get_proc_list(struct kinfo_proc **procList, size_t *procCount)
+psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount)
 {
     int err;
     struct kinfo_proc * result;
     int done;
     static const int name[] = { CTL_KERN, KERN_PROC, KERN_PROC_PROC, 0 };
     // Declaring name as const requires us to cast it when passing it to
     // sysctl because the prototype doesn't include the const modifier.
     size_t              length;
@@ -109,17 +107,17 @@ get_proc_list(struct kinfo_proc **procLi
     *procCount = length / sizeof(struct kinfo_proc);
 
     assert((err == 0) == (*procList != NULL));
     return err;
 }
 
 
 char
-*getcmdpath(long pid, size_t *pathsize)
+*psutil_get_cmd_path(long pid, size_t *pathsize)
 {
     int  mib[4];
     char *path;
     size_t size = 0;
 
     /*
      * Make a sysctl() call to get the raw argument space of the process.
      */
@@ -130,61 +128,62 @@ char
 
     // call with a null buffer first to determine if we need a buffer
     if (sysctl(mib, 4, NULL, &size, NULL, 0) == -1) {
         return NULL;
     }
 
     path = malloc(size);
     if (path == NULL) {
-        PyErr_SetString(PyExc_MemoryError, "couldn't allocate memory");
+        PyErr_NoMemory();
         return NULL;
     }
 
     *pathsize = size;
     if (sysctl(mib, 4, path, &size, NULL, 0) == -1) {
         free(path);
         return NULL;       /* Insufficient privileges */
     }
 
     return path;
 }
 
 
 /*
+ * XXX no longer used; it probably makese sense to remove it.
  * Borrowed from psi Python System Information project
  *
  * Get command arguments and environment variables.
  *
  * Based on code from ps.
  *
  * Returns:
  *      0 for success;
  *      -1 for failure (Exception raised);
  *      1 for insufficient privileges.
  */
 char
-*getcmdargs(long pid, size_t *argsize)
+*psutil_get_cmd_args(long pid, size_t *argsize)
 {
-    int mib[4];
-    size_t size, argmax;
+    int mib[4], argmax;
+    size_t size = sizeof(argmax);
     char *procargs = NULL;
 
     /* Get the maximum process arguments size. */
     mib[0] = CTL_KERN;
     mib[1] = KERN_ARGMAX;
 
     size = sizeof(argmax);
     if (sysctl(mib, 2, &argmax, &size, NULL, 0) == -1)
         return NULL;
 
     /* Allocate space for the arguments. */
     procargs = (char *)malloc(argmax);
     if (procargs == NULL) {
-        PyErr_SetString(PyExc_MemoryError, "couldn't allocate memory");
+        PyErr_NoMemory();
         return NULL;
     }
 
     /*
      * Make a sysctl() call to get the raw argument space of the process.
      */
     mib[0] = CTL_KERN;
     mib[1] = KERN_PROC;
@@ -200,29 +199,29 @@ char
     // return string and set the length of arguments
     *argsize = size;
     return procargs;
 }
 
 
 /* returns the command line as a python list object */
 PyObject*
-get_arg_list(long pid)
+psutil_get_arg_list(long pid)
 {
     char *argstr = NULL;
     int pos = 0;
     size_t argsize = 0;
     PyObject *retlist = Py_BuildValue("[]");
     PyObject *item = NULL;
 
     if (pid < 0) {
         return retlist;
     }
 
-    argstr = getcmdargs(pid, &argsize);
+    argstr = psutil_get_cmd_args(pid, &argsize);
     if (argstr == NULL) {
         goto error;
     }
 
     // args are returned as a flattened string with \0 separators between
     // arguments add each string to the list then step forward to the next
     // separator
     if (argsize > 0) {
@@ -248,24 +247,38 @@ error:
     return NULL;
 }
 
 
 /*
  * Return 1 if PID exists in the current process list, else 0.
  */
 int
-pid_exists(long pid)
+psutil_pid_exists(long pid)
 {
     int kill_ret;
     if (pid < 0) {
         return 0;
     }
 
     // if kill returns success of permission denied we know it's a valid PID
     kill_ret = kill(pid , 0);
     if ((0 == kill_ret) || (EPERM == errno)) {
         return 1;
     }
 
     // otherwise return 0 for PID not found
     return 0;
 }
+
+
+/*
+ * Set exception to AccessDenied if pid exists else NoSuchProcess.
+ */
+int
+psutil_raise_ad_or_nsp(pid) {
+    if (psutil_pid_exists(pid) == 0) {
+        NoSuchProcess();
+    }
+    else {
+        AccessDenied();
+    }
+}
--- a/python/psutil/psutil/arch/bsd/process_info.h
+++ b/python/psutil/psutil/arch/bsd/process_info.h
@@ -1,21 +1,18 @@
 /*
- * $Id: process_info.h 1142 2011-10-05 18:45:49Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * Helper functions related to fetching process information. Used by _psutil_bsd
  * module methods.
  */
 
 #include <Python.h>
 
 typedef struct kinfo_proc kinfo_proc;
 
-int get_proc_list(struct kinfo_proc **procList, size_t *procCount);
-char *getcmdargs(long pid, size_t *argsize);
-char *getcmdpath(long pid, size_t *pathsize);
-PyObject* get_arg_list(long pid);
-int pid_exists(long pid);
-
+int  psutil_get_proc_list(struct kinfo_proc **procList, size_t *procCount);
+char *psutil_get_cmd_args(long pid, size_t *argsize);
+char *psutil_get_cmd_path(long pid, size_t *pathsize);
+int  psutil_pid_exists(long pid);
+PyObject* psutil_get_arg_list(long pid);
--- a/python/psutil/psutil/arch/mswindows/ntextapi.h
+++ b/python/psutil/psutil/arch/mswindows/ntextapi.h
@@ -1,11 +1,9 @@
 /*
- * $Id: ntextapi.h 1452 2012-07-13 19:02:07Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  */
 
 typedef enum _KTHREAD_STATE
 {
@@ -225,8 +223,84 @@ WTSOpenServerA(
     );
 
 VOID
 WINAPI
 WTSCloseServer(
     IN HANDLE hServer
     );
 #endif
+// end mingw support:
+
+/*
+ * NtQueryInformationProcess code taken from
+ * http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/
+ * typedefs needed to compile against ntdll functions not exposted in the API
+ */
+typedef LONG NTSTATUS;
+
+typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(
+    HANDLE ProcessHandle,
+    DWORD ProcessInformationClass,
+    PVOID ProcessInformation,
+    DWORD ProcessInformationLength,
+    PDWORD ReturnLength
+    );
+
+typedef NTSTATUS (NTAPI *_NtSetInformationProcess)(
+    HANDLE ProcessHandle,
+    DWORD ProcessInformationClass,
+    PVOID ProcessInformation,
+    DWORD ProcessInformationLength
+);
+
+typedef struct _PROCESS_BASIC_INFORMATION
+{
+    PVOID Reserved1;
+    PVOID PebBaseAddress;
+    PVOID Reserved2[2];
+    ULONG_PTR UniqueProcessId;
+    PVOID Reserved3;
+} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
+
+
+typedef enum _PROCESSINFOCLASS {
+    ProcessBasicInformation,
+    ProcessQuotaLimits,
+    ProcessIoCounters,
+    ProcessVmCounters,
+    ProcessTimes,
+    ProcessBasePriority,
+    ProcessRaisePriority,
+    ProcessDebugPort,
+    ProcessExceptionPort,
+    ProcessAccessToken,
+    ProcessLdtInformation,
+    ProcessLdtSize,
+    ProcessDefaultHardErrorMode,
+    ProcessIoPortHandlers,
+    ProcessPooledUsageAndLimits,
+    ProcessWorkingSetWatch,
+    ProcessUserModeIOPL,
+    ProcessEnableAlignmentFaultFixup,
+    ProcessPriorityClass,
+    ProcessWx86Information,
+    ProcessHandleCount,
+    ProcessAffinityMask,
+    ProcessPriorityBoost,
+    ProcessDeviceMap,
+    ProcessSessionInformation,
+    ProcessForegroundInformation,
+    ProcessWow64Information,
+    /* added after XP+ */
+    ProcessImageFileName,
+    ProcessLUIDDeviceMapsEnabled,
+    ProcessBreakOnTermination,
+    ProcessDebugObjectHandle,
+    ProcessDebugFlags,
+    ProcessHandleTracing,
+    ProcessIoPriority,
+    ProcessExecuteFlags,
+    ProcessResourceManagement,
+    ProcessCookie,
+    ProcessImageInformation,
+    MaxProcessInfoClass
+} PROCESSINFOCLASS;
--- a/python/psutil/psutil/arch/mswindows/process_handles.c
+++ b/python/psutil/psutil/arch/mswindows/process_handles.c
@@ -1,11 +1,9 @@
 /*
- * $Id: process_handles.c 1463 2012-07-18 13:06:49Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  */
 
 #ifndef UNICODE
 #define UNICODE
@@ -115,17 +113,17 @@ typedef struct _OBJECT_TYPE_INFORMATION
 
 PVOID GetLibraryProcAddress(PSTR LibraryName, PSTR ProcName)
 {
     return GetProcAddress(GetModuleHandleA(LibraryName), ProcName);
 }
 
 
 PyObject*
-get_open_files(long pid, HANDLE processHandle)
+psutil_get_open_files(long pid, HANDLE processHandle)
 {
     _NtQuerySystemInformation NtQuerySystemInformation =
         GetLibraryProcAddress("ntdll.dll", "NtQuerySystemInformation");
     _NtDuplicateObject NtDuplicateObject =
         GetLibraryProcAddress("ntdll.dll", "NtDuplicateObject");
     _NtQueryObject NtQueryObject =
         GetLibraryProcAddress("ntdll.dll", "NtQueryObject");
 
@@ -134,19 +132,25 @@ get_open_files(long pid, HANDLE processH
     ULONG                       handleInfoSize = 0x10000;
 
     ULONG                       i;
     ULONG                       fileNameLength;
     PyObject                    *filesList = Py_BuildValue("[]");
     PyObject                    *arg = NULL;
     PyObject                    *fileFromWchar = NULL;
 
-
+    if (filesList == NULL)
+        return NULL;
 
     handleInfo = (PSYSTEM_HANDLE_INFORMATION)malloc(handleInfoSize);
+    if (handleInfo == NULL) {
+        Py_DECREF(filesList);
+        PyErr_NoMemory();
+        return NULL;
+    }
 
     /* NtQuerySystemInformation won't give us the correct buffer size,
        so we guess by doubling the buffer size. */
     while ((status = NtQuerySystemInformation(
         SystemHandleInformation,
         handleInfo,
         handleInfoSize,
         NULL
--- a/python/psutil/psutil/arch/mswindows/process_handles.h
+++ b/python/psutil/psutil/arch/mswindows/process_handles.h
@@ -4,9 +4,9 @@
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  */
 
 #include <Python.h>
 #include <windows.h>
 
-PyObject* get_open_files(long pid, HANDLE processHandle);
+PyObject* psutil_get_open_files(long pid, HANDLE processHandle);
--- a/python/psutil/psutil/arch/mswindows/process_info.c
+++ b/python/psutil/psutil/arch/mswindows/process_info.c
@@ -1,11 +1,9 @@
 /*
- * $Id: process_info.c 1463 2012-07-18 13:06:49Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * Helper functions related to fetching process information. Used by
  * _psutil_mswindows module methods.
  */
 
@@ -13,50 +11,27 @@
 #include <windows.h>
 #include <Psapi.h>
 #include <tlhelp32.h>
 
 #include "security.h"
 #include "process_info.h"
 #include "ntextapi.h"
 
-/*
- * NtQueryInformationProcess code taken from
- * http://wj32.wordpress.com/2009/01/24/howto-get-the-command-line-of-processes/
- * typedefs needed to compile against ntdll functions not exposted in the API
- */
-typedef LONG NTSTATUS;
-
-typedef NTSTATUS (NTAPI *_NtQueryInformationProcess)(
-    HANDLE ProcessHandle,
-    DWORD ProcessInformationClass,
-    PVOID ProcessInformation,
-    DWORD ProcessInformationLength,
-    PDWORD ReturnLength
-    );
-
-typedef struct _PROCESS_BASIC_INFORMATION
-{
-    PVOID Reserved1;
-    PVOID PebBaseAddress;
-    PVOID Reserved2[2];
-    ULONG_PTR UniqueProcessId;
-    PVOID Reserved3;
-} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;
 
 
 /*
  * 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
-handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess)
+psutil_handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess)
 {
     HANDLE hProcess;
     DWORD  processExitCode = 0;
 
     if (pid == 0) {
         // otherwise we'd get NoSuchProcess
         return AccessDenied();
     }
@@ -79,43 +54,43 @@ handle_from_pid_waccess(DWORD pid, DWORD
         CloseHandle(hProcess);
         return NULL;
     }
     return hProcess;
 }
 
 
 /*
- * Same as handle_from_pid_waccess but implicitly uses
+ * Same as psutil_handle_from_pid_waccess but implicitly uses
  * PROCESS_QUERY_INFORMATION | PROCESS_VM_READ as dwDesiredAccess
  * parameter for OpenProcess.
  */
 HANDLE
-handle_from_pid(DWORD pid) {
+psutil_handle_from_pid(DWORD pid) {
     DWORD dwDesiredAccess = PROCESS_QUERY_INFORMATION | PROCESS_VM_READ;
-    return handle_from_pid_waccess(pid, dwDesiredAccess);
+    return psutil_handle_from_pid_waccess(pid, dwDesiredAccess);
 }
 
 
 // fetch the PEB base address from NtQueryInformationProcess()
 PVOID
-GetPebAddress(HANDLE ProcessHandle)
+psutil_get_peb_address(HANDLE ProcessHandle)
 {
     _NtQueryInformationProcess NtQueryInformationProcess =
         (_NtQueryInformationProcess)GetProcAddress(
         GetModuleHandleA("ntdll.dll"), "NtQueryInformationProcess");
     PROCESS_BASIC_INFORMATION pbi;
 
     NtQueryInformationProcess(ProcessHandle, 0, &pbi, sizeof(pbi), NULL);
     return pbi.PebBaseAddress;
 }
 
 
 DWORD*
-get_pids(DWORD *numberOfReturnedPIDs) {
+psutil_get_pids(DWORD *numberOfReturnedPIDs) {
     /* Win32 SDK says the only way to know if our process array
      * wasn't large enough is to check the returned size and make
      * sure that it doesn't match the size of the array.
      * If it does we allocate a larger array and try again */
 
     // Stores the actual array
     DWORD *procArray = NULL;
     DWORD procArrayByteSz;
@@ -124,33 +99,36 @@ get_pids(DWORD *numberOfReturnedPIDs) {
     // Stores the byte size of the returned array from enumprocesses
     DWORD enumReturnSz = 0;
 
     do {
         procArraySz += 1024;
         free(procArray);
         procArrayByteSz = procArraySz * sizeof(DWORD);
         procArray = malloc(procArrayByteSz);
-
+        if (procArray == NULL) {
+            PyErr_NoMemory();
+            return NULL;
+        }
         if (! EnumProcesses(procArray, procArrayByteSz, &enumReturnSz)) {
             free(procArray);
             PyErr_SetFromWindowsErr(0);
             return NULL;
         }
     } while(enumReturnSz == procArraySz * sizeof(DWORD));
 
     // The number of elements is the returned size / size of each element
     *numberOfReturnedPIDs = enumReturnSz / sizeof(DWORD);
 
     return procArray;
 }
 
 
 int
-pid_is_running(DWORD pid)
+psutil_pid_is_running(DWORD pid)
 {
     HANDLE hProcess;
     DWORD exitCode;
 
     // Special case for PID 0 System Idle Process
     if (pid == 0) {
         return 1;
     }
@@ -192,23 +170,23 @@ pid_is_running(DWORD pid)
 
     PyErr_SetFromWindowsErr(0);
     CloseHandle(hProcess);
     return -1;
 }
 
 
 int
-pid_in_proclist(DWORD pid)
+psutil_pid_in_proclist(DWORD pid)
 {
     DWORD *proclist = NULL;
     DWORD numberOfReturnedPIDs;
     DWORD i;
 
-    proclist = get_pids(&numberOfReturnedPIDs);
+    proclist = psutil_get_pids(&numberOfReturnedPIDs);
     if (NULL == proclist) {
         return -1;
     }
 
     for (i = 0; i < numberOfReturnedPIDs; i++) {
         if (pid == proclist[i]) {
             free(proclist);
             return 1;
@@ -216,35 +194,37 @@ pid_in_proclist(DWORD pid)
     }
 
     free(proclist);
     return 0;
 }
 
 
 // Check exit code from a process handle. Return FALSE on an error also
-BOOL is_running(HANDLE hProcess)
+// XXX - not used anymore
+int
+handlep_is_running(HANDLE hProcess)
 {
     DWORD dwCode;
-
     if (NULL == hProcess) {
-        return FALSE;
+        return 0;
     }
-
     if (GetExitCodeProcess(hProcess, &dwCode)) {
-        return (dwCode == STILL_ACTIVE);
+        if (dwCode == STILL_ACTIVE) {
+            return 1;
+        }
     }
-    return FALSE;
+    return 0;
 }
 
 
 // Return None to represent NoSuchProcess, else return NULL for
 // other exception or the name as a Python string
 PyObject*
-get_name(long pid)
+psutil_get_name(long pid)
 {
     HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
     PROCESSENTRY32 pe = { 0 };
     pe.dwSize = sizeof(PROCESSENTRY32);
 
     if( Process32First(h, &pe)) {
         do {
             if (pe.th32ProcessID == pid) {
@@ -261,17 +241,17 @@ get_name(long pid)
 
     CloseHandle(h);
     return PyErr_SetFromWindowsErr(0);
 }
 
 
 /* returns parent pid (as a Python int) for given pid or None on failure */
 PyObject*
-get_ppid(long pid)
+psutil_get_ppid(long pid)
 {
     HANDLE h = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
     PROCESSENTRY32 pe = { 0 };
     pe.dwSize = sizeof(PROCESSENTRY32);
 
     if( Process32First(h, &pe)) {
         do {
             if (pe.th32ProcessID == pid) {
@@ -291,35 +271,35 @@ get_ppid(long pid)
 }
 
 
 /*
  * returns a Python list representing the arguments for the process
  * with given pid or NULL on error.
  */
 PyObject*
-get_arg_list(long pid)
+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 = handle_from_pid(pid);
+    hProcess = psutil_handle_from_pid(pid);
     if(hProcess == NULL) {
         return NULL;
     }
 
-    pebAddress = GetPebAddress(hProcess);
+    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))
@@ -342,16 +322,20 @@ get_arg_list(long pid)
         ////printf("Could not read CommandLine!\n");
         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))
     {
         ////printf("Could not read the command line string!\n");
         PyErr_SetFromWindowsErr(0);
         goto error;
@@ -381,17 +365,17 @@ get_arg_list(long pid)
         #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)
+        if (argList == NULL)
             goto error;
         for(i=0; i<nArgs; i++) {
             arg_from_wchar = NULL;
             arg = NULL;
             ////printf("%d: %.*S (%d characters)\n", i, wcslen(szArglist[i]),
             //                  szArglist[i], wcslen(szArglist[i]));
             arg_from_wchar = PyUnicode_FromWideChar(szArglist[i],
                                                     wcslen(szArglist[i])
@@ -463,48 +447,58 @@ get_process_info(DWORD pid, PSYSTEM_PROC
     NTQSI_PROC NtQuerySystemInformation;
     HINSTANCE hNtDll;
     hNtDll = LoadLibrary(TEXT("ntdll.dll"));
     NtQuerySystemInformation = (NTQSI_PROC)GetProcAddress(
                                 hNtDll, "NtQuerySystemInformation");
 
     bufferSize = initialBufferSize;
     buffer = malloc(bufferSize);
+    if (buffer == NULL) {
+        PyErr_NoMemory();
+        goto error;
+    }
 
     while (TRUE) {
         status = NtQuerySystemInformation(SystemProcessInformation, buffer,
                                           bufferSize, &bufferSize);
 
         if (status == STATUS_BUFFER_TOO_SMALL || status == STATUS_INFO_LENGTH_MISMATCH)
         {
             free(buffer);
             buffer = malloc(bufferSize);
+            if (buffer == NULL) {
+                PyErr_NoMemory();
+                goto error;
+            }
         }
         else {
             break;
         }
     }
 
     if (status != 0) {
         PyErr_Format(PyExc_RuntimeError, "NtQuerySystemInformation() failed");
-        FreeLibrary(hNtDll);
-        free(buffer);
-        return 0;
+        goto error;
     }
 
     if (bufferSize <= 0x20000) {
         initialBufferSize = bufferSize;
     }
 
     process = PH_FIRST_PROCESS(buffer);
     do {
         if (process->UniqueProcessId == (HANDLE)pid) {
             *retProcess = process;
             *retBuffer = buffer;
             return 1;
         }
     } while ( (process = PH_NEXT_PROCESS(process)) );
 
     NoSuchProcess();
+    goto error;
+
+error:
     FreeLibrary(hNtDll);
-    free(buffer);
+    if (buffer != NULL)
+        free(buffer);
     return 0;
 }
--- a/python/psutil/psutil/arch/mswindows/process_info.h
+++ b/python/psutil/psutil/arch/mswindows/process_info.h
@@ -1,25 +1,23 @@
 /*
- * $Id: process_info.h 1142 2011-10-05 18:45:49Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * Helper functions related to fetching process information. Used by _psutil_mswindows
  * module methods.
  */
 
 #include <Python.h>
 #include <windows.h>
 
-HANDLE handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess);
-HANDLE handle_from_pid(DWORD pid);
-PVOID GetPebAddress(HANDLE ProcessHandle);
-HANDLE handle_from_pid(DWORD pid);
-BOOL is_running(HANDLE hProcess);
-int pid_in_proclist(DWORD pid);
-int pid_is_running(DWORD pid);
-PyObject* get_arg_list(long pid);
-PyObject* get_ppid(long pid);
-PyObject* get_name(long pid);
-DWORD* get_pids(DWORD *numberOfReturnedPIDs);
+HANDLE psutil_handle_from_pid_waccess(DWORD pid, DWORD dwDesiredAccess);
+HANDLE psutil_handle_from_pid(DWORD pid);
+PVOID psutil_get_peb_address(HANDLE ProcessHandle);
+HANDLE psutil_handle_from_pid(DWORD pid);
+int psutil_pid_in_proclist(DWORD pid);
+int psutil_pid_is_running(DWORD pid);
+int psutil_handlep_is_running(HANDLE hProcess);
+PyObject* psutil_get_arg_list(long pid);
+PyObject* psutil_get_ppid(long pid);
+PyObject* psutil_get_name(long pid);
+DWORD* psutil_get_pids(DWORD *numberOfReturnedPIDs);
--- a/python/psutil/psutil/arch/mswindows/security.c
+++ b/python/psutil/psutil/arch/mswindows/security.c
@@ -1,11 +1,9 @@
 /*
- * $Id: security.c 1296 2012-04-25 01:29:43Z david.daeschler@gmail.com $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * Security related functions for Windows platform (Set privileges such as
  * SeDebug), as well as security helper functions.
  */
 
@@ -63,20 +61,18 @@ int HasSystemPrivilege(HANDLE hProcess) 
             PyErr_SetFromWindowsErr(dwRetval);
             return 0;
         }
     }
 
     // allocate buffer and call GetTokenInformation again
     //tp = (PTOKEN_PRIVILEGES) GlobalAlloc(GPTR, dwSize);
     pBuffer = (BYTE *) malloc(dwSize);
-
     if (pBuffer == NULL) {
-        PyErr_SetFromWindowsErr(0);
-        free(pBuffer);
+        PyErr_NoMemory();
         return -1;
     }
 
     if (! GetTokenInformation(hToken, TokenPrivileges, pBuffer, dwSize, &dwSize) ) {
         PyErr_SetFromWindowsErr(0);
         free(pBuffer);
         return -1;
     }
@@ -232,9 +228,8 @@ int UnsetSeDebug()
     if(!SetPrivilege(hToken, SE_DEBUG_NAME, FALSE)){
         //Log2File("Error unsetting SeDebug Privilege [SetPrivilege()]", L_WARN);
         return 0;
     }
 
     CloseHandle(hToken);
     return 1;
 }
-
--- a/python/psutil/psutil/arch/mswindows/security.h
+++ b/python/psutil/psutil/arch/mswindows/security.h
@@ -1,11 +1,9 @@
 /*
- * $Id: security.h 1142 2011-10-05 18:45:49Z g.rodola $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * Security related functions for Windows platform (Set privileges such as
  * SeDebug), as well as security helper functions.
  */
 
--- a/python/psutil/psutil/arch/osx/process_info.c
+++ b/python/psutil/psutil/arch/osx/process_info.c
@@ -1,11 +1,9 @@
 /*
- * $Id: process_info.c 1460 2012-07-18 02:49:24Z g.rodola@gmail.com $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * Helper functions related to fetching process information. Used by _psutil_osx
  * module methods.
  */
 
@@ -23,17 +21,17 @@
 #include "process_info.h"
 #include "../../_psutil_common.h"
 
 
 /*
  * Return 1 if PID exists in the current process list, else 0.
  */
 int
-pid_exists(long pid)
+psutil_pid_exists(long pid)
 {
     int kill_ret;
 
     // save some time if it's an invalid PID
     if (pid < 0) {
         return 0;
     }
 
@@ -53,17 +51,17 @@ pid_exists(long pid)
  * Returns a list of all BSD processes on the system.  This routine
  * allocates the list and puts it in *procList and a count of the
  * number of entries in *procCount.  You are responsible for freeing
  * this list (use "free" from System framework).
  * On success, the function returns 0.
  * On error, the function returns a BSD errno value.
  */
 int
-get_proc_list(kinfo_proc **procList, size_t *procCount)
+psutil_get_proc_list(kinfo_proc **procList, size_t *procCount)
 {
     /* Declaring mib as const requires use of a cast since the
      * sysctl prototype doesn't include the const modifier. */
     static const int mib3[3] = { CTL_KERN, KERN_PROC, KERN_PROC_ALL };
     size_t           size, size2;
     void            *ptr;
     int              err, lim = 8;  /* some limit */
 
@@ -120,32 +118,32 @@ get_proc_list(kinfo_proc **procList, siz
         }
     }
     return ENOMEM;
 }
 
 
 /* Read the maximum argument size for processes */
 int
-get_argmax()
+psutil_get_argmax()
 {
     int argmax;
     int mib[] = { CTL_KERN, KERN_ARGMAX };
     size_t size = sizeof(argmax);
 
     if (sysctl(mib, 2, &argmax, &size, NULL, 0) == 0) {
         return argmax;
     }
     return 0;
 }
 
 
 /* return process args as a python list */
 PyObject*
-get_arg_list(long pid)
+psutil_get_arg_list(long pid)
 {
     int mib[3];
     int nargs;
     int len;
     char *procargs = NULL;
     char *arg_ptr;
     char *arg_end;
     char *curr_arg;
@@ -154,17 +152,17 @@ get_arg_list(long pid)
     PyObject *arglist = NULL;
 
     //special case for PID 0 (kernel_task) where cmdline cannot be fetched
     if (pid == 0) {
         return Py_BuildValue("[]");
     }
 
     /* read argmax and allocate memory for argument space. */
-    argmax = get_argmax();
+    argmax = psutil_get_argmax();
     if (! argmax) {
         PyErr_SetFromErrno(PyExc_OSError);
         goto error;
     }
 
     procargs = (char *)malloc(argmax);
     if (NULL == procargs) {
         PyErr_SetFromErrno(PyExc_OSError);
@@ -172,17 +170,17 @@ get_arg_list(long pid)
     }
 
     /* read argument space */
     mib[0] = CTL_KERN;
     mib[1] = KERN_PROCARGS2;
     mib[2] = pid;
     if (sysctl(mib, 3, procargs, &argmax, NULL, 0) < 0) {
         if (EINVAL == errno) { // invalid == access denied OR nonexistent PID
-            if ( pid_exists(pid) ) {
+            if ( psutil_pid_exists(pid) ) {
                 AccessDenied();
             } else {
                 NoSuchProcess();
             }
         }
         goto error;
     }
 
@@ -233,17 +231,17 @@ error:
     Py_XDECREF(arglist);
     if (procargs != NULL)
         free(procargs);
     return NULL;
 }
 
 
 int
-get_kinfo_proc(pid_t pid, struct kinfo_proc *kp)
+psutil_get_kinfo_proc(pid_t pid, struct kinfo_proc *kp)
 {
     int mib[4];
     size_t len;
     mib[0] = CTL_KERN;
     mib[1] = KERN_PROC;
     mib[2] = KERN_PROC_PID;
     mib[3] = pid;
 
@@ -271,17 +269,17 @@ get_kinfo_proc(pid_t pid, struct kinfo_p
 /*
  * A thin wrapper around proc_pidinfo()
  */
 int
 psutil_proc_pidinfo(long pid, int flavor, void *pti, int size)
 {
     int ret = proc_pidinfo((int)pid, flavor, 0, pti, size);
     if (ret == 0) {
-        if (! pid_exists(pid)) {
+        if (! psutil_pid_exists(pid)) {
             NoSuchProcess();
             return 0;
         }
         else {
             AccessDenied();
             return 0;
         }
     }
--- a/python/psutil/psutil/arch/osx/process_info.h
+++ b/python/psutil/psutil/arch/osx/process_info.h
@@ -1,22 +1,20 @@
 /*
- * $Id: process_info.h 1407 2012-06-30 17:14:54Z g.rodola@gmail.com $
- *
  * Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
  * Use of this source code is governed by a BSD-style license that can be
  * found in the LICENSE file.
  *
  * Helper functions related to fetching process information. Used by _psutil_osx
  * module methods.
  */
 
 #include <Python.h>
 
 
 typedef struct kinfo_proc kinfo_proc;
 
-int get_proc_list(kinfo_proc **procList, size_t *procCount);
-int get_kinfo_proc(pid_t pid, struct kinfo_proc *kp);
-int get_argmax(void);
-int pid_exists(long pid);
+int psutil_get_proc_list(kinfo_proc **procList, size_t *procCount);
+int psutil_get_kinfo_proc(pid_t pid, struct kinfo_proc *kp);
+int psutil_get_argmax(void);
+int psutil_pid_exists(long pid);
 int psutil_proc_pidinfo(long pid, int flavor, void *pti, int size);
-PyObject* get_arg_list(long pid);
+PyObject* psutil_get_arg_list(long pid);
--- a/python/psutil/psutil/error.py
+++ b/python/psutil/psutil/error.py
@@ -1,73 +1,19 @@
 #!/usr/bin/env python
-#
-# $Id: error.py 1142 2011-10-05 18:45:49Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
-"""psutil exception classes;  do not import this directly"""
-
-
-class Error(Exception):
-    """Base exception class. All other psutil exceptions inherit
-    from this one.
-    """
-
-class NoSuchProcess(Error):
-    """Exception raised when a process with a certain PID doesn't
-    or no longer exists (zombie).
-    """
-
-    def __init__(self, pid, name=None, msg=None):
-        self.pid = pid
-        self.name = name
-        self.msg = msg
-        if msg is None:
-            if name:
-                details = "(pid=%s, name=%s)" % (self.pid, repr(self.name))
-            else:
-                details = "(pid=%s)" % self.pid
-            self.msg = "process no longer exists " + details
-
-    def __str__(self):
-        return self.msg
-
-
-class AccessDenied(Error):
-    """Exception raised when permission to perform an action is denied."""
+"""This module is deprecated as exceptions are defined in _error.py
+and are supposed to be accessed from 'psutil' namespace as in:
+- psutil.NoSuchProcess
+- psutil.AccessDenied
+- psutil.TimeoutExpired
+"""
 
-    def __init__(self, pid=None, name=None, msg=None):
-        self.pid = pid
-        self.name = name
-        self.msg = msg
-        if msg is None:
-            if (pid is not None) and (name is not None):
-                self.msg = "(pid=%s, name=%s)" % (pid, repr(name))
-            elif (pid is not None):
-                self.msg = "(pid=%s)" % self.pid
-            else:
-                self.msg = ""
-
-    def __str__(self):
-        return self.msg
-
+import warnings
+from psutil._error import *
 
-class TimeoutExpired(Error):
-    """Raised on Process.wait(timeout) if timeout expires and process
-    is still alive.
-    """
-
-    def __init__(self, pid=None, name=None):
-        self.pid = pid
-        self.name = name
-        if (pid is not None) and (name is not None):
-            self.msg = "(pid=%s, name=%s)" % (pid, repr(name))
-        elif (pid is not None):
-            self.msg = "(pid=%s)" % self.pid
-        else:
-            self.msg = ""
-
-    def __str__(self):
-        return self.msg
-
+warnings.warn("psutil.error module is deprecated and scheduled for removal; " \
+              "use psutil namespace instead", category=DeprecationWarning,
+               stacklevel=2)
deleted file mode 100644
--- a/python/psutil/setup.cfg
+++ /dev/null
@@ -1,5 +0,0 @@
-[egg_info]
-tag_build = 
-tag_date = 0
-tag_svn_revision = 0
-
--- a/python/psutil/setup.py
+++ b/python/psutil/setup.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: setup.py 1469 2012-07-18 16:00:39Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 import sys
 import os
 try:
     from setuptools import setup, Extension
@@ -132,16 +130,17 @@ def main():
               'Programming Language :: Python :: 2.4',
               'Programming Language :: Python :: 2.5',
               'Programming Language :: Python :: 2.6',
               'Programming Language :: Python :: 2.7',
               'Programming Language :: Python :: 3',
               'Programming Language :: Python :: 3.0',
               'Programming Language :: Python :: 3.1',
               'Programming Language :: Python :: 3.2',
+              'Programming Language :: Python :: 3.3',
               'Topic :: System :: Monitoring',
               'Topic :: System :: Networking',
               'Topic :: System :: Networking :: Monitoring',
               'Topic :: System :: Benchmark',
               'Topic :: System :: Hardware',
               'Topic :: System :: Systems Administration',
               'Topic :: Utilities',
               'Topic :: Software Development :: Libraries',
--- a/python/psutil/test/_bsd.py
+++ b/python/psutil/test/_bsd.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: _bsd.py 1498 2012-07-24 21:41:28Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """BSD specific tests.  These are implicitly run by test_psutil.py."""
 
 import unittest
 import subprocess
--- a/python/psutil/test/_linux.py
+++ b/python/psutil/test/_linux.py
@@ -1,24 +1,23 @@
 #!/usr/bin/env python
-#
-# $Id: _linux.py 1498 2012-07-24 21:41:28Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """Linux specific tests.  These are implicitly run by test_psutil.py."""
 
 from __future__ import division
 import unittest
 import subprocess
 import sys
 import time
 import os
+import re
 
 from test_psutil import sh, get_test_subprocess
 from psutil._compat import PY3
 import psutil
 
 
 TOLERANCE = 200 * 1024  # 200 KB
 
@@ -110,13 +109,33 @@ class LinuxSpecificTestCase(unittest.Tes
         used = int(lines[2].split()[2]) * 1024
         self.assert_eq_w_tol(used, psutil.swap_memory().used, TOLERANCE)
 
     def test_swapmem_free(self):
         lines = sh('free').split('\n')[1:]
         free = int(lines[2].split()[3]) * 1024
         self.assert_eq_w_tol(free, psutil.swap_memory().free, TOLERANCE)
 
+    def test_cpu_times(self):
+        fields = psutil.cpu_times()._fields
+        kernel_ver = re.findall('\d.\d.\d', os.uname()[2])[0]
+        kernel_ver_info = tuple(map(int, kernel_ver.split('.')))
+        # steal >= 2.6.11
+        # guest >= 2.6.24
+        # guest_nice >= 3.2.0
+        if kernel_ver_info >= (2, 6, 11):
+            assert 'steal' in fields, fields
+        else:
+            assert 'steal' not in fields, fields
+        if kernel_ver_info >= (2, 6, 24):
+            assert 'guest' in fields, fields
+        else:
+            assert 'guest' not in fields, fields
+        if kernel_ver_info >= (3, 2, 0):
+            assert 'guest_nice' in fields, fields
+        else:
+            assert 'guest_nice' not in fields, fields
+
 
 if __name__ == '__main__':
     test_suite = unittest.TestSuite()
     test_suite.addTest(unittest.makeSuite(LinuxSpecificTestCase))
     unittest.TextTestRunner(verbosity=2).run(test_suite)
--- a/python/psutil/test/_osx.py
+++ b/python/psutil/test/_osx.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: _osx.py 1498 2012-07-24 21:41:28Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """OSX specific tests.  These are implicitly run by test_psutil.py."""
 
 import unittest
 import subprocess
@@ -17,17 +15,17 @@ import re
 
 import psutil
 
 from psutil._compat import PY3
 from test_psutil import reap_children, get_test_subprocess, sh
 
 
 PAGESIZE = os.sysconf("SC_PAGE_SIZE")
-TOLERANCE = 200 * 1024  # 200 KB
+TOLERANCE = 500 * 1024  # 500 KB
 
 
 def sysctl(cmdline):
     """Expects a sysctl command with an argument and parse the result
     returning only the value of interest.
     """
     p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE)
     result = p.communicate()[0].strip().split()[1]
@@ -56,17 +54,17 @@ class OSXSpecificTestCase(unittest.TestC
 
     def tearDown(self):
         reap_children()
 
     def assert_eq_w_tol(self, first, second, tolerance):
         difference = abs(first - second)
         if difference <= tolerance:
             return
-        msg = '%r != %r within %r delta (%r difference)' \
+        msg = '%r != %r (tolerance=%r, difference=%s)' \
               % (first, second, tolerance, difference)
         raise AssertionError(msg)
 
     def test_process_create_time(self):
         cmdline = "ps -o lstart -p %s" %self.pid
         p = subprocess.Popen(cmdline, shell=1, stdout=subprocess.PIPE)
         output = p.communicate()[0]
         if PY3:
--- a/python/psutil/test/_posix.py
+++ b/python/psutil/test/_posix.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: _posix.py 1386 2012-06-27 15:44:36Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """POSIX specific tests.  These are implicitly run by test_psutil.py."""
 
 import unittest
 import subprocess
@@ -14,17 +12,17 @@ import time
 import sys
 import os
 import datetime
 
 import psutil
 
 from psutil._compat import PY3
 from test_psutil import (get_test_subprocess, reap_children, PYTHON, LINUX, OSX,
-                         BSD, ignore_access_denied, sh, skipIf)
+                         BSD, skip_on_access_denied, sh, skipIf)
 
 
 def ps(cmd):
     """Expects a ps command with a -o argument and parse the result
     returning only the value of interest.
     """
     if not LINUX:
         cmd = cmd.replace(" --no-headers ", " ")
@@ -67,26 +65,26 @@ class PosixSpecificTestCase(unittest.Tes
         gid_psutil = psutil.Process(self.pid).gids.real
         self.assertEqual(gid_ps, gid_psutil)
 
     def test_process_username(self):
         username_ps = ps("ps --no-headers -o user -p %s" %self.pid)
         username_psutil = psutil.Process(self.pid).username
         self.assertEqual(username_ps, username_psutil)
 
-    @ignore_access_denied
+    @skip_on_access_denied()
     def test_process_rss_memory(self):
         # give python interpreter some time to properly initialize
         # so that the results are the same
         time.sleep(0.1)
         rss_ps = ps("ps --no-headers -o rss -p %s" %self.pid)
         rss_psutil = psutil.Process(self.pid).get_memory_info()[0] / 1024
         self.assertEqual(rss_ps, rss_psutil)
 
-    @ignore_access_denied
+    @skip_on_access_denied()
     def test_process_vsz_memory(self):
         # give python interpreter some time to properly initialize
         # so that the results are the same
         time.sleep(0.1)
         vsz_ps = ps("ps --no-headers -o vsz -p %s" %self.pid)
         vsz_psutil = psutil.Process(self.pid).get_memory_info()[1] / 1024
         self.assertEqual(vsz_ps, vsz_psutil)
 
--- a/python/psutil/test/_windows.py
+++ b/python/psutil/test/_windows.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: _windows.py 1453 2012-07-13 19:55:11Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """Windows specific tests.  These are implicitly run by test_psutil.py."""
 
 import os
 import unittest
--- a/python/psutil/test/test_memory_leaks.py
+++ b/python/psutil/test/test_memory_leaks.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: test_memory_leaks.py 1499 2012-07-25 12:42:31Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """
 A test script which attempts to detect memory leaks by calling C
 functions many times and compare process memory usage before and
 after the calls.  It might produce false positives.
@@ -144,17 +142,21 @@ class TestProcessObjectLeaks(Base):
 
     def test_get_io_counters(self):
         self.execute('get_io_counters')
 
     def test_get_ionice(self):
         self.execute('get_ionice')
 
     def test_set_ionice(self):
-        self.execute('set_ionice', psutil.IOPRIO_CLASS_NONE)
+        if WINDOWS:
+            value = psutil.Process(os.getpid()).get_ionice()
+            self.execute('set_ionice', value)
+        else:
+            self.execute('set_ionice', psutil.IOPRIO_CLASS_NONE)
 
     def test_username(self):
         self.execute('username')
 
     def test_create_time(self):
         self.execute('create_time')
 
     def test_get_num_threads(self):
--- a/python/psutil/test/test_psutil.py
+++ b/python/psutil/test/test_psutil.py
@@ -1,12 +1,10 @@
 #!/usr/bin/env python
-#
-# $Id: test_psutil.py 1525 2012-08-16 16:32:03Z g.rodola $
-#
+
 # Copyright (c) 2009, Jay Loden, Giampaolo Rodola'. All rights reserved.
 # Use of this source code is governed by a BSD-style license that can be
 # found in the LICENSE file.
 
 """
 psutil test suite.
 
 Note: this is targeted for both python 2.x and 3.x so there's no need
@@ -28,52 +26,52 @@ import atexit
 import errno
 import threading
 import tempfile
 import stat
 import collections
 import datetime
 
 import psutil
-from psutil._compat import PY3, callable, long
+from psutil._compat import PY3, callable, long, wraps
 
 
 PYTHON = os.path.realpath(sys.executable)
 DEVNULL = open(os.devnull, 'r+')
 TESTFN = os.path.join(os.getcwd(), "$testfile")
 POSIX = os.name == 'posix'
 LINUX = sys.platform.startswith("linux")
 WINDOWS = sys.platform.startswith("win32")
 OSX = sys.platform.startswith("darwin")
 BSD = sys.platform.startswith("freebsd")
 
 
 _subprocesses_started = set()
 
-def get_test_subprocess(cmd=None, stdout=DEVNULL, stderr=DEVNULL, stdin=None,
+def get_test_subprocess(cmd=None, stdout=DEVNULL, stderr=DEVNULL, stdin=DEVNULL,
                         wait=False):
     """Return a subprocess.Popen object to use in tests.
     By default stdout and stderr are redirected to /dev/null and the
     python interpreter is used as test process.
     If 'wait' is True attemps to make sure the process is in a
     reasonably initialized state.
     """
     if cmd is None:
         pyline = ""
         if wait:
-            pyline += "open('%s', 'w'); " % TESTFN
+            pyline += "open(r'%s', 'w'); " % TESTFN
         pyline += "import time; time.sleep(3600);"
         cmd_ = [PYTHON, "-c", pyline]
     else:
         cmd_ = cmd
     sproc = subprocess.Popen(cmd_, stdout=stdout, stderr=stderr, stdin=stdin)
     if wait:
         if cmd is None:
             stop_at = time.time() + 3
-            while time.time() > stop_at:
+            while stop_at > time.time():
                 if os.path.exists(TESTFN):
                     break
                 time.sleep(0.001)
             else:
                 warn("couldn't make sure test file was actually created")
         else:
             wait_for_pid(sproc.pid)
     _subprocesses_started.add(sproc.pid)
@@ -161,17 +159,19 @@ def check_ip_address(addr, family):
         for num in ip:
             assert 0 <= num <= 255, ip
     assert 0 <= port <= 65535, port
 
 def safe_remove(fname):
     try:
         os.remove(fname)
     except OSError:
-        pass
+        err = sys.exc_info()[1]
+        if err.args[0] != errno.ENOENT:
+            raise
 
 def call_until(fun, expr, timeout=1):
     """Keep calling function for timeout secs and exit if eval()
     expression is True.
     """
     stop_at = time.time() + timeout
     while time.time() < stop_at:
         ret = fun()
@@ -208,26 +208,32 @@ def skipIf(condition, reason="", warn=Fa
     return outer
 
 def skipUnless(condition, reason="", warn=False):
     """Contrary of skipIf."""
     if not condition:
         return skipIf(True, reason, warn)
     return skipIf(False)
 
-def ignore_access_denied(fun):
+def skip_on_access_denied(only_if=None):
     """Decorator to Ignore AccessDenied exceptions."""
-    def outer(fun, *args, **kwargs):
-        def inner(self):
+    def decorator(fun):
+        @wraps(fun)
+        def wrapper(*args, **kwargs):
             try:
-                return fun(self, *args, **kwargs)
+                return fun(*args, **kwargs)
             except psutil.AccessDenied:
-                pass
-        return inner
-    return outer
+                if only_if is not None:
+                    if not only_if:
+                        raise
+                atexit.register(warn, "%r was skipped because it raised " \
+                                      "AccessDenied" % fun.__name__)
+        return wrapper
+    return decorator
+
 
 def supports_ipv6():
     """Return True if IPv6 is supported on this platform."""
     if not socket.has_ipv6 or not hasattr(socket, "AF_INET6"):
         return False
     sock = None
     try:
         try:
@@ -315,38 +321,48 @@ class TestCase(unittest.TestCase):
         assert sproc.pid not in [x.pid for x in psutil.process_iter()]
 
     def test_TOTAL_PHYMEM(self):
         x = psutil.TOTAL_PHYMEM
         assert isinstance(x, (int, long))
         assert x > 0
         self.assertEqual(x, psutil.virtual_memory().total)
 
-    def test_BOOT_TIME(self):
-        x = psutil.BOOT_TIME
-        assert isinstance(x, float)
-        assert x > 0
+    def test_BOOT_TIME(self, arg=None):
+        x = arg or psutil.BOOT_TIME
+        assert isinstance(x, float), x
+        assert x > 0, x
         assert x < time.time(), x
 
+    def test_get_boot_time(self):
+        self.test_BOOT_TIME(psutil.get_boot_time())
+        if WINDOWS:
+            # work around float precision issues; give it 1 secs tolerance
+            diff = abs(psutil.get_boot_time() - psutil.BOOT_TIME)
+            assert diff < 1, diff
+        else:
+            self.assertEqual(psutil.get_boot_time(), psutil.BOOT_TIME)
+
     def test_NUM_CPUS(self):
         self.assertEqual(psutil.NUM_CPUS, len(psutil.cpu_times(percpu=True)))
         assert psutil.NUM_CPUS >= 1, psutil.NUM_CPUS
 
     @skipUnless(POSIX)
     def test_PAGESIZE(self):
         # pagesize is used internally to perform different calculations
         # and it's determined by using SC_PAGE_SIZE; make sure
         # getpagesize() returns the same value.
         import resource
         self.assertEqual(os.sysconf("SC_PAGE_SIZE"), resource.getpagesize())
 
     def test_deprecated_apis(self):
         warnings.filterwarnings("error")
         p = psutil.Process(os.getpid())
         try:
+            self.assertRaises(DeprecationWarning, __import__, 'psutil.error')
             self.assertRaises(DeprecationWarning, psutil.virtmem_usage)
             self.assertRaises(DeprecationWarning, psutil.used_phymem)
             self.assertRaises(DeprecationWarning, psutil.avail_phymem)
             self.assertRaises(DeprecationWarning, psutil.total_virtmem)
             self.assertRaises(DeprecationWarning, psutil.used_virtmem)
             self.assertRaises(DeprecationWarning, psutil.avail_virtmem)
             self.assertRaises(DeprecationWarning, psutil.phymem_usage)
             self.assertRaises(DeprecationWarning, psutil.get_process_list)
@@ -463,49 +479,69 @@ class TestCase(unittest.TestCase):
             total = 0
             sum(times)
             for cp_time in times:
                 assert isinstance(cp_time, float)
                 assert cp_time >= 0.0, cp_time
                 total += cp_time
             self.assertEqual(total, sum(times))
             str(times)
+        self.assertEqual(len(psutil.cpu_times(percpu=True)[0]),
+                         len(psutil.cpu_times(percpu=False)))
 
     def test_sys_per_cpu_times2(self):
         tot1 = psutil.cpu_times(percpu=True)
         stop_at = time.time() + 0.1
         while 1:
             if time.time() >= stop_at:
                 break
         tot2 = psutil.cpu_times(percpu=True)
         for t1, t2 in zip(tot1, tot2):
             t1, t2 = sum(t1), sum(t2)
             difference = t2 - t1
             if difference >= 0.05:
                 return
         self.fail()
 
+    def _test_cpu_percent(self, percent):
+        assert isinstance(percent, float), percent
+        assert percent >= 0.0, percent
+        assert percent <= 100.0, percent
+
     def test_sys_cpu_percent(self):
         psutil.cpu_percent(interval=0.001)
-        psutil.cpu_percent(interval=0.001)
         for x in range(1000):
-            percent = psutil.cpu_percent(interval=None)
-            assert isinstance(percent, float)
-            assert percent >= 0.0, percent
-            assert percent <= 100.0, percent
+            self._test_cpu_percent(psutil.cpu_percent(interval=None))
 
     def test_sys_per_cpu_percent(self):
-        psutil.cpu_percent(interval=0.001, percpu=True)
-        psutil.cpu_percent(interval=0.001, percpu=True)
+        self.assertEqual(len(psutil.cpu_percent(interval=0.001, percpu=True)),
+                         psutil.NUM_CPUS)
         for x in range(1000):
             percents = psutil.cpu_percent(interval=None, percpu=True)
             for percent in percents:
-                assert isinstance(percent, float)
-                assert percent >= 0.0, percent
-                assert percent <= 100.0, percent
+                self._test_cpu_percent(percent)
+
+    def test_sys_cpu_times_percent(self):
+        psutil.cpu_times_percent(interval=0.001)
+        for x in range(1000):
+            cpu = psutil.cpu_times_percent(interval=None)
+            for percent in cpu:
+                self._test_cpu_percent(percent)
+            self._test_cpu_percent(sum(cpu))
+
+    def test_sys_per_cpu_times_percent(self):
+        self.assertEqual(len(psutil.cpu_times_percent(interval=0.001,
+                                                      percpu=True)),
+                         psutil.NUM_CPUS)
+        for x in range(1000):
+            cpus = psutil.cpu_times_percent(interval=None, percpu=True)
+            for cpu in cpus:
+                for percent in cpu:
+                    self._test_cpu_percent(percent)
+                self._test_cpu_percent(sum(cpu))
 
     def test_disk_usage(self):
         usage = psutil.disk_usage(os.getcwd())
         assert usage.total > 0, usage
         assert usage.used > 0, usage
         assert usage.free > 0, usage
         assert usage.total > usage.used, usage
         assert usage.total > usage.free, usage
@@ -520,16 +556,18 @@ class TestCase(unittest.TestCase):
             err = sys.exc_info()[1]
             if err.args[0] != errno.ENOENT:
                 raise
         else:
             self.fail("OSError not raised")
 
     def test_disk_partitions(self):
         for disk in psutil.disk_partitions(all=False):
+            if WINDOWS and 'cdrom' in disk.opts:
+                continue
             assert os.path.exists(disk.device), disk
             assert os.path.isdir(disk.mountpoint), disk
             assert disk.fstype, disk
             assert isinstance(disk.opts, str)
         for disk in psutil.disk_partitions(all=True):
             if not WINDOWS:
                 try:
                     os.stat(disk.mountpoint)
@@ -594,19 +632,27 @@ class TestCase(unittest.TestCase):
             assert nt.read_bytes >= 0, nt
             assert nt.write_bytes >= 0, nt
             assert nt.read_time >= 0, nt
             assert nt.write_time >= 0, nt
 
         ret = psutil.disk_io_counters(perdisk=False)
         check_ntuple(ret)
         ret = psutil.disk_io_counters(perdisk=True)
+        # make sure there are no duplicates
+        self.assertEqual(len(ret), len(set(ret)))
         for key in ret:
             assert key, key
             check_ntuple(ret[key])
+            if LINUX and key[-1].isdigit():
+                # if 'sda1' is listed 'sda' shouldn't, see:
+                # http://code.google.com/p/psutil/issues/detail?id=338
+                while key[-1].isdigit():
+                    key = key[:-1]
+                assert key not in ret, (key, ret.keys())
 
     def test_get_users(self):
         users = psutil.get_users()
         assert users
         for user in users:
             assert user.name, user
             user.terminal
             user.host
@@ -823,47 +869,63 @@ class TestCase(unittest.TestCase):
             f.write("x" * 1000000)
         f.close()
         io2 = p.get_io_counters()
         assert io2.write_count >= io1.write_count, (io1, io2)
         assert io2.write_bytes >= io1.write_bytes, (io1, io2)
         assert io2.read_count >= io1.read_count, (io1, io2)
         assert io2.read_bytes >= io1.read_bytes, (io1, io2)
 
-    @skipUnless(LINUX)
+    # Linux and Windows Vista+
+    @skipUnless(hasattr(psutil.Process, 'get_ionice'))
     def test_get_set_ionice(self):
-        from psutil import (IOPRIO_CLASS_NONE, IOPRIO_CLASS_RT, IOPRIO_CLASS_BE,
-                            IOPRIO_CLASS_IDLE)
-        self.assertEqual(IOPRIO_CLASS_NONE, 0)
-        self.assertEqual(IOPRIO_CLASS_RT, 1)
-        self.assertEqual(IOPRIO_CLASS_BE, 2)
-        self.assertEqual(IOPRIO_CLASS_IDLE, 3)
-        p = psutil.Process(os.getpid())
-        try:
-            p.set_ionice(2)
-            ioclass, value = p.get_ionice()
-            self.assertEqual(ioclass, 2)
-            self.assertEqual(value, 4)
+        if LINUX:
+            from psutil import (IOPRIO_CLASS_NONE, IOPRIO_CLASS_RT,
+                                IOPRIO_CLASS_BE, IOPRIO_CLASS_IDLE)
+            self.assertEqual(IOPRIO_CLASS_NONE, 0)
+            self.assertEqual(IOPRIO_CLASS_RT, 1)
+            self.assertEqual(IOPRIO_CLASS_BE, 2)
+            self.assertEqual(IOPRIO_CLASS_IDLE, 3)
+            p = psutil.Process(os.getpid())
+            try:
+                p.set_ionice(2)
+                ioclass, value = p.get_ionice()
+                self.assertEqual(ioclass, 2)
+                self.assertEqual(value, 4)
+                #
+                p.set_ionice(3)
+                ioclass, value = p.get_ionice()
+                self.assertEqual(ioclass, 3)
+                self.assertEqual(value, 0)
+                #
+                p.set_ionice(2, 0)
+                ioclass, value = p.get_ionice()
+                self.assertEqual(ioclass, 2)
+                self.assertEqual(value, 0)
+                p.set_ionice(2, 7)
+                ioclass, value = p.get_ionice()
+                self.assertEqual(ioclass, 2)
+                self.assertEqual(value, 7)
+                self.assertRaises(ValueError, p.set_ionice, 2, 10)
+            finally:
+                p.set_ionice(IOPRIO_CLASS_NONE)
+        else:
+            p = psutil.Process(os.getpid())
+            original = p.get_ionice()
+            try:
+                value = 0  # very low
+                if original == value:
+                    value = 1  # low
+                p.set_ionice(value)
+                self.assertEqual(p.get_ionice(), value)
+            finally:
+                p.set_ionice(original)
             #
-            p.set_ionice(3)
-            ioclass, value = p.get_ionice()
-            self.assertEqual(ioclass, 3)
-            self.assertEqual(value, 0)
-            #
-            p.set_ionice(2, 0)
-            ioclass, value = p.get_ionice()
-            self.assertEqual(ioclass, 2)
-            self.assertEqual(value, 0)
-            p.set_ionice(2, 7)
-            ioclass, value = p.get_ionice()
-            self.assertEqual(ioclass, 2)
-            self.assertEqual(value, 7)
-            self.assertRaises(ValueError, p.set_ionice, 2, 10)
-        finally:
-            p.set_ionice(IOPRIO_CLASS_NONE)
+            self.assertRaises(ValueError, p.set_ionice, 3)
+            self.assertRaises(TypeError, p.set_ionice, 2, 1)
 
     def test_get_num_threads(self):
         # on certain platforms such as Linux we might test for exact
         # thread number, since we always have with 1 thread per process,
         # but this does not apply across all platforms (OSX, Windows)
         p = psutil.Process(os.getpid())
         step1 = p.get_num_threads()
 
@@ -978,33 +1040,38 @@ class TestCase(unittest.TestCase):
         assert not p.is_running()
 
     def test_exe(self):
         sproc = get_test_subprocess(wait=True)
         exe = psutil.Process(sproc.pid).exe
         try:
             self.assertEqual(exe, PYTHON)
         except AssertionError:
-            # certain platforms such as BSD are more accurate returning:
-            # "/usr/local/bin/python2.7"
-            # ...instead of:
-            # "/usr/local/bin/python"
-            # We do not want to consider this difference in accuracy
-            # an error.
-            ver = "%s.%s" % (sys.version_info[0], sys.version_info[1])
-            self.assertEqual(exe.replace(ver, ''), PYTHON.replace(ver, ''))
+            if WINDOWS and len(exe) == len(PYTHON):
+                # on Windows we don't care about case sensitivity
+                self.assertEqual(exe.lower(), PYTHON.lower())
+            else:
+                # certain platforms such as BSD are more accurate returning:
+                # "/usr/local/bin/python2.7"
+                # ...instead of:
+                # "/usr/local/bin/python"
+                # We do not want to consider this difference in accuracy
+                # an error.
+                ver = "%s.%s" % (sys.version_info[0], sys.version_info[1])
+                self.assertEqual(exe.replace(ver, ''), PYTHON.replace(ver, ''))
 
     def test_cmdline(self):
         sproc = get_test_subprocess([PYTHON, "-E"], wait=True)
         self.assertEqual(psutil.Process(sproc.pid).cmdline, [PYTHON, "-E"])
 
     def test_name(self):
         sproc = get_test_subprocess(PYTHON, wait=True)
+        name = psutil.Process(sproc.pid).name.lower()
         pyexe = os.path.basename(os.path.realpath(sys.executable)).lower()
-        self.assertEqual(psutil.Process(sproc.pid).name.lower(), pyexe)
+        assert pyexe.startswith(name), (pyexe, name)
 
     if os.name == 'posix':
 
         def test_uids(self):
             p = psutil.Process(os.getpid())
             real, effective, saved = p.uids
             # os.getuid() refers to "real" uid
             self.assertEqual(real, os.getuid())
@@ -1362,17 +1429,17 @@ class TestCase(unittest.TestCase):
         self.assertEqual(p.get_num_fds(), start + 2)
         file.close()
         sock.close()
         self.assertEqual(p.get_num_fds(), start)
 
     def test_get_num_ctx_switches(self):
         p = psutil.Process(os.getpid())
         before = sum(p.get_num_ctx_switches())
-        for x in range(50000):
+        for x in range(500000):
             after = sum(p.get_num_ctx_switches())
             if after > before:
                 return
         self.fail("num ctx switches still the same after 50.000 iterations")
 
     def test_parent_ppid(self):
         this_parent = os.getpid()
         sproc = get_test_subprocess()
@@ -1423,17 +1490,17 @@ class TestCase(unittest.TestCase):
         from psutil._compat import defaultdict
         table = defaultdict(int)
         for p in psutil.process_iter():
             try:
                 table[p.ppid] += 1
             except psutil.Error:
                 pass
         # this is the one, now let's make sure there are no duplicates
-        pid = max(sorted(table, key=lambda x: table[x]))
+        pid = sorted(table.items(), key=lambda x: x[1])[-1][0]
         p = psutil.Process(pid)
         try:
             c = p.get_children(recursive=True)
         except psutil.AccessDenied:  # windows
             pass
         else:
             self.assertEqual(len(c), len(set(c)))
 
@@ -1447,18 +1514,17 @@ class TestCase(unittest.TestCase):
             time.sleep(0.01)
         self.assertEqual(str(p.status), "stopped")
         p.resume()
         assert p.status != psutil.STATUS_STOPPED, p.status
 
     def test_invalid_pid(self):
         self.assertRaises(TypeError, psutil.Process, "1")
         self.assertRaises(TypeError, psutil.Process, None)
-        # Refers to Issue #12
-        self.assertRaises(psutil.NoSuchProcess, psutil.Process, -1)
+        self.assertRaises(ValueError, psutil.Process, -1)
 
     def test_as_dict(self):
         sproc = get_test_subprocess()
         p = psutil.Process(sproc.pid)
         d = p.as_dict()
         try:
             import json
         except ImportError:
@@ -1564,16 +1630,31 @@ class TestCase(unittest.TestCase):
         elif WINDOWS:
             self.assertEqual(p.username, 'NT AUTHORITY\\SYSTEM')
         else:
             p.username
 
         self.assertIn(0, psutil.get_pid_list())
         self.assertTrue(psutil.pid_exists(0))
 
+    def test__all__(self):
+        for name in dir(psutil):
+            if name in ('callable', 'defaultdict', 'error', 'namedtuple'):
+                continue
+            if not name.startswith('_'):
+                try:
+                    __import__(name)
+                except ImportError:
+                    if name not in psutil.__all__:
+                        fun = getattr(psutil, name)
+                        if fun is None:
+                            continue
+                        if 'deprecated' not in fun.__doc__.lower():
+                            self.fail('%r not in psutil.__all__' % name)
+
     def test_Popen(self):
         # Popen class test
         # XXX this test causes a ResourceWarning on Python 3 because
         # psutil.__subproc instance doesn't get propertly freed.
         # Not sure what to do though.
         cmd = [PYTHON, "-c", "import time; time.sleep(3600);"]
         proc = psutil.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
         try:
@@ -1615,45 +1696,65 @@ class TestFetchAllProcesses(unittest.Tes
             if name.startswith("_"):
                 continue
             if name.startswith("set_"):
                 continue
             if name in excluded_names:
                 continue
             attrs.append(name)
 
-        for p in psutil.process_iter():
-            for name in attrs:
+        default = object()
+        failures = []
+        for name in attrs:
+            for p in psutil.process_iter():
+                ret = default
                 try:
                     try:
                         attr = getattr(p, name, None)
                         if attr is not None and callable(attr):
                             ret = attr()
                         else:
                             ret = attr
                         valid_procs += 1
                     except (psutil.NoSuchProcess, psutil.AccessDenied):
                         err = sys.exc_info()[1]
+                        if isinstance(err, psutil.NoSuchProcess):
+                            if psutil.pid_exists(p.pid):
+                                # XXX race condition; we probably need
+                                # to try figuring out the process
+                                # identity before failing
+                                self.fail("PID still exists but fun raised " \
+                                          "NoSuchProcess")
                         self.assertEqual(err.pid, p.pid)
                         if err.name:
                             # make sure exception's name attr is set
                             # with the actual process name
                             self.assertEqual(err.name, p.name)
                         self.assertTrue(str(err))
                         self.assertTrue(err.msg)
                     else:
                         if ret not in (0, 0.0, [], None, ''):
                             assert ret, ret
                         meth = getattr(self, name)
                         meth(ret)
                 except Exception:
                     err = sys.exc_info()[1]
-                    trace = traceback.format_exc()
-                    self.fail('%s\nproc=%s, method=%r, retvalue=%r'
-                              % (trace, p, name, ret))
+                    s = '\n' + '=' * 70 + '\n'
+                    s += "FAIL: test_%s (proc=%s" % (name, p)
+                    if ret != default:
+                        s += ", ret=%s)" % repr(ret)
+                    s += ')\n'
+                    s += '-' * 70
+                    s += "\n%s" % traceback.format_exc()
+                    s =  "\n".join((" " * 4) + i for i in s.splitlines())
+                    failures.append(s)
+                    break
+
+        if failures:
+            self.fail(''.join(failures))
 
         # we should always have a non-empty list, not including PID 0 etc.
         # special cases.
         self.assertTrue(valid_procs > 0)
 
     def cmdline(self, ret):
         pass
 
@@ -1663,29 +1764,30 @@ class TestFetchAllProcesses(unittest.Tes
         else:
             assert os.path.isabs(ret), ret
             # Note: os.stat() may return False even if the file is there
             # hence we skip the test, see:
             # http://stackoverflow.com/questions/3112546/os-path-exists-lies
             if POSIX:
                 assert os.path.isfile(ret), ret
                 if hasattr(os, 'access') and hasattr(os, "X_OK"):
+                    # XXX may fail on OSX
                     self.assertTrue(os.access(ret, os.X_OK))
 
     def ppid(self, ret):
         self.assertTrue(ret >= 0)
 
     def name(self, ret):
         self.assertTrue(isinstance(ret, str))
         self.assertTrue(ret)
 
     def create_time(self, ret):
         self.assertTrue(ret > 0)
         if not WINDOWS:
-            self.assertTrue(ret >= psutil.BOOT_TIME)
+            assert ret >= psutil.BOOT_TIME, (ret, psutil.BOOT_TIME)
         # make sure returned value can be pretty printed
         # with strftime
         time.strftime("%Y %m %d %H:%M:%S", time.localtime(ret))
 
     def uids(self, ret):
         for uid in ret:
             self.assertTrue(uid >= 0)
             self.assertIn(uid, self._uids)
@@ -1707,18 +1809,22 @@ class TestFetchAllProcesses(unittest.Tes
         self.assertTrue(str(ret) != '?')
 
     def get_io_counters(self, ret):
         for field in ret:
             if field != -1:
                 self.assertTrue(field >= 0)
 
     def get_ionice(self, ret):
-        self.assertTrue(ret.ioclass >= 0)
-        self.assertTrue(ret.value >= 0)
+        if LINUX:
+            self.assertTrue(ret.ioclass >= 0)
+            self.assertTrue(ret.value >= 0)
+        else:
+            self.assertTrue(ret >= 0)
+            self.assertIn(ret, (0, 1, 2))
 
     def get_num_threads(self, ret):
         self.assertTrue(ret >= 1)
 
     def get_threads(self, ret):
         for t in ret:
             self.assertTrue(t.id >= 0)
             self.assertTrue(t.user_time >= 0)
@@ -1902,16 +2008,17 @@ if hasattr(os, 'getuid'):
 
 
 def cleanup():
     reap_children(search_all=True)
     DEVNULL.close()
     safe_remove(TESTFN)
 
 atexit.register(cleanup)
+safe_remove(TESTFN)
 
 def test_main():
     tests = []
     test_suite = unittest.TestSuite()
     tests.append(TestCase)
     tests.append(TestFetchAllProcesses)
 
     if POSIX: