SlideShare a Scribd company logo
A Ruby Guide to
*nix Plumbing
The fun of a little knowledge applied unwisely


http://slides.games-with-brains.net
presenting
                Eleanor McHugh
             eleanor@games-with-brains.com




              usual haunts include
                      ruby-talk
                      LRUG
                      devchix
cowgirl for hire
web applications
domain names
broadcast automation
cockpit avionics
her goal
to make *nix a native of the Ruby environment
on the road to perdition
“Are you God’s work, or the Devil’s? Oh, what do
I care whose work you are? You poor silent
creature.”
                         - A Company of Wolves
caveat lector

 danger! we’re entering strange territory
 our map will be missing some major landmarks
 and will be riddled with inaccuracies
 so don’t try this on a live production system
 and read your man pages thoroughly
worse is better
the unix philosophy of life
it’s smart to be lazy
 create small tools
 to solve simple tasks effectively
 perform each task independently
 and pass the results from one task to another
 using a clean interface
 thus solving complex problems sociably
inherently agile
only build what you need
reuse what you already have
change your tools as [des|requ]ired
totally punk
“if you give people the license to be as
outrageous as they want in absolutely any
fashion they can dream up, they’ll be creative
about it, and do something good besides”
                                    - Lester Bangs
the unix kernel
a ruby perspective
basic services
 virtual memory
 process management
 hierarchical file system
 user permissions
 interprocess communication
 signals and interrupts
 execution environment
anatomy of a process
program instructions
program data
system data (file descriptors, user, group, parent, etc.)
environment data
supports one or more threads of execution
preemptively scheduled by the kernel
process creation
a process may spawn child processes via fork()
this creates a duplicate child process
with duplicate file descriptors and program state
which can be replaced via exec() of a new program
all processes ultimately derive from the init process
which is created by the kernel at boot
a costly strategy
 sometimes we only want a blank slate process
 but fork() copies the full process state
 so BSD introduced vfork() which shares data memory
 whilst POSIX introduced spawn()
 most fork() implementations now use copy-on-write
 so the advantages of vfork() have diminished
with certain limitations

 only the thread which forks will be in the child process
 a green threads system can work around this
 although Ruby 1.8 doesn’t seem to
 it’s also possible for exec() to fail
 so forked processes need to guard for this
and a taste for brains

 a zombie is a subprocess which outlives its parent
 zombies are members of the system process group
 and are eventually terminated
 but until then they retain resources
 and may not flush all of their IO buffers
Kernel.system [env ,] cmnd [, args] [, options] => true or false or nil
Kernel.spawn [env ,] cmnd [, args] [, options] => pid
The simplest way to take advantage of multiple processes in Ruby is to
launch a subshell and either block until it terminates or keep a note of its
process ID so this can be checked later. This is an opaque method and
not useful when the parent process wishes to capture results.

