質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

Q&A

解決済

1回答

24806閲覧

Inappropriate ioctl for deviceのエラー原因がわからない

komicool

総合スコア24

Perl

Perlは多目的に使用される実用性が高い動的プログラミング言語のひとつです。

0グッド

0クリップ

投稿2017/06/25 13:16

編集2017/06/25 13:26

perl

1my $fname = "test.dmp"; 2open(INF, ">:raw" , $fname) || die "\nCan't open $fname for writing: $!\n"; 3(後略)

以上のコードを実行したところ、無事ファイルを開ける(作成できる)のですが、「デバイスに不適切な ioctl です(Inappropriate ioctl for device)」というエラーが発生して$!に収納されているようです。

以後の処理をみても特に実害はなく些細なエラーのように思えるのですが、原因が不明でなんとも気持ち悪いので、ぜひとも考えうる原因・解決策についてご教示いただきたいです。

実行環境はRedhatの7.3で、Perlのバージョンはv5.16.3です。
ご回答よろしくお願いします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

perlのopenは開いたファイルがttyかどうかを判定するためにTCGETSというioctlを使っています。これはttyじゃないとエラーを返すので、エラーが返ってこなければttyで、エラーが返ってきたらttyではないとわかるという訳です。この処理のためにerrnoが汚れてしまい、たまたまそのまま残っているので$!を参照するとそのように見えてしまいますが、perlのopenがエラーを返していないのであれば気にする必要はありません。$!はエラーを検出した直後にそのエラーが何であったか知るために使うもので、それ以外のタイミングで参照した場合何が入っているかはわからないので値に意味はないのです。

terminal

1% touch foo 2% strace perl -e 'open F, "<foo" or die "open error $!"' 3...略 4open("foo", O_RDONLY) = 3 5ioctl(3, TCGETS, 0x7ffeede80540) = -1 ENOTTY (Inappropriate ioctl for device) 6...略

投稿2017/06/27 07:26

crhg

総合スコア1175

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

komicool

2017/06/27 16:31

ありがとうございます。おかげさまで、だいぶ理解がすすみました。 もう1点だけ確認させていただきたいのですが、$!の値がリセットされる条件などは存在するのでしょうか。 と言いますのも、スクリプトの末尾で、die "Problem happened: $!\n" if $!; という一文を書いて処理の途中でエラーが発生していないか確認していたのですが、ttyでないファイルにopenを用いる処理があるAとBというスクリプトに関して Aはif $!に引っかからないのに対して、Bはif $!に引っかかっるという事象が発生して困惑しております(A、Bともにopenの直後にdie "Problem happened: $!\n" if $!;を挿入すると「デバイスに不適切な ioctl です」というエラーが発生することは確認済みです)
crhg

2017/06/27 22:08

マニュアルによれば、一部のシステムコールやライブラリ関数には戻り値でエラーを示すことができないので呼ぶ前にerrnoに0を設定しておき呼んだ後に0以外になっていることでエラーを判定するものがあるということなので、そういうものを使っているのかもしれません。 > いくつかのシステムコールやライブラリ関数 (例えば getpriority(2)) では、成功した場合の有効な返り値として -1 が返されることがある。 このような場合、成功なのかエラーなのかを区別するためには、 呼び出しの前に errno を 0 に設定しておけばよい。呼び出しの返り値がエラー発生の可能性を 示すものだった場合には、 errno が 0 以外の値かを見て確認すればよい。 [errnoのマニュアル](https://linuxjm.osdn.jp/html/LDP_man-pages/man3/errno.3.html)
komicool

2017/06/29 14:26

よくわかりました。errnoの補足も含め、丁寧な回答ありがとうございました。助かりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問