[#313454] Request for Block local methods, and Proc syntax — Patrick Li <patrickli_2001@...>

So after using Ruby for a little over two months, I've made the complete

20 messages 2008/09/01

[#313477] Looking for a regular pattern — Zhao Yi <youhaodeyi@...>

Which pattern represents any characters including space, \t \n?

23 messages 2008/09/01
[#313486] Re: Looking for a regular pattern — "Thomas Wieczorek" <wieczo.yo@...> 2008/09/01

On Mon, Sep 1, 2008 at 10:20 AM, Zhao Yi <youhaodeyi@gmail.com> wrote:

[#313489] Re: Looking for a regular pattern — Sebastian Hungerecker <sepp2k@...> 2008/09/01

Thomas Wieczorek wrote:

[#313490] Re: Looking for a regular pattern — Zhao Yi <youhaodeyi@...> 2008/09/01

Sebastian Hungerecker wrote:

[#313493] Re: Looking for a regular pattern — Sebastian Hungerecker <sepp2k@...> 2008/09/01

Zhao Yi wrote:

[#313496] Re: Looking for a regular pattern — Zhao Yi <youhaodeyi@...> 2008/09/01

Sebastian Hungerecker wrote:

[#313516] Parsing a CSV file column-wise — Chris Lowis <chris.lowis@...>

Is there a short-cut to parsing a CSV file column-wise using any of

14 messages 2008/09/01

[#313724] Hash optimization question — Roger Pack <rogerpack2005@...>

Are there any libraries that overcome this problem:

11 messages 2008/09/03

[#313890] How do I quickly search the end of a huge text file? — Brian Green <gallagherjb@...>

I am trying to create a ruby script that will search a maya ascii file

11 messages 2008/09/05

[#313897] Need a 40 LOC (ignoring comments) to be shorter -- suggestions wanted — RichardOnRails <RichardDummyMailbox58407@...>

Hi All,

12 messages 2008/09/05

[#313946] Who's Charles angry at? — Joshua Ballanco <jballanc@...>

Well, I just came across this in my feed reader:

17 messages 2008/09/05

[#314002] Is Ruby good at GUI develop? — Zhao Yi <youhaodeyi@...>

I want to choose a script to develop a GUI program. I want to know more

18 messages 2008/09/06
[#314011] Re: Is Ruby good at GUI develop? — James Britt <james.britt@...> 2008/09/06

Zhao Yi wrote:

[#314395] Re: Is Ruby good at GUI develop? — Jason Cameron <cameronjc2000@...> 2008/09/10

James Britt wrote:

[#314061] any way to write it in one line ? — Erwin <yves_dufour@...>

works = Array.new

17 messages 2008/09/06

[#314083] json for extjs (without rails) — Gurpal 2000 <gurpal@...>

Hi

14 messages 2008/09/07

[#314090] find a button using mechanize — Li Chen <chen_li3@...>

Hi all,

21 messages 2008/09/07
[#314116] Re: find a button using mechanize — Lex Williams <etaern@...> 2008/09/07

Li Chen wrote:

[#314117] Re: find a button using mechanize — Lex Williams <etaern@...> 2008/09/07

Lex Williams wrote:

[#314126] Re: find a button using mechanize — Li Chen <chen_li3@...> 2008/09/07

Lex Williams wrote:

[#314164] Re: find a button using mechanize — Lex Williams <etaern@...> 2008/09/07

Li Chen wrote:

[#314167] Re: find a button using mechanize — Li Chen <chen_li3@...> 2008/09/07

Lex Williams wrote:

[#314185] Re: find a button using mechanize — Lex Williams <etaern@...> 2008/09/08

Li , I wouldn't try to find a form by searching after it's button .

[#314233] Re: find a button using mechanize — Li Chen <chen_li3@...> 2008/09/08

Hi Lex,

[#314253] Re: find a button using mechanize — Lex Williams <etaern@...> 2008/09/08

Li , please post examples . What is it you want to extract ? From what

[#314133] regular expression match and exclude — Azalar --- <pteale@...>

I am parsing a web page full of image links that also contain links to

13 messages 2008/09/07

[#314199] FileUtils.chdir thread safety — Mr_Tibs <tiberiu.motoc@...>

Hi,

20 messages 2008/09/08
[#314285] Re: FileUtils.chdir thread safety — Mr_Tibs <tiberiu.motoc@...> 2008/09/08

Darn it! It would seem like a good idea.

[#314328] Re: FileUtils.chdir thread safety — "Robert Klemme" <shortcutter@...> 2008/09/09

2008/9/9 Mr_Tibs <tiberiu.motoc@gmail.com>:

[#314360] Re: FileUtils.chdir thread safety — Charles Oliver Nutter <charles.nutter@...> 2008/09/09

Robert Klemme wrote:

[#314299] Drake: Distributed Rake — quixoticsycophant@...

= DRAKE -- Distributed Rake

43 messages 2008/09/09

[#314470] How to operate on 2 arrays simultaneously? — "Patrick Doyle" <wpdster@...>

There has got to be a more elegant solution than this. Suppose I have

19 messages 2008/09/10

[#314492] Redefe each to include each_with_index and arity=2 — "DanDiebolt.exe" <dandiebolt@...>

Is is possible to redefine each so that each_with_index behavior can be acheived with an extra parameter to the block each is called with? In other words, how do you redefine each so that instead of using this construct:

9 messages 2008/09/10

[#314529] How to check if a webpage exists — Davide Benini <nutsmuggler@...>

This probably is trivial, but I have been googling for almost 2hs

22 messages 2008/09/10
[#314533] Re: How to check if a webpage exists — "Todd Benson" <caduceass@...> 2008/09/10

On Wed, Sep 10, 2008 at 4:38 PM, Davide Benini <nutsmuggler@hotmail.com> wrote:

[#314534] Re: How to check if a webpage exists — "Axel Etzold" <AEtzold@...> 2008/09/10

[#314572] Re: How to check if a webpage exists — Davide Benini <nutsmuggler@...> 2008/09/11

[#314575] Re: How to check if a webpage exists — Peña, Botp <botp@...> 2008/09/11

From: Davide Benini [mailto:nutsmuggler@hotmail.com]

[#314577] Re: How to check if a webpage exists — Davide Benini <nutsmuggler@...> 2008/09/11

Thanks for your super-fast answer :)

[#314584] Re: How to check if a webpage exists — "Axel Etzold" <AEtzold@...> 2008/09/11

-------- Original-Nachricht --------

[#314585] Re: How to check if a webpage exists — Davide Benini <nutsmuggler@...> 2008/09/11

Hi Axel,

[#314586] Re: How to check if a webpage exists — Peña, Botp <botp@...> 2008/09/11

From: Davide Benini [mailto:nutsmuggler@hotmail.com]

[#314538] pass by reference in each loop — Xiong Chiamiov <xiong.chiamiov+ruby_forum@...>

I have a list of variables that I need to pass through a modifying

19 messages 2008/09/10
[#314574] Re: pass by reference in each loop — Pedro Silva <ei04065@...> 2008/09/11

Hi,

[#314659] Re: pass by reference in each loop — Xiong Chiamiov <xiong.chiamiov+ruby_forum@...> 2008/09/11

Pedro Silva wrote:

[#314660] Re: pass by reference in each loop — Robert Klemme <shortcutter@...> 2008/09/11

On 11.09.2008 23:12, Xiong Chiamiov wrote:

[#314663] Re: pass by reference in each loop — Xiong Chiamiov <xiong.chiamiov+ruby_forum@...> 2008/09/11

Robert Klemme wrote:

[#314563] How to detect blocking? — David Masover <ninja@...>

I've been (barely, occasionally) writing an Actor system for Ruby.

16 messages 2008/09/11
[#314567] Re: How to detect blocking? — Robert Klemme <shortcutter@...> 2008/09/11

On 11.09.2008 06:48, David Masover wrote:

[#314677] Re: How to detect blocking? — David Masover <ninja@...> 2008/09/12

On Thursday 11 September 2008 01:33:25 Robert Klemme wrote:

[#314843] Garbage collecting threads? (was: How to detect blocking?) — David Masover <ninja@...> 2008/09/13

Suppose I start a worker thread, like so:

[#314869] Re: Garbage collecting threads? — Robert Klemme <shortcutter@...> 2008/09/14

On 13.09.2008 22:59, David Masover wrote:

[#314898] Re: Garbage collecting threads? — David Masover <ninja@...> 2008/09/14

On Sunday 14 September 2008 03:24:53 Robert Klemme wrote:

[#314566] How to use this Combinatorial testing technique — Surya <surya5kn@...>

Hi Friends,

13 messages 2008/09/11

[#314590] Advanced conditionals — "Alain m. Lafon" <preek.aml@...>

Hi there,

14 messages 2008/09/11

[#314608] A menubar for Shoes? — Andy Joel <ak_joel@...>

I have just recently tarted to look at Shoes, after a quick dabble with

10 messages 2008/09/11

[#314776] Beginner User having issue with converting char to ASCII — Nick Bo <bornemann1@...>

I am working on this assignment and this is the first class I have used

9 messages 2008/09/12

[#314826] RubyConf hotel: Only single-bed rooms available at group rate? — James Britt <james.britt@...>

Yesterday, the day or the day after I got the RubyConf E-mail giving me

14 messages 2008/09/13
[#314835] Re: RubyConf hotel: Only single-bed rooms available at group rate? — "Gregory Brown" <gregory.t.brown@...> 2008/09/13

On Sat, Sep 13, 2008 at 12:32 PM, James Britt <james.britt@gmail.com> wrote:

[#314838] Re: RubyConf hotel: Only single-bed rooms available at group rate? — James Britt <james.britt@...> 2008/09/13

Gregory Brown wrote:

[#314842] Re: RubyConf hotel: Only single-bed rooms available at group rate? — "Craig Demyanovich" <cdemyanovich@...> 2008/09/13

My partners and I were only able to book a non-smoking room with 1 king bed

[#314856] Re: RubyConf hotel: Only single-bed rooms available at group rate? — James Britt <james.britt@...> 2008/09/14

Craig Demyanovich wrote:

[#314861] A new database access framework for any Ruby (Iron or J) — Post-no-reply Tudbc <post-no-reply@...>

I would like to introduce my new exciting research in TUDBC (Truly

10 messages 2008/09/14

[#314877] how do deal with huge numbers and keep them accurate? — Tomi Zzzz <tomi_z@...>

Hello all, I wrote the following code:

10 messages 2008/09/14

[#314984] how to stream or write data into a tar.gz file as if the data were from files? — bwv549 <jtprince@...>

I have a gazillion little files in memory (each is really just a chunk

13 messages 2008/09/15

[#314989] Getting Employer to Pay for RubyConf — "Clinton D. Judy" <cdj@...>

So I'm just finishing my first year at a real job, and thinking about

15 messages 2008/09/15

[#315083] ANTLR Target for Ruby — arcadio <arcadiorubiogarcia@...>

Hi everyone,

29 messages 2008/09/16
[#315595] Re: ANTLR Target for Ruby — Clifford Heath <no@...> 2008/09/21

arcadio wrote:

[#315598] Re: ANTLR Target for Ruby — "Eric Mahurin" <eric.mahurin@...> 2008/09/21

On Sun, Sep 21, 2008 at 7:56 AM, Clifford Heath <no@spam.please.net> wrote:

[#315110] Gem program -- cannot install libxslt-ruby-0.3.6.gem — Robert Heller <heller@...>

I am trying to install some version of libxslt-ruby on my CentOS 4.7

9 messages 2008/09/17

[#315124] How to clean an xml files from non-utf-8 chars? — Krzysieq <krzysieq@...>

Hi,

19 messages 2008/09/17

[#315125] Threads preventing garbage collection? — Brian Candler <b.candler@...>

I wondered if someone can explain the following behaviour to me.

12 messages 2008/09/17

[#315203] Reseach paper on Ruby. Need references. — Suneel Suneel <suneelgv@...>

Hi,

12 messages 2008/09/18

[#315221] Suggestion for string parsing — Me Me <emanuelef@...>

Hi all,

18 messages 2008/09/18
[#315223] Re: Suggestion for string parsing — Chris Lowis <chris.lowis@...> 2008/09/18

> But I'm sure there's a better way, even considering that the number of

[#315224] Re: Suggestion for string parsing — Me Me <emanuelef@...> 2008/09/18

Thans for answering,

[#315226] Preserve insert order in a Hash — Me Me <emanuelef@...>

Hi,

20 messages 2008/09/18
[#315228] Re: Preserve insert order in a Hash — Peña, Botp <botp@...> 2008/09/18

From: Me Me [mailto:emanuelef@tiscali.it]

[#315249] at_exit handler *except* for fatal runtime error — synergism <synergism@...>

How do we execute a handler (I assume via at_exit) when a program

16 messages 2008/09/18

[#315250] why one array continues to grow after repeated call — Li Chen <chen_li3@...>

Hi all,

21 messages 2008/09/18
[#315259] Re: why one array continues to grow after repeated call — "Rick DeNatale" <rick.denatale@...> 2008/09/18

On Thu, Sep 18, 2008 at 8:41 AM, Li Chen <chen_li3@yahoo.com> wrote:

[#315311] Re: why one array continues to grow after repeated call — Randy Kramer <rhkramer@...> 2008/09/18

On Thursday 18 September 2008 09:01 am, Rick DeNatale wrote:

[#315326] Re: why one array continues to grow after repeated call — Brian Candler <b.candler@...> 2008/09/18

> The statement "Line 4 might look like an assignment to the variable a,

[#315342] Re: why one array continues to grow after repeated call — Randy Kramer <rhkramer@...> 2008/09/18

On Thursday 18 September 2008 02:52 pm, Brian Candler wrote:

[#315287] short regexp question — Fritzek <fritz.thielemann@...>

Hi folks

19 messages 2008/09/18

[#315458] RDoc 2.2.0 released — Tony Strauss <tony.strauss@...>

RDoc 2.2.0 now is available!

20 messages 2008/09/19

[#315460] One-Liners Mashup (#177 again) — Matthew Moss <matthew.moss@...>

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

46 messages 2008/09/19
[#315474] Re: [QUIZ] One-Liners Mashup (#177 again) — "Bill Kelly" <billk@...> 2008/09/20

[#315478] Re: [QUIZ] One-Liners Mashup (#177 again) — James Gray <james@...> 2008/09/20

On Sep 19, 2008, at 9:32 PM, Bill Kelly wrote:

[#315476] update a field in CSV file using fastercsv — Li Chen <chen_li3@...>

Hello everyone,

11 messages 2008/09/20

[#315527] for or each? — tekwiz <twarlick@...>

I just used the new roodi gem to check out some of my code that has a

38 messages 2008/09/20
[#315553] Re: for or each? — Joe Wfel <joe@...> 2008/09/20

It's interesting that array access using 'each' seems to be much

[#315532] Re: for or each? — Phlip <phlip2005@...> 2008/09/20

Phlip wrote:

[#315750] Protecting Ruby code — Sasha Bee <rubyman77@...>

We are just starting a new project and it is going to be a commercial

13 messages 2008/09/23

[#315818] Small, simple Ruby applications and sample code? — Double Minus <nathan.wisman@...>

Hi all,

16 messages 2008/09/24

[#315867] Rake dependencies unknown prior to running tasks — Joe Wfel <joe@...>

Say I don't know what all the dependencies are until I've already

13 messages 2008/09/24
[#315872] Re: Rake dependencies unknown prior to running tasks — Mike Gold <mike.gold.4433@...> 2008/09/24

Joe W旦lfel wrote:

[#315873] Re: Rake dependencies unknown prior to running tasks — Mike Gold <mike.gold.4433@...> 2008/09/24

Mike Gold wrote:

[#315912] Getting the right class with inheritance and super() — "Kyle Schmitt" <kyleaschmitt@...>

I'm wondering what the _right_ way is to go about getting the right

12 messages 2008/09/24
[#315941] Re: Getting the right class with inheritance and super() — David Masover <ninja@...> 2008/09/25

On Wednesday 24 September 2008 15:45:13 Kyle Schmitt wrote:

[#315920] Guy Decoux. — "Jean-Fran輟is Tr穗" <jftran@...>

Hello,

32 messages 2008/09/24

[#315954] Gem update on Windows is broken? — Charles Roper <reachme@...>

When I issue the "gem update" command on Windows, whenever it gets to a

17 messages 2008/09/25
[#316019] Re: Gem update on Windows is broken? — Eric Hodel <drbrain@...7.net> 2008/09/25

On Sep 25, 2008, at 01:22 AM, Charles Roper wrote:

[#316027] How to get terminal dimensions without using curses or ncurses? — Kenneth McDonald <kenneth.m.mcdonald@...>

I'd like to be able to print to terminal and do some reasonable

9 messages 2008/09/25

[#316033] How to make Ruby _THE_ scripting language of choice, fold in SQLite — John Carter <john.carter@...>

Much has been written about the OOP / RDBMS impedance mismatch....

20 messages 2008/09/25
[#316046] Re: How to make Ruby _THE_ scripting language of choice, fold in SQLite — David Masover <ninja@...> 2008/09/26

On Thursday 25 September 2008 18:43:31 John Carter wrote:

[#316051] Re: How to make Ruby _THE_ scripting language of choice, fold in SQLite — Clifford Heath <no@...> 2008/09/26

David Masover wrote:

[#316068] my ears are burning... ;) — parrt@...

Hi Gang, sorry I seem to have pissed off the ruby gang. :) Never

13 messages 2008/09/26

[#316106] Cookie Monster (#178) — "Matthew Moss" <matthew.moss@...>

-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-

17 messages 2008/09/26

[#316144] RubyGems 1.3.0 — Eric Hodel <drbrain@...7.net>

Note! Some versions of RubyGems have a bug that will prevent

15 messages 2008/09/26

[#316316] ruby1.9 block scope — Daniel DeLorme <dan-ml@...42.com>

I could have sworn that one of the firm changes in ruby 1.9 was that

45 messages 2008/09/29
[#316321] Re: ruby1.9 block scope — Yukihiro Matsumoto <matz@...> 2008/09/29

Hi,

[#316323] Re: ruby1.9 block scope — Daniel DeLorme <dan-ml@...42.com> 2008/09/29

Yukihiro Matsumoto wrote:

[#316325] Re: ruby1.9 block scope — Yukihiro Matsumoto <matz@...> 2008/09/29

Hi,

[#316347] Re: ruby1.9 block scope — Daniel DeLorme <dan-ml@...42.com> 2008/09/29

Yukihiro Matsumoto wrote:

[#316365] Re: ruby1.9 block scope — Nobuyoshi Nakada <nobu@...> 2008/09/29

Hi,

[#316386] Re: ruby1.9 block scope — Daniel DeLorme <dan-ml@...42.com> 2008/09/30

Nobuyoshi Nakada wrote:

[#316401] Re: ruby1.9 block scope — Yukihiro Matsumoto <matz@...> 2008/09/30

Hi,

[#316430] Re: ruby1.9 block scope — "David A. Black" <dblack@...> 2008/09/30

Hi --

[#316470] Re: ruby1.9 block scope — Daniel DeLorme <dan-ml@...42.com> 2008/09/30

David A. Black wrote:

[#316486] Re: ruby1.9 block scope — Mike Gold <mike.gold.4433@...> 2008/09/30

[#316495] Re: ruby1.9 block scope — Yukihiro Matsumoto <matz@...> 2008/09/30

Hi,

[#316499] Re: ruby1.9 block scope — Mike Gold <mike.gold.4433@...> 2008/09/30

Yukihiro Matsumoto wrote:

[#316392] Revision control for Ruby — thiagobrandam <thiagobrandam@...>

Does anyone know any good revision control tool/software for Ruby?

25 messages 2008/09/30

[#316450] Real world ruby programs to learn from — Fernando Perez <pedrolito@...>

Hi,

12 messages 2008/09/30

[#316526] Mode method for Array — Glenn <glenn_ritz@...>

Hi,

21 messages 2008/09/30
[#316533] Re: Mode method for Array — Trans <transfire@...> 2008/09/30

[#316536] Re: Mode method for Array — Erik Veenstra <erikveen@...> 2008/10/01

[#316552] Re: Mode method for Array — Brian Candler <b.candler@...> 2008/10/01

Shame that the standard Hash#invert doesn't handle duplicate values

[#316564] Re: Mode method for Array — Erik Veenstra <erikveen@...> 2008/10/01

And since we all love speed, we tend to avoid inject. (For

Optimization help - reading out of /proc on Solaris

From: Daniel Berger <djberg96@...>
Date: 2008-09-16 12:47:48 UTC
List: ruby-talk #315057
Hi all,

Ruby 1.8.6
Solaris 10

I recently converted a C extension to get process table information on
Solaris into a pure Ruby. I knew it would be slower, I just didn't
realize how _much_ slower it would be. I was expecting the pure Ruby
version to be about 1/10th as fast. Instead, it's about 1/70th as
fast. Anticipating the, "Is it fast enough?" question, my answer is,
"I'm not sure". Besides, tuning can be fun. :)

Anyway, below is the code. I ran it through the profiler, but the top
two most costly ops were Dir.foreach, which I don't see any way to
optimize*, and the loop that gathers environment information, which I
again see no way to optimize.

# sunos.rb
#
# A pure Ruby version of sys-proctable for SunOS 5.8 or later
#--
# Directories under /proc on Solaris 2.8+

# The Sys module serves as a namespace only.
module Sys

   # The ProcTable class encapsulates process table information.
   class ProcTable

      # The version of the sys-proctable library
      VERSION = '0.8.0'

      private

      PRNODEV = -1 # non-existent device

      FIELDS = [
         :flag,      # process flags (deprecated)
         :nlwp,      # number of active lwp's in the process
         :pid,       # unique process id
         :ppid,      # process id of parent
         :pgid,      # pid of session leader
         :sid,       # session id
         :uid,       # real user id
         :euid,      # effective user id
         :gid,       # real group id
         :egid,      # effective group id
         :addr,      # address of the process
         :size,      # size of process in kbytes
         :rssize,    # resident set size in kbytes
         :ttydev,    # tty device (or PRNODEV)
         :pctcpu,    # % of recent cpu used by all lwp's
         :pctmem,    # % of system memory used by process
         :start,     # absolute process start time
         :time,      # usr + sys cpu time for this process
         :ctime,     # usr + sys cpu time for reaped children
         :fname,     # name of the exec'd file
         :psargs,    # initial characters argument list
         :wstat,     # if a zombie, the wait status
         :argc,      # initial argument count
         :argv,      # address of initial argument vector
         :envp,      # address of initial environment vector
         :dmodel,    # data model of the process
         :taskid,    # task id
         :projid,    # project id
         :nzomb,     # number of zombie lwp's in the process
         :poolid,    # pool id
         :zoneid,    # zone id
         :contract,  # process contract
         :lwpid,     # lwp id
         :wchan,     # wait address for sleeping lwp
         :stype,     # synchronization event type
         :state,     # numeric lwp state
         :sname,     # printable character for state
         :nice,      # nice for cpu usage
         :syscall,   # system call number (if in syscall)
         :pri,       # priority
         :clname,    # scheduling class name
         :name,      # name of system lwp
         :onpro,     # processor which last ran thsi lwp
         :bindpro,   # processor to which lwp is bound
         :bindpset,  # processor set to which lwp is bound
         :count,     # number of contributing lwp's
         :tstamp,    # current time stamp
         :create,    # process/lwp creation time stamp
         :term,      # process/lwp termination time stamp
         :rtime,     # total lwp real (elapsed) time
         :utime,     # user level cpu time
         :stime,     # system call cpu time
         :ttime,     # other system trap cpu time
         :tftime,    # text page fault sleep time
         :dftime,    # text page fault sleep time
         :kftime,    # kernel page fault sleep time
         :ltime,     # user lock wait sleep time
         :slptime,   # all other sleep time
         :wtime,     # wait-cpu (latency) time
         :stoptime,  # stopped time
         :minf,      # minor page faults
         :majf,      # major page faults
         :nswap,     # swaps
         :inblk,     # input blocks
         :oublk,     # output blocks
         :msnd,      # messages sent
         :mrcv,      # messages received
         :sigs,      # signals received
         :vctx,      # voluntary context switches
         :ictx,      # involuntary context switches
         :sysc,      # system calls
         :ioch,      # chars read and written
         :path,      # array of symbolic link paths from /proc/<pid>/
pid
         :contracts, # array symbolic link paths from /proc/<pid>/
contracts
         :fd,        # array of used file descriptors
         :cmd_args,  # array of command line arguments
         :environ    # hash of environment associated with the process
      ]

      public

      ProcTableStruct = Struct.new("ProcTableStruct", *FIELDS)

      # In block form, yields a ProcTableStruct for each process entry
that you
      # have rights to. This method returns an array of
ProcTableStruct's in
      # non-block form.
      #
      # If a +pid+ is provided, then only a single ProcTableStruct is
yielded or
      # returned, or nil if no process information is found for that
+pid+.
      #
      # Example:
      #
      #   # Iterate over all processes
      #   ProcTable.ps do |proc_info|
      #      p proc_info
      #   end
      #
      #   # Print process table information for only pid 1001
      #   p ProcTable.ps(1001)
      #
      def self.ps(pid = nil)
         array = block_given? ? nil : []

         Dir.foreach("/proc") do |file|
            next if file =~ /\D/ # Skip non-numeric entries under /
proc

            # Only return information for a given pid, if provided
            if pid
               next unless file.to_i == pid
            end

            # Skip over any entries we don't have permissions to read
            begin
               psinfo = IO.read("/proc/#{file}/psinfo")
            rescue StandardError, Errno::EACCES
               next
            end

            struct = ProcTableStruct.new

            struct.flag   = psinfo[0,4].unpack("i")[0]  # pr_flag
            struct.nlwp   = psinfo[4,4].unpack("i")[0]  # pr_nlwp
            struct.pid    = psinfo[8,4].unpack("i")[0]  # pr_pid
            struct.ppid   = psinfo[12,4].unpack("i")[0] # pr_ppid
            struct.pgid   = psinfo[16,4].unpack("i")[0] # pr_pgid
            struct.sid    = psinfo[20,4].unpack("i")[0] # pr_sid
            struct.uid    = psinfo[24,4].unpack("i")[0] # pr_uid
            struct.euid   = psinfo[28,4].unpack("i")[0] # pr_euid
            struct.gid    = psinfo[32,4].unpack("i")[0] # pr_gid
            struct.egid   = psinfo[36,4].unpack("i")[0] # pr_egid
            struct.addr   = psinfo[40,4].unpack("L")[0] # pr_addr

            struct.size   = psinfo[44,4].unpack("L")[0] * 1024 #
pr_size
            struct.rssize = psinfo[48,4].unpack("L")[0] * 1024 #
pr_rssize

            # skip pr_pad1

            # TODO: Convert this to a human readable string somehow
            struct.ttydev = psinfo[56,4].unpack("i")[0] # pr_ttydev

            # pr_pctcpu
            struct.pctcpu = (psinfo[60,2].unpack("S")[0] * 100).to_f /
0x8000

            # pr_pctmem
            struct.pctmem = (psinfo[62,2].unpack("S")[0] * 100).to_f /
0x8000

            struct.start = Time.at(psinfo[64,8].unpack("L")[0]) #
pr_start
            struct.time  = psinfo[72,8].unpack("L")[0]          #
pr_time
            struct.ctime = psinfo[80,8].unpack("L")[0]          #
pr_ctime

            struct.fname  = psinfo[88,16].strip          # pr_fname
            struct.psargs = psinfo[104,80].strip         # pr_psargs
            struct.wstat  = psinfo[184,4].unpack("i")[0] # pr_wstat
            struct.argc   = psinfo[188,4].unpack("i")[0] # pr_argc
            struct.argv   = psinfo[192,4].unpack("L")[0] # pr_argv
            struct.envp   = psinfo[196,4].unpack("L")[0] # pr_envp
            struct.dmodel = psinfo[200,1].unpack("C")[0] # pr_dmodel

            # skip pr_pad2

            struct.taskid   = psinfo[204,4].unpack("i")[0] # pr_taskid
            struct.projid   = psinfo[208,4].unpack("i")[0] #
pr_projectid
            struct.nzomb    = psinfo[212,4].unpack("i")[0] # pr_nzomb
            struct.poolid   = psinfo[216,4].unpack("i")[0] # pr_poolid
            struct.zoneid   = psinfo[220,4].unpack("i")[0] # pr_zoneid
            struct.contract = psinfo[224,4].unpack("i")[0] #
pr_contract

            # skip pr_filler

            ### lwpsinfo struct info

            # skip pr_flag

            struct.lwpid = psinfo[236,4].unpack("i")[0] # pr_lwpid

            # skip pr_addr

            struct.wchan   = psinfo[244,4].unpack("L")[0] # pr_wchan
            struct.stype   = psinfo[248,1].unpack("C")[0] # pr_stype
            struct.state   = psinfo[249,1].unpack("C")[0] # pr_state
            struct.sname   = psinfo[250,1]                # pr_sname
            struct.nice    = psinfo[251,1].unpack("C")[0] # pr_nice
            struct.syscall = psinfo[252,2].unpack("S")[0] # pr_syscall

            # skip pr_oldpri
            # skip pr_cpu

            struct.pri = psinfo[256,4].unpack("i")[0] # pr_syscall

            # skip pr_pctcpu
            # skip pr_pad
            # skip pr_start
            # skip pr_time

            struct.clname   = psinfo[280,8].strip          # pr_clname
            struct.name     = psinfo[288,16].strip         # pr_name
            struct.onpro    = psinfo[304,4].unpack("i")[0] # pr_onpro
            struct.bindpro  = psinfo[308,4].unpack("i")[0] #
pr_bindpro
            struct.bindpset = psinfo[308,4].unpack("i")[0] #
pr_bindpset

            # Get the full command line out of /proc/<pid>/as.
            begin
               fd = File.open("/proc/#{file}/as")

               fd.sysseek(struct.argv, IO::SEEK_SET)
               address = fd.sysread(struct.argc * 4).unpack("L")[0]

               struct.cmd_args = []

               0.upto(struct.argc - 1){ |i|
                  fd.sysseek(address, IO::SEEK_SET)
                  data = fd.sysread(128)[/^[^\0]*/] # Null strip
                  struct.cmd_args << data
                  address += data.length + 1 # Add 1 for the space
               }

               # Get the environment hash associated with the process.
               struct.environ = {}

               fd.sysseek(struct.envp, IO::SEEK_SET)

               env_address = fd.sysread(128).unpack("L")[0]

               loop do
                  fd.sysseek(env_address, IO::SEEK_SET)
                  data = fd.sysread(1024)[/^[^\0]*/] # Null strip
                  break if data.empty?
                  key, value = data.split('=')
                  struct.environ[key] = value
                  env_address += data.length + 1 # Add 1 for the space
               end
            rescue Errno::EACCES, Errno::EOVERFLOW, EOFError
               # Skip this if we don't have proper permissions, if
there's
               # no associated environment, or if there's a largefile
issue.
            ensure
               fd.close if fd
            end

            ### struct prusage

            begin
               prusage = 0.chr * 512
               prusage = IO.read("/proc/#{file}/usage")

               # skip pr_lwpid
               struct.count    = prusage[4,4].unpack("i")[0]  #
pr_count
               struct.tstamp   = prusage[8,8].unpack("L")[0]  #
pr_tstamp
               struct.create   = prusage[16,8].unpack("L")[0] #
pr_create
               struct.term     = prusage[24,8].unpack("L")[0] #
pr_term
               struct.rtime    = prusage[32,8].unpack("L")[0] #
pr_rtime
               struct.utime    = prusage[40,8].unpack("L")[0] #
pr_utime
               struct.stime    = prusage[48,8].unpack("L")[0] #
pr_stime
               struct.ttime    = prusage[56,8].unpack("L")[0] #
pr_ttime
               struct.tftime   = prusage[64,8].unpack("L")[0] #
pr_tftime
               struct.dftime   = prusage[72,8].unpack("L")[0] #
pr_dftime
               struct.kftime   = prusage[80,8].unpack("L")[0] #
pr_kftime
               struct.ltime    = prusage[88,8].unpack("L")[0] #
pr_ltime
               struct.slptime  = prusage[96,8].unpack("L")[0] #
pr_slptime
               struct.wtime    = prusage[104,8].unpack("L")[0] #
pr_wtime
               struct.stoptime = prusage[112,8].unpack("L")[0] #
pr_stoptime
               struct.minf     = prusage[120,4].unpack("L")[0] #
pr_minf
               struct.majf     = prusage[124,4].unpack("L")[0] #
pr_majf
               struct.nswap    = prusage[128,4].unpack("L")[0] #
pr_nswap
               struct.inblk    = prusage[128,4].unpack("L")[0] #
pr_inblk
               struct.oublk    = prusage[128,4].unpack("L")[0] #
pr_oublk
               struct.msnd     = prusage[128,4].unpack("L")[0] #
pr_msnd
               struct.mrcv     = prusage[128,4].unpack("L")[0] #
pr_mrcv
               struct.sigs     = prusage[128,4].unpack("L")[0] #
pr_sigs
               struct.vctx     = prusage[128,4].unpack("L")[0] #
pr_vctx
               struct.ictx     = prusage[128,4].unpack("L")[0] #
pr_ictx
               struct.sysc     = prusage[128,4].unpack("L")[0] #
pr_sysc
               struct.ioch     = prusage[128,4].unpack("L")[0] #
pr_ioch
            rescue Errno::EACCES
               # Do nothing if we lack permissions. Just move on.
            end

            # Information from /proc/<pid>/path. This is represented
as a hash,
            # with the symbolic link name as the key, and the file it
links to
            # as the value, or nil if it cannot be found.
            #--
            # Note that cwd information can be gathered from here,
too.
            struct.path = {}

            Dir["/proc/#{file}/path/*"].each{ |entry|
               link = File.readlink(entry) rescue nil
               struct.path[File.basename(entry)] = link
            }

            # Information from /proc/<pid>/contracts. This is
represented as
            # a hash, with the symbolic link name as the key, and the
file
            # it links to as the value.
            struct.contracts = {}

            Dir["/proc/#{file}/contracts/*"].each{ |entry|
               link = File.readlink(entry) rescue nil
               struct.contracts[File.basename(entry)] = link
            }

            # Information from /proc/<pid>/fd. This returns an array
of
            # numeric file descriptors used by the process.
            struct.fd = Dir["/proc/#{file}/fd/*"].map{ |f|
File.basename(f).to_i }

            if block_given?
               yield struct
            else
               array << struct
            end
         end

         pid ? array[0] : array
      end
   end
end

Thanks,

Dan

* I tried tossing threads at it in a one-thread-per-directory
approach, but they didn't get along with IO.read in MRI, and seemed to
provide no real speed benefit with JRuby.

In This Thread

Prev Next