~ubuntu-branches/ubuntu/precise/terminator/precise

« back to all changes in this revision

Viewing changes to terminatorlib/freebsd.py

  • Committer: Bazaar Package Importer
  • Author(s): Nicolas Valcárcel
  • Date: 2008-07-08 07:24:49 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20080708072449-n7ey6xc46bo9lo2x
Tags: 0.9-1
New upstream release. (Closes: #489858)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#!/usr/local/bin/python
 
2
# ------------------------------------------------------------------
 
3
# Copyright (c) 2008, Thomas Hurst <tom@hur.st>
 
4
#
 
5
# Use of this file is unrestricted provided this notice is retained.
 
6
# If you use it, it'd be nice if you dropped me a note.  Also beer.
 
7
# ------------------------------------------------------------------
 
8
#
 
9
# freebsd.get_process_cwd(pid):
 
10
#  Use sysctl() to retrieve the cwd of an arbitrary process on FreeBSD
 
11
#  using kern.proc.filedesc, as used by procstat(1).
 
12
#  Tested on FreeBSD 7-STABLE/amd64 from April 11 2008.
 
13
 
 
14
from ctypes import *
 
15
 
 
16
# This is padded awkwardly, see /usr/include/sys/socket.h
 
17
class sockaddr_storage(Structure):
 
18
  _fields_ = [
 
19
    ('ss_len',     c_char),
 
20
    ('ss_family',  c_char),       # /usr/include/sys/_types.h; _uint8_t
 
21
    ('__ss_pad1',  c_char * 6),   # (sizeof(int64) - sizeof(char) - sizeof(ss_family_t))
 
22
    ('__ss_align', c_longlong),
 
23
    ('__ss_pad2',  c_char * 112), # (128(maxsize) - sizeof(char) - sizeof(ss_family_t) -
 
24
                                  # sizeof(ss_pad1) - sizeof(int64))
 
25
  ]
 
26
 
 
27
# struct kinfo_file, defined in /usr/include/sys/user.h
 
28
class kinfo_file(Structure):
 
29
  _fields_ = [
 
30
      ('kf_structsize',    c_int),
 
31
      ('kf_type',          c_int),
 
32
      ('kf_fd',            c_int),
 
33
      ('kf_ref_count',     c_int),
 
34
      ('kf_flags',         c_int),
 
35
      ('kf_offset',        c_long), # this is a off_t, a pointer
 
36
      ('kf_vnode_type',    c_int),
 
37
      ('kf_sock_domain',   c_int),
 
38
      ('kf_sock_type',     c_int),
 
39
      ('kf_sock_protocol', c_int),
 
40
      ('kf_path',          c_char * 1024), # PATH_MAX
 
41
      ('kf_sa_local',      sockaddr_storage),
 
42
      ('kf_sa_peer',       sockaddr_storage),
 
43
  ]
 
44
 
 
45
libc = CDLL('libc.so')
 
46
 
 
47
len = c_uint(sizeof(c_uint))
 
48
ver = c_uint(0)
 
49
 
 
50
if (libc.sysctlbyname('kern.osreldate', byref(ver), byref(len), None, 0) < 0):
 
51
  raise OSError, "sysctlbyname returned < 0"
 
52
 
 
53
# kern.proc.filedesc added for procstat(1) after these __FreeBSD_versions
 
54
if ver.value < 700104 and ver.value < 800019:
 
55
  raise NotImplementedError, "cwd detection requires a recent 7.0-STABLE or 8-CURRENT"
 
56
 
 
57
def get_process_cwd(pid):
 
58
  # /usr/include/sys/sysctl.h
 
59
  # CTL_KERN, KERN_PROC, KERN_PROC_FILEDESC
 
60
  oid = (c_uint * 4)(1, 14, 14, pid)
 
61
 
 
62
  if libc.sysctl(oid, 4, None, byref(len), None, 0) < 0:
 
63
    return None
 
64
 
 
65
  buf = c_char_p(" " * len.value)
 
66
  if libc.sysctl(oid, 4, buf, byref(len), None, 0) < 0:
 
67
    return None
 
68
 
 
69
  kifs = cast(buf, POINTER(kinfo_file))
 
70
  for i in xrange(0, len.value / sizeof(kinfo_file)):
 
71
    kif = kifs[i]
 
72
    if kif.kf_fd == -1: # KF_FD_TYPE_CWD
 
73
      return kif.kf_path
 
74
 
 
75
if __name__ == '__main__':
 
76
  import os, sys
 
77
  print " => %d cwd = %s" % (os.getpid(), get_process_cwd(os.getpid()))
 
78
  for pid in sys.argv:
 
79
    try:
 
80
      pid = int(pid)
 
81
    except:
 
82
      pass
 
83
    else:
 
84
      print " => %d cwd = %s" % (pid, get_process_cwd(pid))
 
85