Perl Unixプログラミング - その1

Kazuhoさんの記事(http://gihyo.jp/dev/serial/01/perl-hackers-hub/000601)を読みながら調べたことをまとめてみる。

コード

これはほとんど元記事そのまま。

use strict;
use warnings;
use Errno qw(:POSIX);

my$dir='/tmp/kotaro/1';

unless (mkdir $dir or $!==EEXIST ){
    printf "can't create $dir: $!\n";
}

システムコール

mkdirはシステムコールなので、OSからのエラー番号/エラーメッセージが$!に格納される。
$!は特殊で数値比較だとエラー番号、文字列比較だとエラーメッセージを返す。

文字列比較だとロケール変わった時にポータビリティなくなっちゃうから、数字比較にしなさい。その時は、Errnoモジュールを使うといいぞ、という話。

Errnoとerrno.h

Errnoモジュールはerrno.hに定義されたエラー定数をexportしてくれるモジュール

Errno defines and conditionally exports all the error constants defined in your system errno.h include file. It has a single export tag, :POSIX, which will export all POSIX defined error numbers.

http://search.cpan.org/~jesse/perl-5.14.1/ext/Errno/Errno_pm.PL


さて、errno.hがどこにあるかというと、Mac OSXだと/usr/include/errno.hにあった。さらに#include してたけど。

/*
 * Copyright (c) 2000-2002 Apple Computer, Inc. All rights reserved.
 *
 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@



#define EPERM           1               /* Operation not permitted */#define ENOENT          2               /* No such file or directory */
#define ESRCH           3               /* No such process */

システムコールによるエラー

manのセクション2がシステムコールなので、man 2 mkdirとやればmkdirによって発生するシステムコールのリストを調べることができる。

まとめ

  • システムコールはman 2 ***してちゃんとエラー番号調べた上で、Errnoを使って評価しましょう
  • 高級言語とはいえOSレイヤのことわかってないと正しくプログラムできないなー