diff --git a/terminatorlib/freebsd.py b/terminatorlib/freebsd.py index 6f85d902..0b38e7ab 100644 --- a/terminatorlib/freebsd.py +++ b/terminatorlib/freebsd.py @@ -1,20 +1,21 @@ #!/usr/local/bin/python -# ------------------------------------------------------------------ +# # Copyright (c) 2008, Thomas Hurst # # Use of this file is unrestricted provided this notice is retained. # If you use it, it'd be nice if you dropped me a note. Also beer. -# ------------------------------------------------------------------ -# -# freebsd.get_process_cwd(pid): -# Use sysctl() to retrieve the cwd of an arbitrary process on FreeBSD -# using kern.proc.filedesc, as used by procstat(1). -# Tested on FreeBSD 7-STABLE/amd64 from April 11 2008. + +""" + freebsd.get_process_cwd(pid): + Use sysctl() to retrieve the cwd of an arbitrary process on FreeBSD + using kern.proc.filedesc, as used by procstat(1). + Tested on FreeBSD 7-STABLE/amd64 from April 11 2008. +""" from ctypes import * -# This is padded awkwardly, see /usr/include/sys/socket.h class sockaddr_storage(Structure): + """struct sockaddr_storage, defined in /usr/include/sys/socket.h""" _fields_ = [ ('ss_len', c_char), ('ss_family', c_char), # /usr/include/sys/_types.h; _uint8_t @@ -24,15 +25,15 @@ class sockaddr_storage(Structure): # sizeof(ss_pad1) - sizeof(int64)) ] -# struct kinfo_file, defined in /usr/include/sys/user.h class kinfo_file(Structure): + """struct kinfo_file, defined in /usr/include/sys/user.h """ _fields_ = [ ('kf_structsize', c_int), ('kf_type', c_int), ('kf_fd', c_int), ('kf_ref_count', c_int), ('kf_flags', c_int), - ('kf_offset', c_long), # this is a off_t, a pointer + ('kf_offset', c_size_t), # this is a off_t, a pointer ('kf_vnode_type', c_int), ('kf_sock_domain', c_int), ('kf_sock_type', c_int), @@ -44,34 +45,38 @@ class kinfo_file(Structure): libc = CDLL('libc.so') -len = c_uint(sizeof(c_uint)) +uintlen = c_size_t(sizeof(c_uint)) ver = c_uint(0) -if (libc.sysctlbyname('kern.osreldate', byref(ver), byref(len), None, 0) < 0): +if (libc.sysctlbyname('kern.osreldate', byref(ver), byref(uintlen), None, 0) < 0): raise OSError, "sysctlbyname returned < 0" # kern.proc.filedesc added for procstat(1) after these __FreeBSD_versions if ver.value < 700104 and ver.value < 800019: raise NotImplementedError, "cwd detection requires a recent 7.0-STABLE or 8-CURRENT" + def get_process_cwd(pid): + """Return string containing the current working directory of the given pid, + or None on failure.""" # /usr/include/sys/sysctl.h # CTL_KERN, KERN_PROC, KERN_PROC_FILEDESC oid = (c_uint * 4)(1, 14, 14, pid) - if libc.sysctl(oid, 4, None, byref(len), None, 0) < 0: + if libc.sysctl(oid, 4, None, byref(uintlen), None, 0) < 0: return None - buf = c_char_p(" " * len.value) - if libc.sysctl(oid, 4, buf, byref(len), None, 0) < 0: + buf = c_char_p(" " * uintlen.value) + if libc.sysctl(oid, 4, buf, byref(uintlen), None, 0) < 0: return None kifs = cast(buf, POINTER(kinfo_file)) - for i in xrange(0, len.value / sizeof(kinfo_file)): + for i in xrange(0, uintlen.value / sizeof(kinfo_file)): kif = kifs[i] if kif.kf_fd == -1: # KF_FD_TYPE_CWD return kif.kf_path + if __name__ == '__main__': import os, sys print " => %d cwd = %s" % (os.getpid(), get_process_cwd(os.getpid()))