Monday, October 29, 2012

Procenv and the Process Environment

Quiz

How many attributes of a processes "environment" can you think of besides its environment variables? I'm using the term "environment" in a very loose sense here to mean "any system or process level attribute that can be queried via system calls or library calls (or "/proc-picking") that affects a running process". I'm also including details of the process itself and details of the program that came to be a running process.

We're not talking about installed packages or application configuration files in /etc here, but purely low-level program, process and system meta-data.


I've got over 20 items in my list excluding environment variables.

Whilst you're pondering on that...

Compare and Contrast


If you've been involved with computers for any appreciable length of time, chances are you have come across the scenario where some program fails to run in a particular environment, but works "perfectly" in another (generally a developers cosy interactive shell environment).

Ignoring the fact that the development environment should always mirror the production environment as closely as possible, this problem tends to crop up in certain common scenarios. The two most common (from my observations) being:

  • system "services"

    Such programs (often daemons of course) run -- and indeed should run -- in an exceedingly sparse environment: they get given just enough of an environment to do their job safely and efficiently.

    And yes, I get asked quite a lot why some new Upstart job won't start, but runs in a desktop session environment "perfectly" :-)
  • build systems

    Sometimes, the environment of such systems is quite different to what the developer expected. Maybe the build system is a virtualised or chrooted system, or it might be running on a host which has a different architecture to the expected one.

Environment

Back to the poser. How many have you got? Here's my list of "groups":

  • pid details.
  • session details.
  • credentials information.
  • password database details for user running the program.
  • groups user running application belongs to.
  • SELinux details.
  • CPU details.
  • scheduler details.
  • capabilities.
  • oom details.
  • cgroups.
  • stat details for the binary that is being run.
  • details of libraries that said binary has loaded.
  • compiler details for the binary being run.
  • uname details.
  • open file descriptors.
  • process limits.
  • system limits.
  • configuration-dependent limits.
  • timezone details.
  • clock details.
  • time details.
  • terminal details.
  • signal dispositions.
  • mount details.
  • networking details.
  • sizeof details.
  • ranges of standard system data types.

Procenv

