Portable ps
This commit is contained in:
parent
d805699156
commit
4f88768976
|
@ -0,0 +1,223 @@
|
|||
;;; This file is part of the Scheme Untergrund Library.
|
||||
|
||||
;;; Copyright (c) 2002-2003 by Martin Gasbichler.
|
||||
;;; For copyright information, see the file COPYING which comes with
|
||||
;;; the distribution.
|
||||
|
||||
(define-record-type process-info :process-info
|
||||
(really-make-process-info pid ppid logname
|
||||
real-uid effective-uid saved-set-uid
|
||||
real-gid effective-gid saved-set-gid
|
||||
time tty executable command-line)
|
||||
process-recrod?
|
||||
(pid process-info-pid)
|
||||
(ppid process-info-ppid)
|
||||
(logname process-info-logname)
|
||||
(real-uid process-info-real-uid)
|
||||
(effective-uid process-info-effective-uid)
|
||||
(saved-set-uid process-info-saved-set-uid)
|
||||
(real-gid process-info-real-gid)
|
||||
(effective-gid process-info-effective-gid)
|
||||
(saved-set-gid process-info-saved-set-gid)
|
||||
(time process-info-time)
|
||||
(tty process-info-tty)
|
||||
(executable process-info-executable)
|
||||
(command-line process-info-command-line))
|
||||
|
||||
(define-record-discloser :process-info
|
||||
(lambda (pi)
|
||||
(list 'pi (process-info-pid pi) (process-info-executable pi) (process-info-logname pi))))
|
||||
|
||||
(define (make-process-info-with-restlist
|
||||
ps-functions
|
||||
pid ppid logname
|
||||
real-uid effective-uid saved-set-uid
|
||||
real-gid effective-gid saved-set-gid
|
||||
time tty executable . command-line)
|
||||
(really-make-process-info
|
||||
(string->number pid) (string->number ppid) logname
|
||||
(string->number real-uid) (string->number effective-uid)
|
||||
(string->number saved-set-uid)
|
||||
(string->number real-gid) (string->number effective-gid)
|
||||
(string->number saved-set-gid)
|
||||
((ps-time->seconds ps-functions) time)
|
||||
tty executable command-line))
|
||||
|
||||
(define *os-pss* '())
|
||||
|
||||
(define (add-ps! ps-functions)
|
||||
(set! *os-pss* (cons ps-functions *os-pss*)))
|
||||
|
||||
(define (pps)
|
||||
(let ((os (uname:os-name (uname))))
|
||||
(let lp ((os-pss *os-pss*))
|
||||
(if (null? *os-pss*)
|
||||
(error "ps not defined for " os)
|
||||
(let ((next (car os-pss)))
|
||||
(if (string=? os (ps-uname-string next))
|
||||
(call-ps next)
|
||||
(lp (cdr os-pss))))))))
|
||||
|
||||
(define (call-ps ps-functions)
|
||||
(map (lambda (line)
|
||||
(apply make-process-info-with-restlist
|
||||
ps-functions
|
||||
((ps-line-splitter ps-functions) line)))
|
||||
((ps-command ps-functions))))
|
||||
|
||||
(define-record-type ps-functions :ps-functions
|
||||
(really-make-ps-functions uname-string command time->seconds line-splitter)
|
||||
ps-functions?
|
||||
(uname-string ps-uname-string)
|
||||
(command ps-command)
|
||||
(time->seconds ps-time->seconds)
|
||||
(line-splitter ps-line-splitter))
|
||||
|
||||
(define (make-ps-functions uname-string command time->seconds . maybe-line-splitter)
|
||||
(really-make-ps-functions uname-string
|
||||
command time->seconds
|
||||
(if (null? maybe-line-splitter)
|
||||
(sloppy-suffix-splitter)
|
||||
(car maybe-line-splitter))))
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; FreeBSD
|
||||
|
||||
(define (fbsd-ps-command)
|
||||
(let ((res (run/strings
|
||||
(ps -axww
|
||||
;; uses rgid instead of gid
|
||||
"-opid,ppid,user,ruid,uid,svuid,rgid,rgid,svgid,time,tty,ucomm,command"))))
|
||||
(if (null? res)
|
||||
(error "ps failed")
|
||||
(cdr res))))
|
||||
|
||||
(define fbsd-time->seconds ; hmm, what does the output look like for older processes??
|
||||
(let ((short-rx (rx (: (submatch (+ digit)) #\:
|
||||
(submatch (: digit digit)) #\.
|
||||
(submatch (: digit digit))))))
|
||||
(lambda (time)
|
||||
(let ((match-data (regexp-search short-rx time)))
|
||||
(if match-data
|
||||
(+ (* 60 (string->number (match:substring match-data 1)))
|
||||
(string->number (match:substring match-data 2))
|
||||
(quotient (string->number (match:substring match-data 3)) 50))
|
||||
0)))))
|
||||
|
||||
(define fbsd-ps (make-ps-functions "FreeBSD" fbsd-ps-command fbsd-time->seconds))
|
||||
(add-ps! fbsd-ps)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Darwin
|
||||
|
||||
(define (darwin-ps-command)
|
||||
(let ((res (run/strings
|
||||
(ps -axww
|
||||
;; uses rgid instead of gid
|
||||
"-opid,ppid,user,ruid,uid,svuid,rgid,svgid,time,tty,ucomm,command"))))
|
||||
(if (null? res)
|
||||
(error "ps failed")
|
||||
(cdr res))))
|
||||
|
||||
(define (darwin-line-splitter line)
|
||||
(let ((line-as-list ((sloppy-suffix-splitter) line)))
|
||||
(append (take line-as-list 7)
|
||||
(list (list-ref line-as-list 7))
|
||||
(drop line-as-list 7))))
|
||||
|
||||
(define darwin-ps (make-ps-functions "Darwin"
|
||||
darwin-ps-command
|
||||
fbsd-time->seconds
|
||||
darwin-line-splitter))
|
||||
(add-ps! darwin-ps)
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Linux
|
||||
(define (linux-ps-command)
|
||||
(let ((res (run/strings
|
||||
(ps -A ;axww
|
||||
"-opid,ppid,user,ruid,uid,svuid,rgid,gid,svgid,time,tty,ucomm,command"))))
|
||||
(if (null? res)
|
||||
(error "ps failed")
|
||||
(cdr res))))
|
||||
|
||||
(define linux-time->seconds ; hmm, what does the output look like for older processes??
|
||||
(let ((short-rx (rx (: (submatch (+ digit)) #\:
|
||||
(submatch (: digit digit)) #\:
|
||||
(submatch (: digit digit))))))
|
||||
(lambda (time)
|
||||
(let ((match-data (regexp-search short-rx time)))
|
||||
(if match-data
|
||||
(+ (* 60 60 (string->number (match:substring match-data 1)))
|
||||
(* 60 (string->number (match:substring match-data 2)))
|
||||
(string->number (match:substring match-data 3)))
|
||||
0)))))
|
||||
|
||||
(define linux-ps (make-ps-functions "Linux" linux-ps-command linux-time->seconds))
|
||||
(add-ps! linux-ps)
|
||||
|
||||
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; AIX
|
||||
|
||||
(define (aix-ps-command)
|
||||
(let ((res (run/strings
|
||||
(ps -A
|
||||
;; uses ruid/rgid instead of svuid/svgid
|
||||
-opid -oppid -ouser -oruid -ouid -oruid -orgid -ogid -orgid -otime -otty -oucomm -oargs))))
|
||||
(if (null? res)
|
||||
(error "ps failed")
|
||||
(cdr res))))
|
||||
|
||||
(define aix-time->seconds
|
||||
(let ((short-rx (rx (: (? (submatch (** 1 3 digit)) #\-)
|
||||
(submatch (** 1 2 digit)) #\:
|
||||
(submatch (: digit digit)) #\:
|
||||
(submatch (: digit digit))))))
|
||||
(lambda (time)
|
||||
(let ((match-data (regexp-search short-rx time)))
|
||||
(if match-data
|
||||
(+
|
||||
(if (match:substring match-data 1)
|
||||
(* 24 60 60 (string->number (match:substring match-data 1)))
|
||||
0)
|
||||
(* 60 60 (string->number (match:substring match-data 2)))
|
||||
(* 60 (string->number (match:substring match-data 3)))
|
||||
(string->number (match:substring match-data 4)))
|
||||
(error "cannot parse time" time))))))
|
||||
|
||||
(define aix-ps (make-ps-functions "AIX" aix-ps-command aix-time->seconds))
|
||||
(add-ps! aix-ps)
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;; Solaris
|
||||
|
||||
(define (solaris-ps-command)
|
||||
(let ((res (run/strings
|
||||
(ps -A
|
||||
;; uses ruid/rgid instead of svuid/svgid
|
||||
-opid -oppid -ouser -oruid -ouid -oruid -orgid -ogid -orgid -otime -otty -ocomm -oargs))))
|
||||
(if (null? res)
|
||||
(error "ps failed")
|
||||
(cdr res))))
|
||||
|
||||
(define solaris-time->seconds
|
||||
(let ((short-rx (rx (: (? (submatch (** 1 3 digit)) #\-)
|
||||
(? (submatch (** 1 2 digit)) #\:)
|
||||
(submatch (** 1 2 digit)) #\:
|
||||
(submatch (: digit digit))))))
|
||||
(lambda (time)
|
||||
(let ((match-data (regexp-search short-rx time)))
|
||||
(if match-data
|
||||
(+
|
||||
(if (match:substring match-data 1)
|
||||
(* 24 60 60 (string->number (match:substring match-data 1)))
|
||||
0)
|
||||
(if (match:substring match-data 2)
|
||||
(* 60 60 (string->number (match:substring match-data 2)))
|
||||
0)
|
||||
(* 60 (string->number (match:substring match-data 3)))
|
||||
(string->number (match:substring match-data 4)))
|
||||
(error "cannot parse time" time))))))
|
||||
|
||||
(define solaris-ps (make-ps-functions "SunOS" solaris-ps-command solaris-time->seconds))
|
||||
(add-ps! solaris-ps)
|
Loading…
Reference in New Issue