IO.` cmd ` => string
The next step up in utility from system() and spawn(), the backquote
method captures standard output from the subshell and as a bonus
stores a Process::Status object in the thread-global $? variable.
IO.popen cmd [, mode = quot;rquot;] => io
IO.popen cmd [, mode = quot;rquot; [{ | io | block }] => obj
Invokes a command shell in a subprocess and executes the specified
commands, providing a [uni|bi]directional pipe which the parent process
can use to communicate with the subprocess.

Open3.popen3 cmd [{ |stdin, stdout, stderr| block }]
Open3.popen3 cmd => array
A wrapper for spawn() which provides access to the standard IO streams
of the subshell along with a thread waiting on it.
Kernel.fork [{ block }] => fixnum or nil
Process.fork [{ block }] => fixnum or nil
Ruby provides its own fork() implementation which can either take a
block and run it in a subprocess, or can allow a more traditional split in
execution paths. No IPC mechanism is provided beyond allowing the
parent to wait on the child process and receive an error code.

Kernel.exec [env ,] cmnd [, args] [, options]
And as you’d expect it also allows access to the exec() family of system
calls. This is a rare core library methods which doesn’t return a value for
the simple reason that the existing program ceases to exist unless an
error occurs, and that’s flagged with a SystemCallError exception. It’s
common practice to terminate the program or retry exec() after a delay.
file descriptors

 the kernel keeps a table of open files for each process
 an integer index is used to reference entries
 and is known as a file descriptor
 unix is liberal about what counts as a file
 and most descriptors are inherited by child processes
beware the subtleties
 file descriptors are unique to a process
 so closing a descriptor only affects that process
 but the underlying descriptions are shared
 performing an lseek() changes the description
 and can therefore affect other processes
 with much hilarity ensuing...
IO.sysopen path [, mode [, perm] => fixnum
io.sysread int [, buffer] => string
io.syswrite string => int
io.sysseek offset, whence = SEEK_SET => int
These methods make direct calls to the kernel to open and manipulate
the contents of files, bypassing buffering. They shouldn’t be used with
higher-level methods such as IO#read as unpredictable results may occur.

Errors are raised as Exceptions in the Errno namespace.
IO.new fd [, mode] [, opt] => io
IO.for_fd fd [, mode] [, opt] => io
Returns a new IO object (a stream) for the given IO object or integer file
descriptor and mode string. See also IO#fileno and IO.for_fd.

  a = IO.new(2,quot;wquot;)    # '2' is standard error
  $stderr.puts quot;Helloquot;
  a.puts quot;Worldquot;

produces:

  Hello
  World
require 'fcntl'
filemode = Fcntl::O_CREAT | Fcntl::O_RDWR | Fcntl::O_APPEND
descriptor = IO.sysopen “test.dat”, filemode
file = IO.for_fd descriptor
file.syswrite “hello”
file.sysseek 0
file.sysread 10

produces:
  hello
handling many files at once

file access is much slower than memory access
this causes threads and processes to block
so usually IO is buffered by the kernel
and non-blocking access methods are implemented
however this is still ineffient when writing servers
select rd_ary [, wrt_ary] [, err_ary] [, timeout] => array or nil
Select is the standard low-level method for polling many IO streams at
once and it’s a blocking call, hence the need for a timeout. For writing
socket servers etc. this usually works reasonably well and Ruby’s
implementation plays nicely with threads.
kernel eventing
 allows the kernel to raise events for streams
 a process can then poll for events without blocking
 on BSD this is handled by kqueue
 on Linux by epoll and inotify
 epoll is much more efficient that inotify
 EventMachine makes use of whichever it can find
Interprocess Communication
IPC objects have descriptors like files
but they don’t need to exist in the file system
POSIX and System V interfaces
System V uses keys to identify IPC objects
keys can be generated from paths using ftok()
POSIX uses paths to identify IPC objects
pipes

provides a pair of end-points for processes to talk
an unnamed pipe connects related processes
a named pipe is like a file
it has user permissions
and can be accessed by unrelated processes
IO.pipe => read_file, write_file
Ruby supports anonymous pipes, which can be used to communicate
between a parent a child process, taking advantage of the fact that the
file descriptors for the end-points will exist across a fork().

Good practice is for the parent process to close the reading end of the
pipe whilst the child closes the writing end as soon as they return from
fork() and the child should also close the reading end before it terminates
to ensure buffered data is properly flushed.
sockets


ruby has excellent support for sockets
use it unless you need kernel level eventing
signals


 wrapped nicely by the Signal class
 with support for signal handlers
shared memory
a single defined region of virtual memory
can be mapped into many different processes
each of which can modify it
this offers a flexible form of IPC
but to be effective requires synchronisation
ruby has no direct support for shared memory
semaphores


exist independently of processes
ruby has no direct support for semaphores
but later we’ll see how to use them anyway
syscall
calling functions in the kernel
from the docs
Kernel#syscall fixnum [, args...] => integer
Calls the operating system function identified by fixnum, passing in the
arguments, which must be either String objects, or Integer objects that
ultimately fit within a native long. Up to nine parameters may be passed
(14 on the Atari-ST). The function identified by fixnum is system
dependent. On some Unix systems, the numbers may be obtained from a
header file called syscall.h.

  syscall 4, 1, “hellon”, 6 # ‘4’ is write(2) on our box

produces:

  hello
finding your syscall codes

 MacOS X
   /usr/include/sys/syscall.h
 Linux
   /usr/include/asm/unistd_32.h
   /usr/include/asm/unistd_64.h
a fragile approach
 the native syscall is a very primitive interface
   error codes
   file descriptors & pointer addresses
   modifiable buffers
 ruby syscall doesn’t support modifiable buffers
 but it does wrap errors as Errno exceptions
IO.sysx the hard way
On MacOS X

  file = syscall 5, “test.dat”, 1      # open O_WRONLY (fcntl.h)
  syscall 4, file, “some textn”, 10   # write
  syscall 3, file, “”, 5               # read
  syscall 6, file                      # close

produces:
  Errno::EFAULT: Bad address          should be Errno::EBADF
posix semaphores
process 1                                            process 2

  require ‘fcntl’                                      Open, Wait, TryWait, Post = 268, 271, 272, 273
  Open, Wait, Post, Close = 268, 271, 273, 269         s = syscall Open, “/tmp/s”
  s = syscall Open, “/tmp/s”, Fcntl::O_CREAT, 1911     begin
  syscall Wait, s                                           t = Time.now
  puts “locked at #{Time.now}”                              syscall TryWait, s
  sleep 50                                                  puts “locked at #{t}”
  puts “posted at #{Time.now}”                         rescue Exception => e
  syscall Post, s                                           puts “busy at #{t}”
  syscall Close, s                                          syscall Wait, s
                                                            puts “waited #{Time.now - t} seconds”
                                                       end


produces:                                            produces:
  locked at Thu May 28 01:03:23 +0100 2009             busy at Thu May 28 01:03:36 +0100 2009
  posted at Thu May 28 01:04:13 +0100 2009             waited 47.056508 seconds
complex parameters
some kernel calls accept structured data types
ruby represents these as String objects
which can be prepared with
  Array#pack
  Joel VanderWerf’s bit-struct library
both approaches allow embedded nulls
but on 1.9 remember to use 8-bit ASCII encoding
except when they don’t
On Ruby 1.8.7 or 1.9.1 (upto patch 129)

  syscall 4, 1, “hellon#{0.chr}goodbyen”, 15

produces:

  ArgumentError: string contains null byte
     from (irb):1:in `syscall'
     from (irb):1
     from /usr/local/bin/irb19:12:in `<main>'

This should be fixed in patch 130.
ruby/dl
memory buffers
structs
c runtime access
ruby/dl
 part of the standard library since ruby 1.8
 access to dynamically loaded libraries
   .dll on windows
   .so and .dylib on unix
 supports C-style memory access
 and callback functions written in Ruby
require ‘dl’
libc = DL.dlopen(‘libc.dylib’)
open = libc[‘syscall’, ‘IISI’]
write = libc[‘syscall’, ‘IIISI’]
read = libc[‘syscall’, ‘IIIsI’]
close = libc[‘syscall’, ‘III’]      produces:
file = open.call 5, “test.dat”, 1       [3, [5, quot;test.datquot;, 1]]
write.call 4, file[0], “textn”, 5      [5, [4, 3, quot;textnquot;, 5]]
close.call 6, file[0]                   [0, [6, 3]]
file = open.call 5, “test.dat”, 0       [3, [5, quot;test.datquot;, 0]]
buffer = DL.malloc(10)
read.call(3, file[0], buffer, 10)       [5, [3, 3, quot;textnquot;, 10]]
close.call 6, file[0]                   [0, [6, 3]]
require ‘dl’                                            file = open “test.dat”, 0x0209
CRT = DL.dlopen ‘libc.dylib’                            write file, “textn”
F = ‘syscall’                                           close file

def open file, mode                                      file = open “test.dat”, 0x0000
     CRT[F, ‘IISI’].call(5, file, mode)[0]               text = read file, 10
end                                                     close file

def write fd, string, bytes = string.length
    CRT[F, ‘IIISI’].call(4, fd, string, bytes)[0]
end

def read fd, bytes = 1
     buffer = DL.malloc(bytes)
     CRT[F, ‘IIIsI’].call(3, fd, buffer, bytes)[1][2]
end

def close fd
     CRT[F, ‘III’].call(6, fd)[0]
end
memory management
memory pointers encapsulated by DL::PtrData
garbage collected
  uses free() or a custom deallocator
  handles realloc() automatically
plays nicely with ruby strings and arrays
  [String|Array].to_ptr
  PtrData.struct! and PtrData.union!
where next?
books
uris
http://slides.games-with-brains.net

http://www.jbrowse.com/text/rdl_en.html

http://www.kegel.com/c10k.html

http://www.ecst.csuchico.edu/~beej/guide/ipc/

http://beej.us/guide/bgnet/

http://wiki.netbsd.se/kqueue_tutorial
always stray from the path...
“And that’s all I’ll tell you, cause that’s all I know.”
                               - A Company of Wolves

More Related Content

What's hot

Bypassing anti virus scanners
Bypassing anti virus scannersBypassing anti virus scanners
Bypassing anti virus scannersmartacax
 
Why Erlang? - Bar Camp Atlanta 2008
Why Erlang?  - Bar Camp Atlanta 2008Why Erlang?  - Bar Camp Atlanta 2008
Why Erlang? - Bar Camp Atlanta 2008
boorad
 
Erlang
ErlangErlang
Erlang
ESUG
 
[Defcon24] Introduction to the Witchcraft Compiler Collection
[Defcon24] Introduction to the Witchcraft Compiler Collection[Defcon24] Introduction to the Witchcraft Compiler Collection
[Defcon24] Introduction to the Witchcraft Compiler Collection
Moabi.com
 
Composing and Executing Parallel Data Flow Graphs wth Shell Pipes
Composing and Executing Parallel Data Flow Graphs wth Shell PipesComposing and Executing Parallel Data Flow Graphs wth Shell Pipes
Composing and Executing Parallel Data Flow Graphs wth Shell PipesVinoth Chandar
 
PE Packers Used in Malicious Software - Part 1
PE Packers Used in Malicious Software - Part 1PE Packers Used in Malicious Software - Part 1
PE Packers Used in Malicious Software - Part 1
amiable_indian
 
Kernel Recipes 2019 - Faster IO through io_uring
Kernel Recipes 2019 - Faster IO through io_uringKernel Recipes 2019 - Faster IO through io_uring
Kernel Recipes 2019 - Faster IO through io_uring
Anne Nicolas
 
Fun with Network Interfaces
Fun with Network InterfacesFun with Network Interfaces
Fun with Network Interfaces
Kernel TLV
 
The TCP/IP stack in the FreeBSD kernel COSCUP 2014
The TCP/IP stack in the FreeBSD kernel COSCUP 2014The TCP/IP stack in the FreeBSD kernel COSCUP 2014
The TCP/IP stack in the FreeBSD kernel COSCUP 2014Kevin Lo
 
Lua and its Ecosystem
Lua and its EcosystemLua and its Ecosystem
Lua and its Ecosystem
François Perrad
 
Bh Usa 07 Butler And Kendall
Bh Usa 07 Butler And KendallBh Usa 07 Butler And Kendall
Bh Usa 07 Butler And KendallKarlFrank99
 
Operating System Assignment Help
Operating System Assignment HelpOperating System Assignment Help
Operating System Assignment Help
Programming Homework Help
 
Computer Science Homework Help
Computer Science Homework HelpComputer Science Homework Help
Computer Science Homework Help
Programming Homework Help
 
Posix Threads
Posix ThreadsPosix Threads
Posix Threads
Doug Abbott
 

What's hot (16)

Bypassing anti virus scanners
Bypassing anti virus scannersBypassing anti virus scanners
Bypassing anti virus scanners
 
Why Erlang? - Bar Camp Atlanta 2008
Why Erlang?  - Bar Camp Atlanta 2008Why Erlang?  - Bar Camp Atlanta 2008
Why Erlang? - Bar Camp Atlanta 2008
 
Erlang
ErlangErlang
Erlang
 
[Defcon24] Introduction to the Witchcraft Compiler Collection
[Defcon24] Introduction to the Witchcraft Compiler Collection[Defcon24] Introduction to the Witchcraft Compiler Collection
[Defcon24] Introduction to the Witchcraft Compiler Collection
 
Composing and Executing Parallel Data Flow Graphs wth Shell Pipes
Composing and Executing Parallel Data Flow Graphs wth Shell PipesComposing and Executing Parallel Data Flow Graphs wth Shell Pipes
Composing and Executing Parallel Data Flow Graphs wth Shell Pipes
 
PE Packers Used in Malicious Software - Part 1
PE Packers Used in Malicious Software - Part 1PE Packers Used in Malicious Software - Part 1
PE Packers Used in Malicious Software - Part 1
 
Kernel Recipes 2019 - Faster IO through io_uring
Kernel Recipes 2019 - Faster IO through io_uringKernel Recipes 2019 - Faster IO through io_uring
Kernel Recipes 2019 - Faster IO through io_uring
 
Pthreads linux
Pthreads linuxPthreads linux
Pthreads linux
 
Fun with Network Interfaces
Fun with Network InterfacesFun with Network Interfaces
Fun with Network Interfaces
 
The TCP/IP stack in the FreeBSD kernel COSCUP 2014
The TCP/IP stack in the FreeBSD kernel COSCUP 2014The TCP/IP stack in the FreeBSD kernel COSCUP 2014
The TCP/IP stack in the FreeBSD kernel COSCUP 2014
 
Lua and its Ecosystem
Lua and its EcosystemLua and its Ecosystem
Lua and its Ecosystem
 
Bh Usa 07 Butler And Kendall
Bh Usa 07 Butler And KendallBh Usa 07 Butler And Kendall
Bh Usa 07 Butler And Kendall
 
P threads
P threadsP threads
P threads
 
Operating System Assignment Help
Operating System Assignment HelpOperating System Assignment Help
Operating System Assignment Help
 
Computer Science Homework Help
Computer Science Homework HelpComputer Science Homework Help
Computer Science Homework Help
 
Posix Threads
Posix ThreadsPosix Threads
Posix Threads
 

Viewers also liked

Ruby golightly
Ruby golightlyRuby golightly
Ruby golightly
Eleanor McHugh
 
Finding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in goFinding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in go
Eleanor McHugh
 
Anonymity, trust, accountability
Anonymity, trust, accountabilityAnonymity, trust, accountability
Anonymity, trust, accountability
Eleanor McHugh
 
Implementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & CImplementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & C
Eleanor McHugh
 
Going Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with GoGoing Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with Go
Eleanor McHugh
 
Implementing Virtual Machines in Ruby & C
Implementing Virtual Machines in Ruby & CImplementing Virtual Machines in Ruby & C
Implementing Virtual Machines in Ruby & C
Eleanor McHugh
 

Viewers also liked (6)

Ruby golightly
Ruby golightlyRuby golightly
Ruby golightly
 
Finding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in goFinding a useful outlet for my many Adventures in go
Finding a useful outlet for my many Adventures in go
 
Anonymity, trust, accountability
Anonymity, trust, accountabilityAnonymity, trust, accountability
Anonymity, trust, accountability
 
Implementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & CImplementing Virtual Machines in Go & C
Implementing Virtual Machines in Go & C
 
Going Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with GoGoing Loopy: Adventures in Iteration with Go
Going Loopy: Adventures in Iteration with Go
 
Implementing Virtual Machines in Ruby & C
Implementing Virtual Machines in Ruby & CImplementing Virtual Machines in Ruby & C
Implementing Virtual Machines in Ruby & C
 

Similar to The Ruby Plumber's Guide to *nix

MultiThreading in Python
MultiThreading in PythonMultiThreading in Python
MultiThreading in Python
SRINIVAS KOLAPARTHI
 
Intro To .Net Threads
Intro To .Net ThreadsIntro To .Net Threads
Intro To .Net Threads
rchakra
 
Introto netthreads-090906214344-phpapp01
Introto netthreads-090906214344-phpapp01Introto netthreads-090906214344-phpapp01
Introto netthreads-090906214344-phpapp01Aravindharamanan S
 
4.Process.ppt
4.Process.ppt4.Process.ppt
4.Process.ppt
AkfeteAssefa
 
brief intro to Linux device drivers
brief intro to Linux device driversbrief intro to Linux device drivers
brief intro to Linux device drivers
Alexandre Moreno
 
Networking threads
Networking threadsNetworking threads
Networking threads
Nilesh Pawar
 
LXC Containers and AUFs
LXC Containers and AUFsLXC Containers and AUFs
LXC Containers and AUFsDocker, Inc.
 
Unix Shell and System Boot Process
Unix Shell and System Boot ProcessUnix Shell and System Boot Process
Unix Shell and System Boot Process
Arvind Krishnaa
 
Concurrent Programming with Ruby and Tuple Spaces
Concurrent Programming with Ruby and Tuple SpacesConcurrent Programming with Ruby and Tuple Spaces
Concurrent Programming with Ruby and Tuple Spaces
luccastera
 
Operating System Chapter 4 Multithreaded programming
Operating System Chapter 4 Multithreaded programmingOperating System Chapter 4 Multithreaded programming
Operating System Chapter 4 Multithreaded programming
guesta40f80
 
Operating System 4 1193308760782240 2
Operating System 4 1193308760782240 2Operating System 4 1193308760782240 2
Operating System 4 1193308760782240 2mona_hakmy
 
Operating System 4
Operating System 4Operating System 4
Operating System 4tech2click
 
Slot02 concurrency1
Slot02 concurrency1Slot02 concurrency1
Slot02 concurrency1
Viên Mai
 
Here comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdfHere comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdf
Krystian Zybała
 
Linux Programming
Linux ProgrammingLinux Programming
Multithreading by rj
Multithreading by rjMultithreading by rj
Intel Briefing Notes
Intel Briefing NotesIntel Briefing Notes
Intel Briefing Notes
Graham Lee
 

Similar to The Ruby Plumber's Guide to *nix (20)

MultiThreading in Python
MultiThreading in PythonMultiThreading in Python
MultiThreading in Python
 
Intro To .Net Threads
Intro To .Net ThreadsIntro To .Net Threads
Intro To .Net Threads
 
concurrency
concurrencyconcurrency
concurrency
 
Introto netthreads-090906214344-phpapp01
Introto netthreads-090906214344-phpapp01Introto netthreads-090906214344-phpapp01
Introto netthreads-090906214344-phpapp01
 
4.Process.ppt
4.Process.ppt4.Process.ppt
4.Process.ppt
 
brief intro to Linux device drivers
brief intro to Linux device driversbrief intro to Linux device drivers
brief intro to Linux device drivers
 
Networking threads
Networking threadsNetworking threads
Networking threads
 
LXC Containers and AUFs
LXC Containers and AUFsLXC Containers and AUFs
LXC Containers and AUFs
 
Chapter 6 os
Chapter 6 osChapter 6 os
Chapter 6 os
 
Threads
ThreadsThreads
Threads
 
Unix Shell and System Boot Process
Unix Shell and System Boot ProcessUnix Shell and System Boot Process
Unix Shell and System Boot Process
 
Concurrent Programming with Ruby and Tuple Spaces
Concurrent Programming with Ruby and Tuple SpacesConcurrent Programming with Ruby and Tuple Spaces
Concurrent Programming with Ruby and Tuple Spaces
 
Operating System Chapter 4 Multithreaded programming
Operating System Chapter 4 Multithreaded programmingOperating System Chapter 4 Multithreaded programming
Operating System Chapter 4 Multithreaded programming
 
Operating System 4 1193308760782240 2
Operating System 4 1193308760782240 2Operating System 4 1193308760782240 2
Operating System 4 1193308760782240 2
 
Operating System 4
Operating System 4Operating System 4
Operating System 4
 
Slot02 concurrency1
Slot02 concurrency1Slot02 concurrency1
Slot02 concurrency1
 
Here comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdfHere comes the Loom - Ya!vaConf.pdf
Here comes the Loom - Ya!vaConf.pdf
 
Linux Programming
Linux ProgrammingLinux Programming
Linux Programming
 
Multithreading by rj
Multithreading by rjMultithreading by rj
Multithreading by rj
 
Intel Briefing Notes
Intel Briefing NotesIntel Briefing Notes
Intel Briefing Notes
 

More from Eleanor McHugh

[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf
Eleanor McHugh
 
Generics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient CollectionsGenerics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient Collections
Eleanor McHugh
 
The Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data IntegrityThe Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data Integrity
Eleanor McHugh
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
Eleanor McHugh
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's Perspective
Eleanor McHugh
 
Go for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionGo for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd edition
Eleanor McHugh
 
An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]
Eleanor McHugh
 
An introduction to functional programming with go
An introduction to functional programming with goAn introduction to functional programming with go
An introduction to functional programming with go
Eleanor McHugh
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 redux
Eleanor McHugh
 
Identity & trust in Monitored Spaces
Identity & trust in Monitored SpacesIdentity & trust in Monitored Spaces
Identity & trust in Monitored Spaces
Eleanor McHugh
 
Don't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By DesignDon't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By Design
Eleanor McHugh
 
Don't ask, don't tell the virtues of privacy by design
Don't ask, don't tell   the virtues of privacy by designDon't ask, don't tell   the virtues of privacy by design
Don't ask, don't tell the virtues of privacy by design
Eleanor McHugh
 
Anonymity, identity, trust
Anonymity, identity, trustAnonymity, identity, trust
Anonymity, identity, trust
Eleanor McHugh
 
Going Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google GoGoing Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google Go
Eleanor McHugh
 
Distributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at ScaleDistributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at Scale
Eleanor McHugh
 
Hello Go
Hello GoHello Go
Hello Go
Eleanor McHugh
 
Go for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd editionGo for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd edition
Eleanor McHugh
 
Implementing Software Machines in C and Go
Implementing Software Machines in C and GoImplementing Software Machines in C and Go
Implementing Software Machines in C and Go
Eleanor McHugh
 
Implementing Software Machines in Go and C
Implementing Software Machines in Go and CImplementing Software Machines in Go and C
Implementing Software Machines in Go and C
Eleanor McHugh
 
Encrypt all transports
Encrypt all transportsEncrypt all transports
Encrypt all transports
Eleanor McHugh
 

More from Eleanor McHugh (20)

[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf[2023] Putting the R! in R&D.pdf
[2023] Putting the R! in R&D.pdf
 
Generics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient CollectionsGenerics, Reflection, and Efficient Collections
Generics, Reflection, and Efficient Collections
 
The Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data IntegrityThe Relevance of Liveness - Biometrics and Data Integrity
The Relevance of Liveness - Biometrics and Data Integrity
 
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
The Browser Environment - A Systems Programmer's Perspective [sinatra edition]
 
The Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's PerspectiveThe Browser Environment - A Systems Programmer's Perspective
The Browser Environment - A Systems Programmer's Perspective
 
Go for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd editionGo for the paranoid network programmer, 3rd edition
Go for the paranoid network programmer, 3rd edition
 
An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]An introduction to functional programming with Go [redux]
An introduction to functional programming with Go [redux]
 
An introduction to functional programming with go
An introduction to functional programming with goAn introduction to functional programming with go
An introduction to functional programming with go
 
Implementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 reduxImplementing virtual machines in go & c 2018 redux
Implementing virtual machines in go & c 2018 redux
 
Identity & trust in Monitored Spaces
Identity & trust in Monitored SpacesIdentity & trust in Monitored Spaces
Identity & trust in Monitored Spaces
 
Don't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By DesignDon't Ask, Don't Tell - The Virtues of Privacy By Design
Don't Ask, Don't Tell - The Virtues of Privacy By Design
 
Don't ask, don't tell the virtues of privacy by design
Don't ask, don't tell   the virtues of privacy by designDon't ask, don't tell   the virtues of privacy by design
Don't ask, don't tell the virtues of privacy by design
 
Anonymity, identity, trust
Anonymity, identity, trustAnonymity, identity, trust
Anonymity, identity, trust
 
Going Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google GoGoing Loopy - Adventures in Iteration with Google Go
Going Loopy - Adventures in Iteration with Google Go
 
Distributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at ScaleDistributed Ledgers: Anonymity & Immutability at Scale
Distributed Ledgers: Anonymity & Immutability at Scale
 
Hello Go
Hello GoHello Go
Hello Go
 
Go for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd editionGo for the paranoid network programmer, 2nd edition
Go for the paranoid network programmer, 2nd edition
 
Implementing Software Machines in C and Go
Implementing Software Machines in C and GoImplementing Software Machines in C and Go
Implementing Software Machines in C and Go
 
Implementing Software Machines in Go and C
Implementing Software Machines in Go and CImplementing Software Machines in Go and C
Implementing Software Machines in Go and C
 
Encrypt all transports
Encrypt all transportsEncrypt all transports
Encrypt all transports
 

Recently uploaded

FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
Cheryl Hung
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
Paul Groth
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
Product School
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
ThousandEyes
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
Prayukth K V
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
Safe Software
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
Guy Korland
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
Ralf Eggert
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
CatarinaPereira64715
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
Frank van Harmelen
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
DianaGray10
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
91mobiles
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
RTTS
 

Recently uploaded (20)

FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdfFIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
FIDO Alliance Osaka Seminar: Passkeys at Amazon.pdf
 
Key Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdfKey Trends Shaping the Future of Infrastructure.pdf
Key Trends Shaping the Future of Infrastructure.pdf
 
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMsTo Graph or Not to Graph Knowledge Graph Architectures and LLMs
To Graph or Not to Graph Knowledge Graph Architectures and LLMs
 
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
From Siloed Products to Connected Ecosystem: Building a Sustainable and Scala...
 
Assuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyesAssuring Contact Center Experiences for Your Customers With ThousandEyes
Assuring Contact Center Experiences for Your Customers With ThousandEyes
 
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 previewState of ICS and IoT Cyber Threat Landscape Report 2024 preview
State of ICS and IoT Cyber Threat Landscape Report 2024 preview
 
Essentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with ParametersEssentials of Automations: Optimizing FME Workflows with Parameters
Essentials of Automations: Optimizing FME Workflows with Parameters
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
GraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge GraphGraphRAG is All You need? LLM & Knowledge Graph
GraphRAG is All You need? LLM & Knowledge Graph
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)PHP Frameworks: I want to break free (IPC Berlin 2024)
PHP Frameworks: I want to break free (IPC Berlin 2024)
 
ODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User GroupODC, Data Fabric and Architecture User Group
ODC, Data Fabric and Architecture User Group
 
Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*Neuro-symbolic is not enough, we need neuro-*semantic*
Neuro-symbolic is not enough, we need neuro-*semantic*
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4UiPath Test Automation using UiPath Test Suite series, part 4
UiPath Test Automation using UiPath Test Suite series, part 4
 
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdfSmart TV Buyer Insights Survey 2024 by 91mobiles.pdf
Smart TV Buyer Insights Survey 2024 by 91mobiles.pdf
 
JMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and GrafanaJMeter webinar - integration with InfluxDB and Grafana
JMeter webinar - integration with InfluxDB and Grafana
 

The Ruby Plumber's Guide to *nix

  • 1. A Ruby Guide to *nix Plumbing The fun of a little knowledge applied unwisely http://slides.games-with-brains.net
  • 2. presenting Eleanor McHugh eleanor@games-with-brains.com usual haunts include ruby-talk LRUG devchix
  • 3. cowgirl for hire web applications domain names broadcast automation cockpit avionics
  • 4. her goal to make *nix a native of the Ruby environment
  • 5. on the road to perdition “Are you God’s work, or the Devil’s? Oh, what do I care whose work you are? You poor silent creature.” - A Company of Wolves
  • 6. caveat lector danger! we’re entering strange territory our map will be missing some major landmarks and will be riddled with inaccuracies so don’t try this on a live production system and read your man pages thoroughly
  • 7. worse is better the unix philosophy of life
  • 8. it’s smart to be lazy create small tools to solve simple tasks effectively perform each task independently and pass the results from one task to another using a clean interface thus solving complex problems sociably
  • 9. inherently agile only build what you need reuse what you already have change your tools as [des|requ]ired
  • 10. totally punk “if you give people the license to be as outrageous as they want in absolutely any fashion they can dream up, they’ll be creative about it, and do something good besides” - Lester Bangs
  • 11. the unix kernel a ruby perspective
  • 12. basic services virtual memory process management hierarchical file system user permissions interprocess communication signals and interrupts execution environment
  • 13. anatomy of a process program instructions program data system data (file descriptors, user, group, parent, etc.) environment data supports one or more threads of execution preemptively scheduled by the kernel
  • 14. process creation a process may spawn child processes via fork() this creates a duplicate child process with duplicate file descriptors and program state which can be replaced via exec() of a new program all processes ultimately derive from the init process which is created by the kernel at boot
  • 15. a costly strategy sometimes we only want a blank slate process but fork() copies the full process state so BSD introduced vfork() which shares data memory whilst POSIX introduced spawn() most fork() implementations now use copy-on-write so the advantages of vfork() have diminished
  • 16. with certain limitations only the thread which forks will be in the child process a green threads system can work around this although Ruby 1.8 doesn’t seem to it’s also possible for exec() to fail so forked processes need to guard for this
  • 17. and a taste for brains a zombie is a subprocess which outlives its parent zombies are members of the system process group and are eventually terminated but until then they retain resources and may not flush all of their IO buffers
  • 18. Kernel.system [env ,] cmnd [, args] [, options] => true or false or nil Kernel.spawn [env ,] cmnd [, args] [, options] => pid The simplest way to take advantage of multiple processes in Ruby is to launch a subshell and either block until it terminates or keep a note of its process ID so this can be checked later. This is an opaque method and not useful when the parent process wishes to capture results. IO.` cmd ` => string The next step up in utility from system() and spawn(), the backquote method captures standard output from the subshell and as a bonus stores a Process::Status object in the thread-global $? variable.
  • 19. IO.popen cmd [, mode = quot;rquot;] => io IO.popen cmd [, mode = quot;rquot; [{ | io | block }] => obj Invokes a command shell in a subprocess and executes the specified commands, providing a [uni|bi]directional pipe which the parent process can use to communicate with the subprocess. Open3.popen3 cmd [{ |stdin, stdout, stderr| block }] Open3.popen3 cmd => array A wrapper for spawn() which provides access to the standard IO streams of the subshell along with a thread waiting on it.
  • 20. Kernel.fork [{ block }] => fixnum or nil Process.fork [{ block }] => fixnum or nil Ruby provides its own fork() implementation which can either take a block and run it in a subprocess, or can allow a more traditional split in execution paths. No IPC mechanism is provided beyond allowing the parent to wait on the child process and receive an error code. Kernel.exec [env ,] cmnd [, args] [, options] And as you’d expect it also allows access to the exec() family of system calls. This is a rare core library methods which doesn’t return a value for the simple reason that the existing program ceases to exist unless an error occurs, and that’s flagged with a SystemCallError exception. It’s common practice to terminate the program or retry exec() after a delay.
  • 21. file descriptors the kernel keeps a table of open files for each process an integer index is used to reference entries and is known as a file descriptor unix is liberal about what counts as a file and most descriptors are inherited by child processes
  • 22. beware the subtleties file descriptors are unique to a process so closing a descriptor only affects that process but the underlying descriptions are shared performing an lseek() changes the description and can therefore affect other processes with much hilarity ensuing...
  • 23. IO.sysopen path [, mode [, perm] => fixnum io.sysread int [, buffer] => string io.syswrite string => int io.sysseek offset, whence = SEEK_SET => int These methods make direct calls to the kernel to open and manipulate the contents of files, bypassing buffering. They shouldn’t be used with higher-level methods such as IO#read as unpredictable results may occur. Errors are raised as Exceptions in the Errno namespace.
  • 24. IO.new fd [, mode] [, opt] => io IO.for_fd fd [, mode] [, opt] => io Returns a new IO object (a stream) for the given IO object or integer file descriptor and mode string. See also IO#fileno and IO.for_fd. a = IO.new(2,quot;wquot;) # '2' is standard error $stderr.puts quot;Helloquot; a.puts quot;Worldquot; produces: Hello World
  • 25. require 'fcntl' filemode = Fcntl::O_CREAT | Fcntl::O_RDWR | Fcntl::O_APPEND descriptor = IO.sysopen “test.dat”, filemode file = IO.for_fd descriptor file.syswrite “hello” file.sysseek 0 file.sysread 10 produces: hello
  • 26. handling many files at once file access is much slower than memory access this causes threads and processes to block so usually IO is buffered by the kernel and non-blocking access methods are implemented however this is still ineffient when writing servers
  • 27. select rd_ary [, wrt_ary] [, err_ary] [, timeout] => array or nil Select is the standard low-level method for polling many IO streams at once and it’s a blocking call, hence the need for a timeout. For writing socket servers etc. this usually works reasonably well and Ruby’s implementation plays nicely with threads.
  • 28. kernel eventing allows the kernel to raise events for streams a process can then poll for events without blocking on BSD this is handled by kqueue on Linux by epoll and inotify epoll is much more efficient that inotify EventMachine makes use of whichever it can find
  • 29. Interprocess Communication IPC objects have descriptors like files but they don’t need to exist in the file system POSIX and System V interfaces System V uses keys to identify IPC objects keys can be generated from paths using ftok() POSIX uses paths to identify IPC objects
  • 30. pipes provides a pair of end-points for processes to talk an unnamed pipe connects related processes a named pipe is like a file it has user permissions and can be accessed by unrelated processes
  • 31. IO.pipe => read_file, write_file Ruby supports anonymous pipes, which can be used to communicate between a parent a child process, taking advantage of the fact that the file descriptors for the end-points will exist across a fork(). Good practice is for the parent process to close the reading end of the pipe whilst the child closes the writing end as soon as they return from fork() and the child should also close the reading end before it terminates to ensure buffered data is properly flushed.
  • 32. sockets ruby has excellent support for sockets use it unless you need kernel level eventing
  • 33. signals wrapped nicely by the Signal class with support for signal handlers
  • 34. shared memory a single defined region of virtual memory can be mapped into many different processes each of which can modify it this offers a flexible form of IPC but to be effective requires synchronisation ruby has no direct support for shared memory
  • 35. semaphores exist independently of processes ruby has no direct support for semaphores but later we’ll see how to use them anyway
  • 37. from the docs Kernel#syscall fixnum [, args...] => integer Calls the operating system function identified by fixnum, passing in the arguments, which must be either String objects, or Integer objects that ultimately fit within a native long. Up to nine parameters may be passed (14 on the Atari-ST). The function identified by fixnum is system dependent. On some Unix systems, the numbers may be obtained from a header file called syscall.h. syscall 4, 1, “hellon”, 6 # ‘4’ is write(2) on our box produces: hello
  • 38. finding your syscall codes MacOS X /usr/include/sys/syscall.h Linux /usr/include/asm/unistd_32.h /usr/include/asm/unistd_64.h
  • 39. a fragile approach the native syscall is a very primitive interface error codes file descriptors & pointer addresses modifiable buffers ruby syscall doesn’t support modifiable buffers but it does wrap errors as Errno exceptions
  • 40. IO.sysx the hard way On MacOS X file = syscall 5, “test.dat”, 1 # open O_WRONLY (fcntl.h) syscall 4, file, “some textn”, 10 # write syscall 3, file, “”, 5 # read syscall 6, file # close produces: Errno::EFAULT: Bad address should be Errno::EBADF
  • 41. posix semaphores process 1 process 2 require ‘fcntl’ Open, Wait, TryWait, Post = 268, 271, 272, 273 Open, Wait, Post, Close = 268, 271, 273, 269 s = syscall Open, “/tmp/s” s = syscall Open, “/tmp/s”, Fcntl::O_CREAT, 1911 begin syscall Wait, s t = Time.now puts “locked at #{Time.now}” syscall TryWait, s sleep 50 puts “locked at #{t}” puts “posted at #{Time.now}” rescue Exception => e syscall Post, s puts “busy at #{t}” syscall Close, s syscall Wait, s puts “waited #{Time.now - t} seconds” end produces: produces: locked at Thu May 28 01:03:23 +0100 2009 busy at Thu May 28 01:03:36 +0100 2009 posted at Thu May 28 01:04:13 +0100 2009 waited 47.056508 seconds
  • 42. complex parameters some kernel calls accept structured data types ruby represents these as String objects which can be prepared with Array#pack Joel VanderWerf’s bit-struct library both approaches allow embedded nulls but on 1.9 remember to use 8-bit ASCII encoding
  • 43. except when they don’t On Ruby 1.8.7 or 1.9.1 (upto patch 129) syscall 4, 1, “hellon#{0.chr}goodbyen”, 15 produces: ArgumentError: string contains null byte from (irb):1:in `syscall' from (irb):1 from /usr/local/bin/irb19:12:in `<main>' This should be fixed in patch 130.
  • 45. ruby/dl part of the standard library since ruby 1.8 access to dynamically loaded libraries .dll on windows .so and .dylib on unix supports C-style memory access and callback functions written in Ruby
  • 46. require ‘dl’ libc = DL.dlopen(‘libc.dylib’) open = libc[‘syscall’, ‘IISI’] write = libc[‘syscall’, ‘IIISI’] read = libc[‘syscall’, ‘IIIsI’] close = libc[‘syscall’, ‘III’] produces: file = open.call 5, “test.dat”, 1 [3, [5, quot;test.datquot;, 1]] write.call 4, file[0], “textn”, 5 [5, [4, 3, quot;textnquot;, 5]] close.call 6, file[0] [0, [6, 3]] file = open.call 5, “test.dat”, 0 [3, [5, quot;test.datquot;, 0]] buffer = DL.malloc(10) read.call(3, file[0], buffer, 10) [5, [3, 3, quot;textnquot;, 10]] close.call 6, file[0] [0, [6, 3]]
  • 47. require ‘dl’ file = open “test.dat”, 0x0209 CRT = DL.dlopen ‘libc.dylib’ write file, “textn” F = ‘syscall’ close file def open file, mode file = open “test.dat”, 0x0000 CRT[F, ‘IISI’].call(5, file, mode)[0] text = read file, 10 end close file def write fd, string, bytes = string.length CRT[F, ‘IIISI’].call(4, fd, string, bytes)[0] end def read fd, bytes = 1 buffer = DL.malloc(bytes) CRT[F, ‘IIIsI’].call(3, fd, buffer, bytes)[1][2] end def close fd CRT[F, ‘III’].call(6, fd)[0] end
  • 48. memory management memory pointers encapsulated by DL::PtrData garbage collected uses free() or a custom deallocator handles realloc() automatically plays nicely with ruby strings and arrays [String|Array].to_ptr PtrData.struct! and PtrData.union!
  • 51. always stray from the path... “And that’s all I’ll tell you, cause that’s all I know.” - A Company of Wolves