The answer to the two posers above is procenv. This is a simple utility, licensed under the GPL, that essentially dumps every conceivable aspect of a processes environment (*) that it can (without needing super-user privs). It unashamedly emulates a number of existing system utilities as it is attempting to be all-encompassing: I wrote it with the aim of being able to dump "everything" that a process may care about by simply running a single program (by default). Also, the line of demarcation between "process", "program" and  "system" is slightly blurry in some aspects (for example sysconf(3) variables could arguably be considered system attributes, but procenv shows these too since they are obviously meant to be querable by applications.


(*) - well, it doesn't currently query the network environment and I may have overlooked something, so patches are of course welcome!


Rationale

"But wait!" I hear you cry, "this procenv is redundant: I can get all the information I need from /proc!"

Well, that's half correct - you can get a lot of information out of /proc, but there are some caveats with that approach:

  • /proc might not be mounted.
  • /proc might not be readable (it could legitimately have permissions 0000).
  • the format and location of files in /proc may change in the future.
  • the format of certain files in /proc is sometimes extremely terse and cryptic.
As such, where possible, procenv uses system and library calls rather than grubbing around in /proc for the answers it needs since system calls and library calls don't generally change :-)


"Well, I could just write a shell script to massage the data in /proc into a consistent format, or just make use of other system utilities to produce an aggregated report" you say. Yes, you could do that, but procenv is striving to be cross-platform and additional to the /proc concerns, writing such a tool in shell comes with a bag of gotchas if it's going to work on anything but GNU Linux:

  • which shell are you going to support?
  • which version of standard utilities like (awk (or gawk or even nawk) are you going to support?
If you did write such a shell script, it could end up being somewhat of a monster if it was to work on all platforms and massage utility output to be consistent across these platforms.

Possible Uses

There are quite a few I suspect. Here are a few thoughts on some of the environments it could be run in to give a better understanding of what that enviroment is:

  • See what nohup(1) does to your process:

    $ nohup procenv
  • See what shell back-grounding using does to your process:

    $ procenv &
  • Exploring the environment available to you when you login to a system with restricted access (what has been restricted?)
  • Seeing the environment the kernel gives to the initramfs.
    Boot with options including something like:

    rdinit=/usr/bin/procenv PROCENV_FILE=/dev/ttyS0 PROCENV_EXEC="/init"
  • Exploring the environment the initramfs gives to PID 1 aka "init"(aka Upstart for the majority of folks I hope ;-)

    init=/usr/bin/procenv PROCENV_FILE=/dev/ttyS0 PROCENV_EXEC="/sbin/init"
  • Investigating chroots
  • Jails (yes, it runs on FreeBSD and Debian GNU/kFreeBSD too :-)
  • Explore a container environment (LXC, OpenVZ, VServer, etc).
  • Explore an OpenStack or EC2 instance.
  • Understanding the environment of an Upstart job:

    $ cat << EOT
    exec /usr/bin/procenv
    EOT | sudo tee /etc/init/procenv.conf




  • Those alluded-to build environments such as those provided by pbuilder(8) and sbuild(1).


  • Summary


    So, if you want to know if you are a Process Leader or a Session Leader (or both!), or you want to know what your stderr/stdout/stderr are connected to, give procenv a try.

    Example Output

    Here's some sample output from procenv shown running in an LXC container running Ubuntu Quantal:

    $ procenv --misc
    umask: 0002
    current directory (cwd): '/home/james'
    root: '/'
    chroot: yes
    selinux context: lxc-container-default (enforce)
    container: lxc
    cpu: 4 of 4
    scheduler: SCHED_OTHER
    scheduler priority: process=0, process group=0, user=-11
    memory page size: 4096 bytes
    

    Here's an example showing the full details (running procenv with no options):
     
    procenv:
      version: procenv 0.3
      platform: Linux (Intel)
      kernel bits: 32
    capabilities(linux):
      CAP_CHOWN=yes
      CAP_DAC_OVERRIDE=yes
      CAP_DAC_READ_SEARCH=yes
      CAP_FOWNER=yes
      CAP_FSETID=yes
      CAP_KILL=yes
      CAP_SETGID=yes
      CAP_SETUID=yes
      CAP_SETPCAP=yes
      CAP_LINUX_IMMUTABLE=yes
      CAP_NET_BIND_SERVICE=yes
      CAP_NET_BROADCAST=yes
      CAP_NET_ADMIN=yes
      CAP_NET_RAW=yes
      CAP_IPC_LOCK=yes
      CAP_IPC_OWNER=yes
      CAP_SYS_MODULE=no
      CAP_SYS_RAWIO=yes
      CAP_SYS_CHROOT=yes
      CAP_SYS_PTRACE=yes
      CAP_SYS_PACCT=yes
      CAP_SYS_ADMIN=yes
      CAP_SYS_BOOT=yes
      CAP_SYS_NICE=yes
      CAP_SYS_RESOURCE=yes
      CAP_SYS_TIME=yes
      CAP_SYS_TTY_CONFIG=yes
      CAP_MKNOD=yes
      CAP_LEASE=yes
      CAP_AUDIT_WRITE=yes
      CAP_AUDIT_CONTROL=yes
      CAP_SETFCAP=yes
      CAP_MAC_OVERRIDE=yes
      CAP_MAC_ADMIN=no
      CAP_SYSLOG=yes
      CAP_WAKE_ALARM=yes
    cgroup(linux):
      8:perf_event:/lxc/quantal
      7:blkio:/lxc/quantal
      6:freezer:/lxc/quantal
      5:devices:/lxc/quantal
      4:memory:/lxc/quantal
      3:cpuacct:/lxc/quantal
      2:cpu:/lxc/quantal
      1:cpuset:/lxc/quantal
    clocks:
      CLOCK_REALTIME: resolution: 0.000000001s
      CLOCK_MONOTONIC: resolution: 0.000000001s
      CLOCK_MONOTONIC_RAW: resolution: 0.000000001s
      CLOCK_PROCESS_CPUTIME_ID: resolution: 0.000000001s
      CLOCK_THREAD_CPUTIME_ID: resolution: 0.000000001s
    compiler:
      name: GCC
      version: 4.7.2
      compile date: Oct 27 2012
      compile time: 14:57:03
      __STRICT_ANSI__: not defined
      _POSIX_C_SOURCE: 200809
      _POSIX_SOURCE: defined
      _XOPEN_SOURCE: 700
      _XOPEN_SOURCE_EXTENDED: defined
      _ISOC95_SOURCE: defined
      _ISOC99_SOURCE: defined
      _ISOC11_SOURCE: not defined
      _LARGEFILE64_SOURCE: defined
      _FILE_OFFSET_BITS: not defined
      _BSD_SOURCE: defined
      _SVID_SOURCE: defined
      _ATFILE_SOURCE: defined
      _GNU_SOURCE: defined
      _REENTRANT: not defined
      _THREAD_SAFE: not defined
      _FORTIFY_SOURCE: defined
    confstr:
      _CS_GNU_LIBC_VERSION: 'glibc 2.15'
      _CS_GNU_LIBPTHREAD_VERSION: 'NPTL 2.15'
      _CS_PATH: '/bin:/usr/bin'
    environment:
      TERM=linux
      HOME=/home/james
      SHELL=/bin/zsh
      USER=james
      LOGNAME=james
      PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games
      MAIL=/var/mail/james
      HUSHLOGIN=FALSE
      SHLVL=1
      PWD=/home/james
      OLDPWD=/home/james
      LS_COLORS=rs=0:di=01;34:ln=01;36:mh=00:pi=40;33:so=01;35:do=01;35:bd=40;33;01:cd=40;33;01:or=40;31;01:su=37;41:sg=30;43:ca=30;41:tw=30;42:ow=34;42:st=37;44:ex=01;32:*.tar=01;31:*.tgz=01;31:*.arj=01;31:*.taz=01;31:*.lzh=01;31:*.lzma=01;31:*.tlz=01;31:*.txz=01;31:*.zip=01;31:*.z=01;31:*.Z=01;31:*.dz=01;31:*.gz=01;31:*.lz=01;31:*.xz=01;31:*.bz2=01;31:*.bz=01;31:*.tbz=01;31:*.tbz2=01;31:*.tz=01;31:*.deb=01;31:*.rpm=01;31:*.jar=01;31:*.war=01;31:*.ear=01;31:*.sar=01;31:*.rar=01;31:*.ace=01;31:*.zoo=01;31:*.cpio=01;31:*.7z=01;31:*.rz=01;31:*.jpg=01;35:*.jpeg=01;35:*.gif=01;35:*.bmp=01;35:*.pbm=01;35:*.pgm=01;35:*.ppm=01;35:*.tga=01;35:*.xbm=01;35:*.xpm=01;35:*.tif=01;35:*.tiff=01;35:*.png=01;35:*.svg=01;35:*.svgz=01;35:*.mng=01;35:*.pcx=01;35:*.mov=01;35:*.mpg=01;35:*.mpeg=01;35:*.m2v=01;35:*.mkv=01;35:*.webm=01;35:*.ogm=01;35:*.mp4=01;35:*.m4v=01;35:*.mp4v=01;35:*.vob=01;35:*.qt=01;35:*.nuv=01;35:*.wmv=01;35:*.asf=01;35:*.rm=01;35:*.rmvb=01;35:*.flc=01;35:*.avi=01;35:*.fli=01;35:*.flv=01;35:*.gl=01;35:*.dl=01;35:*.xcf=01;35:*.xwd=01;35:*.yuv=01;35:*.cgm=01;35:*.emf=01;35:*.axv=01;35:*.anx=01;35:*.ogv=01;35:*.ogx=01;35:*.aac=00;36:*.au=00;36:*.flac=00;36:*.mid=00;36:*.midi=00;36:*.mka=00;36:*.mp3=00;36:*.mpc=00;36:*.ogg=00;36:*.ra=00;36:*.wav=00;36:*.axa=00;36:*.oga=00;36:*.spx=00;36:*.xspf=00;36:
      _=/home/james/./procenv
    fds:
      fd 0: terminal=yes ('/dev/console')
      fd 1: terminal=yes ('/dev/console')
      fd 2: terminal=yes ('/dev/console')
      fd 3: terminal=yes ('/dev/tty')
      fd 4: terminal=no
      fd 17: terminal=no
    fds (linux/proc):
      '/proc/self/fd/0' -> '/dev/console' (terminal=yes, valid=yes)
      '/proc/self/fd/1' -> '/dev/console' (terminal=yes, valid=yes)
      '/proc/self/fd/2' -> '/dev/console' (terminal=yes, valid=yes)
      '/proc/self/fd/3' -> '/dev/tty' (terminal=yes, valid=yes)
      '/proc/self/fd/4' -> '/tmp/procenv-lxc.log' (terminal=no, valid=yes)
    libs:
      /lib/i386-linux-gnu/librt.so.1
      /lib/i386-linux-gnu/libselinux.so.1
      /lib/i386-linux-gnu/libc.so.6
      /lib/i386-linux-gnu/libpthread.so.0
      /lib/i386-linux-gnu/libdl.so.2
      /lib/ld-linux.so.2
      /lib/i386-linux-gnu/libnss_compat.so.2
      /lib/i386-linux-gnu/libnsl.so.1
      /lib/i386-linux-gnu/libnss_nis.so.2
      /lib/i386-linux-gnu/libnss_files.so.2
    limits:
      RLIMIT_AS (soft=4294967295 (max), hard=4294967295 (max))
      RLIMIT_CORE (soft=4294967295 (max), hard=4294967295 (max))
      RLIMIT_CPU (soft=4294967295 (max), hard=4294967295 (max))
      RLIMIT_DATA (soft=4294967295 (max), hard=4294967295 (max))
      RLIMIT_FSIZE (soft=4294967295 (max), hard=4294967295 (max))
      RLIMIT_LOCKS (soft=4294967295 (max), hard=4294967295 (max))
      RLIMIT_MEMLOCK (soft=65536, hard=65536)
      RLIMIT_MSGQUEUE (soft=819200, hard=819200)
      RLIMIT_NICE (soft=0, hard=0)
      RLIMIT_NOFILE (soft=10240, hard=10240)
      RLIMIT_NPROC (soft=63489, hard=63489)
      RLIMIT_RSS (soft=4294967295 (max), hard=4294967295 (max))
      RLIMIT_RTPRIO (soft=0, hard=0)
      RLIMIT_SIGPENDING (soft=63489, hard=63489)
      RLIMIT_STACK (soft=8388608, hard=4294967295 (max))
    misc:
      umask: 0002
      current directory (cwd): '/home/james'
      root: '/'
      chroot: yes
      selinux context: lxc-container-default (enforce)
      container: lxc
      cpu: 4 of 4
      scheduler: SCHED_OTHER
      scheduler priority: process=0, process group=0, user=-11
      memory page size: 4096 bytes
    mounts:
      fsname='rootfs', dir='/', type='rootfs', opts='rw', dev=(major:8, minor:1)
        pathconf for path '/':
          _PC_LINK_MAX=65000
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='/dev/disk/by-uuid/7ad192e9-7b26-49d1-8e1c-fefc7dc495cb', dir='/', type='ext4', opts='rw,relatime,errors=remount-ro,data=ordered', dev=(major:8, minor:1)
        pathconf for path '/':
          _PC_LINK_MAX=65000
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='proc', dir='/proc', type='proc', opts='rw,nosuid,nodev,noexec,relatime', dev=(major:0, minor:36)
        pathconf for path '/proc':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='sysfs', dir='/sys', type='sysfs', opts='rw,relatime', dev=(major:0, minor:37)
        pathconf for path '/sys':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='devpts', dir='/dev/console', type='devpts', opts='rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000', dev=(major:0, minor:11)
        pathconf for path '/dev/console':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='devpts', dir='/dev/tty1', type='devpts', opts='rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000', dev=(major:0, minor:11)
        pathconf for path '/dev/tty1':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='devpts', dir='/dev/tty2', type='devpts', opts='rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000', dev=(major:0, minor:11)
        pathconf for path '/dev/tty2':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='devpts', dir='/dev/tty3', type='devpts', opts='rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000', dev=(major:0, minor:11)
        pathconf for path '/dev/tty3':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='devpts', dir='/dev/tty4', type='devpts', opts='rw,nosuid,noexec,relatime,gid=5,mode=620,ptmxmode=000', dev=(major:0, minor:11)
        pathconf for path '/dev/tty4':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='devpts', dir='/dev/pts', type='devpts', opts='rw,relatime,mode=600,ptmxmode=666', dev=(major:0, minor:38)
        pathconf for path '/dev/pts':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='devpts', dir='/dev/ptmx', type='devpts', opts='rw,relatime,mode=600,ptmxmode=666', dev=(major:0, minor:38)
        pathconf for path '/dev/ptmx':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='none', dir='/proc/sys/fs/binfmt_misc', type='binfmt_misc', opts='rw,nosuid,nodev,noexec,relatime', dev=(major:0, minor:29)
        pathconf for path '/proc/sys/fs/binfmt_misc':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='none', dir='/sys/fs/fuse/connections', type='fusectl', opts='rw,relatime', dev=(major:0, minor:16)
        pathconf for path '/sys/fs/fuse/connections':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='none', dir='/sys/kernel/debug', type='debugfs', opts='rw,relatime', dev=(major:0, minor:6)
        pathconf for path '/sys/kernel/debug':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='none', dir='/sys/kernel/security', type='securityfs', opts='rw,relatime', dev=(major:0, minor:10)
        pathconf for path '/sys/kernel/security':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='none', dir='/run', type='tmpfs', opts='rw,nosuid,noexec,relatime,size=814240k,mode=755', dev=(major:0, minor:39)
        pathconf for path '/run':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='none', dir='/run/lock', type='tmpfs', opts='rw,nosuid,nodev,noexec,relatime,size=5120k', dev=(major:0, minor:40)
        pathconf for path '/run/lock':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='none', dir='/run/shm', type='tmpfs', opts='rw,nosuid,nodev,relatime', dev=(major:0, minor:41)
        pathconf for path '/run/shm':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
      fsname='none', dir='/run/user', type='tmpfs', opts='rw,nosuid,nodev,noexec,relatime,size=102400k,mode=755', dev=(major:0, minor:42)
        pathconf for path '/run/user':
          _PC_LINK_MAX=127
          _PC_MAX_CANON=255
          _PC_MAX_INPUT=255
          _PC_NAME_MAX=255
          _PC_PATH_MAX=4096
          _PC_PIPE_BUF=4096
          _PC_CHOWN_RESTRICTED=1
          _PC_NO_TRUNC=1
          _PC_VDISABLE=0
    oom(linux):
      oom_score=0
      oom_adj=0
      oom_score_adj=0
    process:
      process id (pid): 344
      parent process id (ppid): 307
      session id (sid): 290 (leader=no)
      name: 'procenv'
      ancestry: 344 ('procenv'), 307 ('zsh'), 290 ('login'), 1 ('init')
      process group id: 344 (leader=yes)
      foreground process group: 344
      terminal: '/dev/tty'
      has controlling terminal: yes
      on console: no
      real user id (uid): 1000 ('james')
      effective user id (euid): 1000 ('james')
      saved set-user-id (suid): 1000 ('james')
      real group id (gid): 1000 ('james')
      effective group id (egid): 1000 ('james')
      saved set-group-id (sgid): 1000 ('james')
      login name: 'james'
      passwd: name='james', gecos='', dir='/home/james', shell='/bin/zsh'
      groups: 'james' (1000)
    ranges:
      char:
        unsigned: 0 to 255 (0.000000e+00 to 2.550000e+02, 0x00 to 0xff)
        signed: -128 to 127
      short int:
        unsigned: 0 to 65535 (0.000000e+00 to 6.553500e+04, 0x0000 to 0xffff)
        signed: -32768 to 32767
      int:
        unsigned: 0 to 4294967295 (0.000000e+00 to 4.294967e+09, 0x00000000 to 0xffffffff)
        signed: -2147483648 to 2147483647
      long int:
        unsigned: 0 to 4294967295 (0.000000e+00 to 4.294967e+09, 0x00000000 to 0xffffffff)
        signed: -2147483648 to 2147483647
      long long int:
        unsigned: 0 to 18446744073709551615 (0.000000e+00 to 1.844674e+19, 0x0000000000000000 to 0xffffffffffffffff)
        signed: -9223372036854775808 to 9223372036854775807
      float:
        signed: 1.175494e-38 to 3.402823e+38
      double:
        signed: 2.225074e-308 to 1.797693e+308
      long double:
        signed: 3.362103e-4932 to 1.189731e+4932
    signals:
      SIGHUP ('Hangup', 1): blocked=no, ignored=no
      SIGINT ('Interrupt', 2): blocked=no, ignored=no
      SIGQUIT ('Quit', 3): blocked=no, ignored=no
      SIGILL ('Illegal instruction', 4): blocked=no, ignored=no
      SIGTRAP ('Trace/breakpoint trap', 5): blocked=no, ignored=no
      SIGABRT ('Aborted', 6): blocked=no, ignored=no
      SIGBUS ('Bus error', 7): blocked=no, ignored=no
      SIGFPE ('Floating point exception', 8): blocked=no, ignored=no
      SIGKILL ('Killed', 9): blocked=no, ignored=no
      SIGUSR1 ('User defined signal 1', 10): blocked=no, ignored=no
      SIGSEGV ('Segmentation fault', 11): blocked=no, ignored=no
      SIGUSR2 ('User defined signal 2', 12): blocked=no, ignored=no
      SIGPIPE ('Broken pipe', 13): blocked=no, ignored=no
      SIGALRM ('Alarm clock', 14): blocked=no, ignored=no
      SIGTERM ('Terminated', 15): blocked=no, ignored=no
      SIGSTKFLT ('Stack fault', 16): blocked=no, ignored=no
      SIGCHLD|SIGCLD ('Child exited', 17): blocked=no, ignored=no
      SIGCONT ('Continued', 18): blocked=no, ignored=no
      SIGSTOP ('Stopped (signal)', 19): blocked=no, ignored=no
      SIGTSTP ('Stopped', 20): blocked=no, ignored=no
      SIGTTIN ('Stopped (tty input)', 21): blocked=no, ignored=no
      SIGTTOU ('Stopped (tty output)', 22): blocked=no, ignored=no
      SIGURG ('Urgent I/O condition', 23): blocked=no, ignored=no
      SIGXCPU ('CPU time limit exceeded', 24): blocked=no, ignored=no
      SIGXFSZ ('File size limit exceeded', 25): blocked=no, ignored=no
      SIGVTALRM ('Virtual timer expired', 26): blocked=no, ignored=no
      SIGPROF ('Profiling timer expired', 27): blocked=no, ignored=no
      SIGWINCH ('Window changed', 28): blocked=no, ignored=no
      SIGIO ('I/O possible', 29): blocked=no, ignored=no
      SIGPWR ('Power failure', 30): blocked=no, ignored=no
      SIGSYS ('Bad system call', 31): blocked=no, ignored=no
    sizeof:
      bits/byte (CHAR_BIT): 8
      sizeof (char): 1 byte
      sizeof (short int): 2 bytes
      sizeof (int): 4 bytes
      sizeof (long int): 4 bytes
      sizeof (long long int): 8 bytes
      sizeof (float): 4 bytes
      sizeof (double): 8 bytes
      sizeof (long double): 12 bytes
      sizeof (size_t): 4 bytes
      sizeof (ssize_t): 4 bytes
      sizeof (ptrdiff_t): 4 bytes
      sizeof (void *): 4 bytes
      sizeof (wchar_t): 4 bytes
      sizeof (intmax_t): 8 bytes
      sizeof (intptr_t): 4 bytes
      sizeof (uintptr_t): 4 bytes
      sizeof (time_t): 4 bytes
      sizeof (clock_t): 4 bytes
      sizeof (sig_atomic_t): 4 bytes
      sizeof (off_t): 4 bytes
      sizeof (fpos_t): 12 bytes
      sizeof (mode_t): 4 bytes
      sizeof (pid_t): 4 bytes
      sizeof (uid_t): 4 bytes
      sizeof (gid_t): 4 bytes
      sizeof (wint_t): 4 bytes
      sizeof (div_t): 8 bytes
      sizeof (ldiv_t): 8 bytes
      sizeof (lldiv_t): 16 bytes
      sizeof (mbstate_t): 8 bytes
    stat:
      argv[0]: './procenv'
      real path: '/home/james/procenv'
      dev: major=8, minor=1
      inode: 10223742
      mode: 0775 (-rwxrwxr-x)
      hard links: 1
      user id (uid): 1000 ('james')
      group id (gid): 1000 ('james')
      size: 161516 bytes (320 512-byte blocks)
      atime: 1351542553 (Mon Oct 29 20:29:13 2012)
      mtime: 1351542549 (Mon Oct 29 20:29:09 2012)
      ctime: 1351542549 (Mon Oct 29 20:29:09 2012)
    sysconf:
      ARG_MAX(_SC_ARG_MAX)=2097152
      BC_BASE_MAX(_SC_BC_BASE_MAX)=99
      BC_DIM_MAX(_SC_BC_DIM_MAX)=2048
      BC_SCALE_MAX(_SC_BC_SCALE_MAX)=99
      BC_STRING_MAX(_SC_BC_STRING_MAX)=1000
      CHILD_MAX(_SC_CHILD_MAX)=63489
      _SC_CLK_TCK=100
      COLL_WEIGHTS_MAX(_SC_COLL_WEIGHTS_MAX)=255
      EXPR_NEST_MAX(_SC_EXPR_NEST_MAX)=32
      HOST_NAME_MAX(_SC_HOST_NAME_MAX)=64
      LINE_MAX(_SC_LINE_MAX)=2048
      LOGIN_NAME_MAX(_SC_LOGIN_NAME_MAX)=256
      OPEN_MAX(_SC_OPEN_MAX)=10240
      PAGESIZE(_SC_PAGESIZE)=4096
      RE_DUP_MAX(_SC_RE_DUP_MAX)=32767
      STREAM_MAX(_SC_STREAM_MAX)=16
      SYMLOOP_MAX(_SC_SYMLOOP_MAX)=-1
      TTY_NAME_MAX(_SC_TTY_NAME_MAX)=32
      TZNAME_MAX(_SC_TZNAME_MAX)=6
      _POSIX_VERSION(_SC_VERSION)=200809
      BC_BASE_MAX(_SC_BC_BASE_MAX)=99
      BC_DIM_MAX(_SC_BC_DIM_MAX)=2048
      BC_SCALE_MAX(_SC_BC_SCALE_MAX)=99
      BC_STRING_MAX(_SC_BC_STRING_MAX)=1000
      COLL_WEIGHTS_MAX(_SC_COLL_WEIGHTS_MAX)=255
      EXPR_NEST_MAX(_SC_EXPR_NEST_MAX)=32
      LINE_MAX(_SC_LINE_MAX)=2048
      RE_DUP_MAX(_SC_RE_DUP_MAX)=32767
      POSIX2_VERSION(_SC_2_VERSION)=200809
      POSIX2_C_DEV(_SC_2_C_DEV)=200809
      POSIX2_FORT_DEV(_SC_2_FORT_DEV)=-1
      POSIX2_FORT_RUN(_SC_2_FORT_RUN)=-1
      _POSIX2_LOCALEDEF(_SC_2_LOCALEDEF)=200809
      POSIX2_SW_DEV(_SC_2_SW_DEV)=200809
      _SC_PHYS_PAGES=2035593
      _SC_AVPHYS_PAGES=1343166
      _SC_NPROCESSORS_CONF=4
      _SC_NPROCESSORS_ONLN=4
      _POSIX_ADVISORY_INFO(_SC_ADVISORY_INFO)=200809
      _POSIX_ASYNCHRONOUS_IO(_SC_ASYNCHRONOUS_IO)=200809
      _POSIX_BARRIERS(_SC_BARRIERS)=200809
      _POSIX_CHOWN_RESTRICTED=2097152
      _POSIX_CLOCK_SELECTION(_SC_CLOCK_SELECTION)=200809
      _POSIX_CPUTIME(_SC_CPUTIME)=200809
      _POSIX_FILE_LOCKING(_SC_FILE_LOCKING)=-1
      _POSIX_FSYNC(_SC_FSYNC)=200809
      _POSIX_JOB_CONTROL(_SC_JOB_CONTROL)=1
      _POSIX_MAPPED_FILES(_SC_MAPPED_FILES)=200809
      _POSIX_MEMLOCK(_SC_MEMLOCK)=200809
      _POSIX_MEMLOCK_RANGE(_SC_MEMLOCK_RANGE)=200809
      _POSIX_MEMORY_PROTECTION(_SC_MEMORY_PROTECTION)=200809
      _POSIX_MESSAGE_PASSING(_SC_MESSAGE_PASSING)=200809
      _POSIX_MONOTONIC_CLOCK(_SC_MONOTONIC_CLOCK)=200809
      _POSIX_MULTI_PROCESS(_SC_MULTI_PROCESS)=-1
      _POSIX_PRIORITIZED_IO(_SC_PRIORITIZED_IO)=200809
      _POSIX_PRIORITY_SCHEDULING(_SC_PRIORITY_SCHEDULING)=200809
      _POSIX_RAW_SOCKETS=-1
      _POSIX_READER_WRITER_LOCKS(_SC_READER_WRITER_LOCKS)=200809
      _POSIX_REALTIME_SIGNALS(_SC_REALTIME_SIGNALS)=200809
      _POSIX_REGEXP(_SC_REGEXP)=1
      _POSIX_SAVED_IDS(_SC_SAVED_IDS)=1
      _POSIX_SEMAPHORES(_SC_SEMAPHORES)=200809
      _POSIX_SHARED_MEMORY_OBJECTS(_SC_SHARED_MEMORY_OBJECTS)=200809
      _POSIX_SHELL(_SC_SHELL)=1
      _POSIX_SPAWN(_SC_SPAWN)=200809
      _POSIX_SPIN_LOCKS(_SC_SPIN_LOCKS)=200809
      _POSIX_SPORADIC_SERVER(_SC_SPORADIC_SERVER)=-1
      _POSIX_SYNCHRONIZED_IO(_SC_SYNCHRONIZED_IO)=200809
      _POSIX_THREAD_ATTR_STACKSIZE(_SC_THREAD_ATTR_STACKSIZE)=200809
      _POSIX_THREAD_CPUTIME(_SC_THREAD_CPUTIME)=200809
      _POSIX_THREAD_PRIO_INHERIT(_SC_THREAD_PRIO_INHERIT)=200809
      _POSIX_THREAD_PRIO_PROTECT(_SC_THREAD_PRIO_PROTECT)=200809
      _POSIX_THREAD_PRIORITY_SCHEDULING(_SC_THREAD_PRIORITY_SCHEDULING)=200809
      _POSIX_THREAD_PROCESS_SHARED(_SC_THREAD_PROCESS_SHARED)=200809
      _POSIX_THREAD_SAFE_FUNCTIONS(_SC_THREAD_SAFE_FUNCTIONS)=200809
      _POSIX_THREAD_SPORADIC_SERVER(_SC_THREAD_SPORADIC_SERVER)=-1
      _POSIX_THREADS(_SC_THREADS)=200809
      _POSIX_TIMEOUTS(_SC_TIMEOUTS)=200809
      _POSIX_TIMERS(_SC_TIMERS)=200809
      _POSIX_TRACE(_SC_TRACE)=-1
      _POSIX_TRACE_EVENT_FILTER(_SC_TRACE_EVENT_FILTER)=-1
      _POSIX_TRACE_INHERIT(_SC_TRACE_INHERIT)=-1
      _POSIX_TRACE_LOG(_SC_TRACE_LOG)=-1
      _POSIX_VDISABLE=2097152
      _XOPEN_CRYPT=63489
      _XOPEN_LEGACY=63489
      _XOPEN_REALTIME=63489
      _XOPEN_REALTIME_THREADS=63489
      _XOPEN_UNIX=63489
    time:
      raw: 1351542560.130094335
      local: Mon Oct 29 20:29:20 2012
      ISO: 2012-09-29T20:29
    timezone:
      tzname[0]='UTC'
      tzname[1]='UTC'
      timezone=0
      daylight=0
    tty:
      c_iflag=0x2502
      c_iflag:IGNBRK=0
      c_iflag:BRKINT=1
      c_iflag:IGNPAR=0
      c_iflag:PARMRK=0
      c_iflag:INPCK=0
      c_iflag:ISTRIP=0
      c_iflag:INLCR=0
      c_iflag:IGNCR=0
      c_iflag:ICRNL=1
      c_iflag:IUCLC=0
      c_iflag:IXON=1
      c_iflag:IXANY=0
      c_iflag:IXOFF=0
      c_iflag:IMAXBEL=1
      c_iflag:IUTF8=0
      c_oflag=0x5
      c_oflag:OPOST=1
      c_oflag:OLCUC=0
      c_oflag:ONLCR=1
      c_oflag:OCRNL=0
      c_oflag:ONOCR=0
      c_oflag:ONLRET=0
      c_oflag:OFILL=0
      c_oflag:OFDEL=0
      c_oflag:NLDLY=0
      c_oflag:CRDLY=0
      c_oflag:TABDLY=0
      c_oflag:BSDLY=0
      c_oflag:VTDLY=0
      c_oflag:FFDLY=0
      c_cflag=0x4bf
        [c_cflag:input baud speed=B38400]
        [c_cflag:output baud speed=B38400]
      c_cflag:CBAUDEX=0
      c_cflag:CSIZE=1
      c_cflag:CSTOPB=0
      c_cflag:CREAD=1
      c_cflag:PARENB=0
      c_cflag:PARODD=0
      c_cflag:HUPCL=1
      c_cflag:CLOCAL=0
      c_cflag:CIBAUD=0
      c_cflag:CMSPAR=0
      c_cflag:CRTSCTS=0
      c_lflag=0x8a3b
      c_lflag:ISIG=1
      c_lflag:XCASE=0
      c_lflag:ICANON=1
      c_lflag:ECHO=1
      c_lflag:ECHOE=1
      c_lflag:ECHOK=1
      c_lflag:ECHONL=0
      c_lflag:ECHOCTL=1
      c_lflag:ECHOPRT=0
      c_lflag:ECHOKE=1
      c_lflag:FLUSHO=0
      c_lflag:NOFLSH=0
      c_lflag:TOSTOP=0
      c_lflag:PENDIN=0
      c_lflag:IEXTEN=1
      c_cc:
        c_cc[VINTR]:0x3
        c_cc[VQUIT]:0x1c
        c_cc[VERASE]:0x7f
        c_cc[VKILL]:0x15
        c_cc[VEOF]:0x4
        c_cc[VTIME]:0x0
        c_cc[VMIN]:0x1
        c_cc[VSWTC]:0x0
        c_cc[VSTART]:0x11
        c_cc[VSTOP]:0x13
        c_cc[VSUSP]:0x1a
        c_cc[VEOL]:0x0
        c_cc[VREPRINT]:0x12
        c_cc[VDISCARD]:0xf
        c_cc[VWERASE]:0x17
        c_cc[VLNEXT]:0x16
        c_cc[VEOL2]:0x0
    uname:
      sysname: Linux
      nodename: quantal
      release: 3.5.0-17-generic
      version: #28-Ubuntu SMP Tue Oct 9 19:32:08 UTC 2012
      machine: i686
      domainname: (none)
    


    Code

    Grab the code from:



    2 comments:

    1. Cool! I've sent you a bunch of merges for more prctl and capabilities reporting.

      ReplyDelete
    2. Thanks very much for your contributions Kees - merged! Procenv should be in Debian soon.

      ReplyDelete