SlideShare a Scribd company logo
Unix Programming with Perl Cybozu Labs, Inc. Kazuho Oku
Writing correct code tests aren’t enough tests don’t ensure that the code is correct writing correct code requires… knowledge of perl  and  knowledge of the OS the presentation covers the ascpects of unix programming using perl, including errno fork and filehandles Unix signals Oct 16 2010 Unix Programming with Perl
Errno Oct 16 2010 Unix Programming with Perl
The right way to “create a dir if not exists” Is this OK? if (! -d $dir) { mkdir $dir or die "failed to create dir:$dir:$!"; } Oct 16 2010 Unix Programming with Perl
The right way to “create a dir if not exists” (2) No! if (! -d $dir) { # what if another process created a dir # while we are HERE? mkdir $dir or die "failed to create dir:$dir:$!"; } Oct 16 2010 Unix Programming with Perl
The right way to “create a dir if not exists” (3) The right way is to check the cause of the error when mkdir fails Oct 16 2010 Unix Programming with Perl
The right way to “create a dir if not exists” (4) So, is this OK? if (mkdir $dir) { # ok, dir created } elsif ($! =~ /File exists/) { # ok, directory exists } else { die "failed to create dir:$dir:$!"; } Oct 16 2010 Unix Programming with Perl
The right way to “create a dir if not exists” (5) No! The message stored in $! depends on OS and / or locale. if (mkdir $dir) { # ok, dir created } elsif ($! =~ /File exists/) { # ok, directory exists } else { die "failed to create dir:$dir:$!"; } Oct 16 2010 Unix Programming with Perl
The right way to “create a dir if not exists” (6) The right way is to use Errno. use Errno (); if (mkdir $dir) { # ok, created dir } elsif ($! == Errno::EEXIST) { # ok, already exists } else { die "failed to create dir:$dir:$!"; } Oct 16 2010 Unix Programming with Perl
$! and Errno $! is a  dualvar is a number in numeric context (ex. 17) equiv. to the  errno  global in C is a string in string context (ex. “File exists”) equiv. to  strerror(errno)  in C the Errno module list of constants (numbers) that errno ($! in numeric context) may take Oct 16 2010 Unix Programming with Perl
How to find the Errnos perldoc -f mkdir  doesn’t include a list of errnos it might return see  man 2 mkdir man mkdir  will show the man page of the mkdir command specify section 2 for system calls specify section 3 for C library calls Oct 16 2010 Unix Programming with Perl
How to find the Errnos errnos on man include those defined by POSIX and OS-specific constants the POSIX spec. can be found at opengroup.org, etc. http://www.opengroup.org/onlinepubs/000095399/ Oct 16 2010 Unix Programming with Perl
Fork and filehandles Oct 16 2010 Unix Programming with Perl
Filehandles aren’t cloned by fork fork clones the memory image uses CoW (Copy-on-Write) for optimization fork does  not  clone file handles only increments the refcount to the file handle in the OS the file is left open until both the parent and child closes the file seek position and lock states are shared between the processes the same for TCP / UDP sockets Oct 16 2010 Unix Programming with Perl
File handles aren’t cloned by fork (2) Oct 16 2010 Unix Programming with Perl memory Parent Process Operating System File System lock owner, etc. File memory Another Process memory Child Process fork seek pos. / lock state, etc. File Control Info. open(file) seek pos. / lock state, etc. File Control Info. open(file)
Examples of resource collisions due to fork FAQ “ The SQLite database becomes corrupt” “ MySQL reports malformed packet” mostly due to sharing a single DBI connection created  before  calling fork SQLite uses file locks for access control file lock needed for each process, however after fork the lock is shared between the processes in the case of MySQL a single TCP (or unix) connection is shared between the processes Oct 16 2010 Unix Programming with Perl
Examples of resource collisions due to fork (2) The wrong code… my $dbh = DBI->connect(...); my $pid = fork; if ($pid == 0) { # child process $dbi->do(...); } else { # parent process $dbi->do(...); Oct 16 2010 Unix Programming with Perl
How to avoid resource collisions after fork close the file handle in the child process (or in the parent) right after fork only the refcount will be decremented.  lock states / seek positions do not change Oct 16 2010 Unix Programming with Perl
How to avoid collisions after fork (DBI) undef $dbh  in the child process doesn’t work since the child process will run things such as unlocking and / or rollbacks on the shared DBI connection the connection needs to be closed, without running such operations Oct 16 2010 Unix Programming with Perl
How to avoid collisions after fork (DBI) (2) the answer: use InactiveDestroy my $pid = fork; if ($pid == 0) { # child process $dbh->{InactiveDestroy} = 1; undef $dbh; ... } Oct 16 2010 Unix Programming with Perl
How to avoid collisions after fork (DBI) (3) if fork is called deep inside a module and can’t be modified, then… # thanks to tokuhirom, kazeburo BEGIN { no strict qw(refs); no warnings qw(redefine); *CORE::GLOBAL::fork = sub { my $pid = CORE::fork; if ($pid == 0) { # do the cleanup for child process $dbh->{InactiveDestroy} = 1; undef $dbh; } $pid; }; } Oct 16 2010 Unix Programming with Perl
How to avoid collisions after fork (DBI) (4) other ways to change the behavior of fork POSIX::AtFork (gfx) Perl wrapper for pthread_atfork can change the behavior of fork(2) called within XS forks.pm (rybskej) Oct 16 2010 Unix Programming with Perl
Close filehandles before calling exec file handles (file descriptors) are passed to the new process created by exec some tools (setlock of daemontools, Server::Starter) rely on the feature OTOH, it is a good practice to close the file handles that needn’t be passed to the exec’ed process, to avoid child process from accidentially using them Oct 16 2010 Unix Programming with Perl
Close file handles before calling exec (2) my $pid = fork; if ($pid == 0) { # child process, close filehandles $dbh->{InactiveDestroy} = 1; undef $dbh; exec ...; ... Oct 16 2010 Unix Programming with Perl
Close file handles before calling exec (3) Some OS’es have O_CLOEXEC flag designates the file descriptors to be closed when exec(2) is being called is OS-dependent linux supports the flag, OSX doesn’t not usable from perl? Oct 16 2010 Unix Programming with Perl
Unix Signals Oct 16 2010 Unix Programming with Perl
SIGPIPE “ my network application suddenly dies without saying anything” often due to not catching SIGPIPE a signal sent when failing to write to a filehandle ex. when the socket is closed by peer the default behavior is to kill the process solution: $SIG{PIPE} = 'IGNORE'; downside: you should consult the return value of print, etc. to check if the writes succeeded Oct 16 2010 Unix Programming with Perl
Using alarm alarm can be used (together with SIG{ALRM}, EINTR) to handle timeouts local $SIG{ALRM} = sub {}; alarm($timeout); my $len = $sock->read(my $buf, $maxlen); if (! defined($len) && $! == Errno::EINTR) { warn 'timeout’; return; } Oct 16 2010 Unix Programming with Perl
Pros and cons of using alarm + can be used to timeout almost all system calls (that may block) −  the timeout set by alarm(2) is a process-wide global (and so is $SIG{ALRM}) use of select (or IO::Select) is preferable for network access Oct 16 2010 Unix Programming with Perl
Writing cancellable code typical use-case: run forever until receiving a signal, and gracefully shutdown ex. Gearman::Worker Oct 16 2010 Unix Programming with Perl
Writing cancellable code (2) make your module cancellable -  my $len = $sock->read(my $buf, $maxlen); +  my $len; +  { +  $len = $sock->read(my $buf, $maxlen); +  if (! defined($len) && $! == Errno::EINTR) { +  return if $self->{cancel_requested}; +  redo; +  } +  } ... + sub request_cancel { +  my $self = shift; +  $self->{cancel_requested} = 1; + }  Oct 16 2010 Unix Programming with Perl
Writing cancellable code (3) The code that cancels the operation on SIGTERM $SIG{TERM} = sub { $my_module->request_cancel }; $my_module->run_forever(); Or the caller may use alarm to set timeout $SIG{ALRM} = sub { $my_module->request_cancel }; alarm(100); $my_module->run_forever(); Oct 16 2010 Unix Programming with Perl
Proc::Wait3 built-in wait() and waitpid() does not return when receiving signals use Proc::Wait3 instead Oct 16 2010 Unix Programming with Perl
Further reading Oct 16 2010 Unix Programming with Perl
Further reading this presentation is based on my memo for an article on WEB+DB PRESS if you have any questions, having problems on Unix programming, please let me know Oct 16 2010 Unix Programming with Perl

More Related Content

What's hot (20)

PDF
Quick start bash script
Simon Su
 
PPTX
Penetration testing using python
Purna Chander K
 
PDF
Shell scripting
Geeks Anonymes
 
ODP
Perl one-liners
daoswald
 
PDF
Shell scripting
Manav Prasad
 
PDF
Devinsampa nginx-scripting
Tony Fabeen
 
PDF
various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)
CODE BLUE
 
DOCX
Quize on scripting shell
lebse123
 
PPT
Unix 5 en
Simonas Kareiva
 
PDF
Shell Script
Adam Victor Brandizzi
 
ODP
Clojure: Practical functional approach on JVM
sunng87
 
ODP
Programming Under Linux In Python
Marwan Osman
 
PDF
PHP Internals and Virtual Machine
julien pauli
 
PPTX
Shell & Shell Script
Amit Ghosh
 
KEY
Yapcasia2011 - Hello Embed Perl
Hideaki Ohno
 
DOCX
32 shell-programming
kayalkarnan
 
PDF
Redis & ZeroMQ: How to scale your application
rjsmelo
 
PPTX
Shell Script Tutorial
Quang Minh Đoàn
 
PPTX
Unix shell scripts
Prakash Lambha
 
ODP
OpenGurukul : Language : Shell Scripting
Open Gurukul
 
Quick start bash script
Simon Su
 
Penetration testing using python
Purna Chander K
 
Shell scripting
Geeks Anonymes
 
Perl one-liners
daoswald
 
Shell scripting
Manav Prasad
 
Devinsampa nginx-scripting
Tony Fabeen
 
various tricks for remote linux exploits  by Seok-Ha Lee (wh1ant)
CODE BLUE
 
Quize on scripting shell
lebse123
 
Unix 5 en
Simonas Kareiva
 
Shell Script
Adam Victor Brandizzi
 
Clojure: Practical functional approach on JVM
sunng87
 
Programming Under Linux In Python
Marwan Osman
 
PHP Internals and Virtual Machine
julien pauli
 
Shell & Shell Script
Amit Ghosh
 
Yapcasia2011 - Hello Embed Perl
Hideaki Ohno
 
32 shell-programming
kayalkarnan
 
Redis & ZeroMQ: How to scale your application
rjsmelo
 
Shell Script Tutorial
Quang Minh Đoàn
 
Unix shell scripts
Prakash Lambha
 
OpenGurukul : Language : Shell Scripting
Open Gurukul
 

Viewers also liked (20)

PDF
H2O - the optimized HTTP server
Kazuho Oku
 
PDF
Reorganizing Website Architecture for HTTP/2 and Beyond
Kazuho Oku
 
PDF
HTTP/2の課題と将来
Kazuho Oku
 
PPT
Webアプリケーションの無停止稼働
Kazuho Oku
 
PPTX
JSX 速さの秘密 - 高速なJavaScriptを書く方法
Kazuho Oku
 
PPTX
例えば牛丼を避ける
Kazuho Oku
 
PDF
H2O - making HTTP better
Kazuho Oku
 
PDF
Developing the fastest HTTP/2 server
Kazuho Oku
 
PDF
ウェブブラウザの時代は終わるのか 〜スマホアプリとHTML5の未来〜
Kazuho Oku
 
PPT
ウェブアーキテクチャの歴史と未来
Kazuho Oku
 
PPTX
illumos day 2014 SMB2
gordonross
 
PDF
German Perl Workshop 2015 - Infrastruktur als Code
Jan Gehring
 
PPT
A Practical Event Driven Model
Xi Wu
 
PDF
Gearinfive
bpmedley
 
PDF
Distribute the workload, PHPTek, Amsterdam, 2011
Helgi Þormar Þorbjörnsson
 
PDF
Apress.html5.and.java script.projects.oct.2011
Samuel K. Itotia
 
ODP
Introducing Modern Perl
Dave Cross
 
ODP
perl usage at database applications
Joe Jiang
 
PDF
Gearman
Jui-Nan Lin
 
PDF
Dbi Advanced Talk 200708
oscon2007
 
H2O - the optimized HTTP server
Kazuho Oku
 
Reorganizing Website Architecture for HTTP/2 and Beyond
Kazuho Oku
 
HTTP/2の課題と将来
Kazuho Oku
 
Webアプリケーションの無停止稼働
Kazuho Oku
 
JSX 速さの秘密 - 高速なJavaScriptを書く方法
Kazuho Oku
 
例えば牛丼を避ける
Kazuho Oku
 
H2O - making HTTP better
Kazuho Oku
 
Developing the fastest HTTP/2 server
Kazuho Oku
 
ウェブブラウザの時代は終わるのか 〜スマホアプリとHTML5の未来〜
Kazuho Oku
 
ウェブアーキテクチャの歴史と未来
Kazuho Oku
 
illumos day 2014 SMB2
gordonross
 
German Perl Workshop 2015 - Infrastruktur als Code
Jan Gehring
 
A Practical Event Driven Model
Xi Wu
 
Gearinfive
bpmedley
 
Distribute the workload, PHPTek, Amsterdam, 2011
Helgi Þormar Þorbjörnsson
 
Apress.html5.and.java script.projects.oct.2011
Samuel K. Itotia
 
Introducing Modern Perl
Dave Cross
 
perl usage at database applications
Joe Jiang
 
Gearman
Jui-Nan Lin
 
Dbi Advanced Talk 200708
oscon2007
 
Ad

Similar to Unix Programming with Perl (20)

PDF
Confraria SECURITY & IT - Lisbon Set 29, 2011
ricardomcm
 
PPTX
Confraria Security & IT - Lisbon Set 29, 2011
ricardomcm
 
PDF
Operating System Lecture Notes Mit 6828 Itebooks
eelmaatohura
 
PPT
PHP CLI: A Cinderella Story
Mike Lively
 
PDF
Introduction to Rust - Waterford Tech Meetup 2025
John Rellis
 
PDF
Jordan Hubbard Talk @ LISA
guest4c923d
 
PDF
Introduction to shell scripting
Corrado Santoro
 
PPT
Bioinformatica 29-09-2011-p1-introduction
Prof. Wim Van Criekinge
 
PPTX
Linux Systems Programming: Inter Process Communication (IPC) using Pipes
RashidFaridChishti
 
PDF
Farewell to Disks: Efficient Processing of Obstinate Data
Distinguished Lecturer Series - Leon The Mathematician
 
PPT
Linux basics
sirmanohar
 
PPT
02 fundamentals
sirmanohar
 
PDF
Perl for System Automation - 01 Advanced File Processing
Danairat Thanabodithammachari
 
PDF
44CON London 2015 - 15-Minute Linux Incident Response Live Analysis
44CON
 
PPTX
2015 555 kharchenko_ppt
Maxym Kharchenko
 
PDF
Filip palian mateuszkocielski. simplest ownage human observed… routers
Yury Chemerkin
 
PDF
Simplest-Ownage-Human-Observed… - Routers
Logicaltrust pl
 
PDF
Let's Talk Locks!
C4Media
 
PDF
Will iPython replace bash?
Roberto Polli
 
Confraria SECURITY & IT - Lisbon Set 29, 2011
ricardomcm
 
Confraria Security & IT - Lisbon Set 29, 2011
ricardomcm
 
Operating System Lecture Notes Mit 6828 Itebooks
eelmaatohura
 
PHP CLI: A Cinderella Story
Mike Lively
 
Introduction to Rust - Waterford Tech Meetup 2025
John Rellis
 
Jordan Hubbard Talk @ LISA
guest4c923d
 
Introduction to shell scripting
Corrado Santoro
 
Bioinformatica 29-09-2011-p1-introduction
Prof. Wim Van Criekinge
 
Linux Systems Programming: Inter Process Communication (IPC) using Pipes
RashidFaridChishti
 
Farewell to Disks: Efficient Processing of Obstinate Data
Distinguished Lecturer Series - Leon The Mathematician
 
Linux basics
sirmanohar
 
02 fundamentals
sirmanohar
 
Perl for System Automation - 01 Advanced File Processing
Danairat Thanabodithammachari
 
44CON London 2015 - 15-Minute Linux Incident Response Live Analysis
44CON
 
2015 555 kharchenko_ppt
Maxym Kharchenko
 
Filip palian mateuszkocielski. simplest ownage human observed… routers
Yury Chemerkin
 
Simplest-Ownage-Human-Observed… - Routers
Logicaltrust pl
 
Let's Talk Locks!
C4Media
 
Will iPython replace bash?
Roberto Polli
 
Ad

More from Kazuho Oku (20)

PDF
HTTP/2で 速くなるとき ならないとき
Kazuho Oku
 
PDF
QUIC標準化動向 〜2017/7
Kazuho Oku
 
PDF
TLS 1.3 と 0-RTT のこわ〜い話
Kazuho Oku
 
PPTX
Recent Advances in HTTP, controlling them using ruby
Kazuho Oku
 
PPTX
Programming TCP for responsiveness
Kazuho Oku
 
PDF
Programming TCP for responsiveness
Kazuho Oku
 
PPTX
TLS & LURK @ IETF 95
Kazuho Oku
 
PPTX
HTTPとサーバ技術の最新動向
Kazuho Oku
 
PPTX
ウェブを速くするためにDeNAがやっていること - HTTP/2と、さらにその先
Kazuho Oku
 
PPTX
Cache aware-server-push in H2O version 1.5
Kazuho Oku
 
PDF
HTTP/2時代のウェブサイト設計
Kazuho Oku
 
PDF
H2O - making the Web faster
Kazuho Oku
 
PPTX
JSON SQL Injection and the Lessons Learned
Kazuho Oku
 
PPTX
JSX の現在と未来 - Oct 26 2013
Kazuho Oku
 
PDF
JSX - 公開から1年を迎えて
Kazuho Oku
 
PDF
JSX - developing a statically-typed programming language for the Web
Kazuho Oku
 
PPTX
JSX
Kazuho Oku
 
PPTX
JSX Optimizer
Kazuho Oku
 
PPTX
JSX Design Overview (日本語)
Kazuho Oku
 
PPTX
JSX
Kazuho Oku
 
HTTP/2で 速くなるとき ならないとき
Kazuho Oku
 
QUIC標準化動向 〜2017/7
Kazuho Oku
 
TLS 1.3 と 0-RTT のこわ〜い話
Kazuho Oku
 
Recent Advances in HTTP, controlling them using ruby
Kazuho Oku
 
Programming TCP for responsiveness
Kazuho Oku
 
Programming TCP for responsiveness
Kazuho Oku
 
TLS & LURK @ IETF 95
Kazuho Oku
 
HTTPとサーバ技術の最新動向
Kazuho Oku
 
ウェブを速くするためにDeNAがやっていること - HTTP/2と、さらにその先
Kazuho Oku
 
Cache aware-server-push in H2O version 1.5
Kazuho Oku
 
HTTP/2時代のウェブサイト設計
Kazuho Oku
 
H2O - making the Web faster
Kazuho Oku
 
JSON SQL Injection and the Lessons Learned
Kazuho Oku
 
JSX の現在と未来 - Oct 26 2013
Kazuho Oku
 
JSX - 公開から1年を迎えて
Kazuho Oku
 
JSX - developing a statically-typed programming language for the Web
Kazuho Oku
 
JSX Optimizer
Kazuho Oku
 
JSX Design Overview (日本語)
Kazuho Oku
 

Recently uploaded (20)

PPTX
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
PDF
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
PPTX
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
PPTX
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
PDF
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
PDF
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
PDF
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
PDF
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
PDF
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
PDF
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
PPTX
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
PDF
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
PDF
Log-Based Anomaly Detection: Enhancing System Reliability with Machine Learning
Mohammed BEKKOUCHE
 
PDF
Python basic programing language for automation
DanialHabibi2
 
PDF
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
PDF
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
PPTX
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
PDF
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
PPTX
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
PDF
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 
AI Penetration Testing Essentials: A Cybersecurity Guide for 2025
defencerabbit Team
 
Building Real-Time Digital Twins with IBM Maximo & ArcGIS Indoors
Safe Software
 
OpenID AuthZEN - Analyst Briefing July 2025
David Brossard
 
UiPath Academic Alliance Educator Panels: Session 2 - Business Analyst Content
DianaGray10
 
NewMind AI - Journal 100 Insights After The 100th Issue
NewMind AI
 
Newgen 2022-Forrester Newgen TEI_13 05 2022-The-Total-Economic-Impact-Newgen-...
darshakparmar
 
CIFDAQ Market Insights for July 7th 2025
CIFDAQ
 
Exolore The Essential AI Tools in 2025.pdf
Srinivasan M
 
CIFDAQ Token Spotlight for 9th July 2025
CIFDAQ
 
Agentic AI lifecycle for Enterprise Hyper-Automation
Debmalya Biswas
 
"Autonomy of LLM Agents: Current State and Future Prospects", Oles` Petriv
Fwdays
 
HCIP-Data Center Facility Deployment V2.0 Training Material (Without Remarks ...
mcastillo49
 
Log-Based Anomaly Detection: Enhancing System Reliability with Machine Learning
Mohammed BEKKOUCHE
 
Python basic programing language for automation
DanialHabibi2
 
Fl Studio 24.2.2 Build 4597 Crack for Windows Free Download 2025
faizk77g
 
[Newgen] NewgenONE Marvin Brochure 1.pdf
darshakparmar
 
AUTOMATION AND ROBOTICS IN PHARMA INDUSTRY.pptx
sameeraaabegumm
 
Empower Inclusion Through Accessible Java Applications
Ana-Maria Mihalceanu
 
Building Search Using OpenSearch: Limitations and Workarounds
Sease
 
Transcript: New from BookNet Canada for 2025: BNC BiblioShare - Tech Forum 2025
BookNet Canada
 

Unix Programming with Perl

  • 1. Unix Programming with Perl Cybozu Labs, Inc. Kazuho Oku
  • 2. Writing correct code tests aren’t enough tests don’t ensure that the code is correct writing correct code requires… knowledge of perl and knowledge of the OS the presentation covers the ascpects of unix programming using perl, including errno fork and filehandles Unix signals Oct 16 2010 Unix Programming with Perl
  • 3. Errno Oct 16 2010 Unix Programming with Perl
  • 4. The right way to “create a dir if not exists” Is this OK? if (! -d $dir) { mkdir $dir or die "failed to create dir:$dir:$!"; } Oct 16 2010 Unix Programming with Perl
  • 5. The right way to “create a dir if not exists” (2) No! if (! -d $dir) { # what if another process created a dir # while we are HERE? mkdir $dir or die "failed to create dir:$dir:$!"; } Oct 16 2010 Unix Programming with Perl
  • 6. The right way to “create a dir if not exists” (3) The right way is to check the cause of the error when mkdir fails Oct 16 2010 Unix Programming with Perl
  • 7. The right way to “create a dir if not exists” (4) So, is this OK? if (mkdir $dir) { # ok, dir created } elsif ($! =~ /File exists/) { # ok, directory exists } else { die "failed to create dir:$dir:$!"; } Oct 16 2010 Unix Programming with Perl
  • 8. The right way to “create a dir if not exists” (5) No! The message stored in $! depends on OS and / or locale. if (mkdir $dir) { # ok, dir created } elsif ($! =~ /File exists/) { # ok, directory exists } else { die "failed to create dir:$dir:$!"; } Oct 16 2010 Unix Programming with Perl
  • 9. The right way to “create a dir if not exists” (6) The right way is to use Errno. use Errno (); if (mkdir $dir) { # ok, created dir } elsif ($! == Errno::EEXIST) { # ok, already exists } else { die "failed to create dir:$dir:$!"; } Oct 16 2010 Unix Programming with Perl
  • 10. $! and Errno $! is a dualvar is a number in numeric context (ex. 17) equiv. to the errno global in C is a string in string context (ex. “File exists”) equiv. to strerror(errno) in C the Errno module list of constants (numbers) that errno ($! in numeric context) may take Oct 16 2010 Unix Programming with Perl
  • 11. How to find the Errnos perldoc -f mkdir doesn’t include a list of errnos it might return see man 2 mkdir man mkdir will show the man page of the mkdir command specify section 2 for system calls specify section 3 for C library calls Oct 16 2010 Unix Programming with Perl
  • 12. How to find the Errnos errnos on man include those defined by POSIX and OS-specific constants the POSIX spec. can be found at opengroup.org, etc. http://www.opengroup.org/onlinepubs/000095399/ Oct 16 2010 Unix Programming with Perl
  • 13. Fork and filehandles Oct 16 2010 Unix Programming with Perl
  • 14. Filehandles aren’t cloned by fork fork clones the memory image uses CoW (Copy-on-Write) for optimization fork does not clone file handles only increments the refcount to the file handle in the OS the file is left open until both the parent and child closes the file seek position and lock states are shared between the processes the same for TCP / UDP sockets Oct 16 2010 Unix Programming with Perl
  • 15. File handles aren’t cloned by fork (2) Oct 16 2010 Unix Programming with Perl memory Parent Process Operating System File System lock owner, etc. File memory Another Process memory Child Process fork seek pos. / lock state, etc. File Control Info. open(file) seek pos. / lock state, etc. File Control Info. open(file)
  • 16. Examples of resource collisions due to fork FAQ “ The SQLite database becomes corrupt” “ MySQL reports malformed packet” mostly due to sharing a single DBI connection created before calling fork SQLite uses file locks for access control file lock needed for each process, however after fork the lock is shared between the processes in the case of MySQL a single TCP (or unix) connection is shared between the processes Oct 16 2010 Unix Programming with Perl
  • 17. Examples of resource collisions due to fork (2) The wrong code… my $dbh = DBI->connect(...); my $pid = fork; if ($pid == 0) { # child process $dbi->do(...); } else { # parent process $dbi->do(...); Oct 16 2010 Unix Programming with Perl
  • 18. How to avoid resource collisions after fork close the file handle in the child process (or in the parent) right after fork only the refcount will be decremented. lock states / seek positions do not change Oct 16 2010 Unix Programming with Perl
  • 19. How to avoid collisions after fork (DBI) undef $dbh in the child process doesn’t work since the child process will run things such as unlocking and / or rollbacks on the shared DBI connection the connection needs to be closed, without running such operations Oct 16 2010 Unix Programming with Perl
  • 20. How to avoid collisions after fork (DBI) (2) the answer: use InactiveDestroy my $pid = fork; if ($pid == 0) { # child process $dbh->{InactiveDestroy} = 1; undef $dbh; ... } Oct 16 2010 Unix Programming with Perl
  • 21. How to avoid collisions after fork (DBI) (3) if fork is called deep inside a module and can’t be modified, then… # thanks to tokuhirom, kazeburo BEGIN { no strict qw(refs); no warnings qw(redefine); *CORE::GLOBAL::fork = sub { my $pid = CORE::fork; if ($pid == 0) { # do the cleanup for child process $dbh->{InactiveDestroy} = 1; undef $dbh; } $pid; }; } Oct 16 2010 Unix Programming with Perl
  • 22. How to avoid collisions after fork (DBI) (4) other ways to change the behavior of fork POSIX::AtFork (gfx) Perl wrapper for pthread_atfork can change the behavior of fork(2) called within XS forks.pm (rybskej) Oct 16 2010 Unix Programming with Perl
  • 23. Close filehandles before calling exec file handles (file descriptors) are passed to the new process created by exec some tools (setlock of daemontools, Server::Starter) rely on the feature OTOH, it is a good practice to close the file handles that needn’t be passed to the exec’ed process, to avoid child process from accidentially using them Oct 16 2010 Unix Programming with Perl
  • 24. Close file handles before calling exec (2) my $pid = fork; if ($pid == 0) { # child process, close filehandles $dbh->{InactiveDestroy} = 1; undef $dbh; exec ...; ... Oct 16 2010 Unix Programming with Perl
  • 25. Close file handles before calling exec (3) Some OS’es have O_CLOEXEC flag designates the file descriptors to be closed when exec(2) is being called is OS-dependent linux supports the flag, OSX doesn’t not usable from perl? Oct 16 2010 Unix Programming with Perl
  • 26. Unix Signals Oct 16 2010 Unix Programming with Perl
  • 27. SIGPIPE “ my network application suddenly dies without saying anything” often due to not catching SIGPIPE a signal sent when failing to write to a filehandle ex. when the socket is closed by peer the default behavior is to kill the process solution: $SIG{PIPE} = 'IGNORE'; downside: you should consult the return value of print, etc. to check if the writes succeeded Oct 16 2010 Unix Programming with Perl
  • 28. Using alarm alarm can be used (together with SIG{ALRM}, EINTR) to handle timeouts local $SIG{ALRM} = sub {}; alarm($timeout); my $len = $sock->read(my $buf, $maxlen); if (! defined($len) && $! == Errno::EINTR) { warn 'timeout’; return; } Oct 16 2010 Unix Programming with Perl
  • 29. Pros and cons of using alarm + can be used to timeout almost all system calls (that may block) − the timeout set by alarm(2) is a process-wide global (and so is $SIG{ALRM}) use of select (or IO::Select) is preferable for network access Oct 16 2010 Unix Programming with Perl
  • 30. Writing cancellable code typical use-case: run forever until receiving a signal, and gracefully shutdown ex. Gearman::Worker Oct 16 2010 Unix Programming with Perl
  • 31. Writing cancellable code (2) make your module cancellable - my $len = $sock->read(my $buf, $maxlen); + my $len; + { + $len = $sock->read(my $buf, $maxlen); + if (! defined($len) && $! == Errno::EINTR) { + return if $self->{cancel_requested}; + redo; + } + } ... + sub request_cancel { + my $self = shift; + $self->{cancel_requested} = 1; + } Oct 16 2010 Unix Programming with Perl
  • 32. Writing cancellable code (3) The code that cancels the operation on SIGTERM $SIG{TERM} = sub { $my_module->request_cancel }; $my_module->run_forever(); Or the caller may use alarm to set timeout $SIG{ALRM} = sub { $my_module->request_cancel }; alarm(100); $my_module->run_forever(); Oct 16 2010 Unix Programming with Perl
  • 33. Proc::Wait3 built-in wait() and waitpid() does not return when receiving signals use Proc::Wait3 instead Oct 16 2010 Unix Programming with Perl
  • 34. Further reading Oct 16 2010 Unix Programming with Perl
  • 35. Further reading this presentation is based on my memo for an article on WEB+DB PRESS if you have any questions, having problems on Unix programming, please let me know Oct 16 2010 Unix Programming with Perl