[Eject]光学ドライブの開閉状態を取得してみる
Ejectコマンド工作をやってると良く光学ドライブの開閉状態を確認したくなりますよね。
ならないとしたら、今すぐこの記事を読むのをやめて病院に行って下さい。
※Ejectネタです。(☝ ՞ਊ ՞)☝ウィーン
というわけで今回は、光学ドライブの開閉状態を確認する方法を考えてみました。
前回の記事の続きです。
前回はディスクのマウントの有無で光学ドライブの開閉状態確認していましたが、少しレベルアップしました。
システムコールを利用する
最終的な結論から言うと、現段階ではこれが一番良い方法だと思います。
初めてのLinuxプログラミングに四苦八苦しながらも書いたら何とかなりました。
いきなりソースコード。
[2014/9/11 追記]close()忘れてました。ファイルディスクリプタ開いたらしっかりclose()しませう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
#include <stdio.h>
#include <fcntl.h>
#include <linux/cdrom.h>
#include <sys/ioctl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc,char *argv[]){
int fd, result, slot;
if(argc != 2){
printf("ERROR!n");
return(-1);
}
fd = open(argv[1], O_RDONLY | O_NONBLOCK);
result=ioctl(fd, CDROM_DRIVE_STATUS, slot);
//[2014-9-11 追記]ファイルディスクリプタ開いたはいいけどclose忘れてました。
//終了するときに勝手にcloseしてくれるはずだけど一応ね。。
close(fd);
switch(result) {
case CDS_NO_INFO:
printf("NO_INFOMATIONn");
return(0);
case CDS_NO_DISC:
printf("NO_DISCn");
return(1);
case CDS_TRAY_OPEN:
printf("TRAY_OPENn");
return(2);
case CDS_DRIVE_NOT_READY:
printf("NOT_READYn");
return(3);
case CDS_DISC_OK:
printf("DISC_OKn");
return(4);
default:
printf("ERROR!n");
return(-1);
}
}
|
コンパイルします。
1 |
$gcc drive_status.c
|
実行します。
1
2
3
4
5
6
|
$./a.out /dev/cdrom1
NO_DISC
$ ./a.out /dev/cdrom1
DISC_OK
$ ./a.out /dev/cdrom1
TRAY_OPEN
|
使い方
引数にはデバイスファイルを指定します。上記は一例ですので状況に応じて変更してください。
TRAY_OPENが返ってきた場合はトレイが開いている状態となります。
NO_DISK, DISC_OK, NOT_READYであればトレイが閉じている状態となるはずです。
(DISC_OK, NOT_READYの違いはよく分かりません。マウントの有無?)
NO_INFOMATIONの場合は、情報を取得すらできていないのでエラーとして扱ってもいいかもしれません。
その辺りを含めて、都合のいいように改造して使ってみたりするといいと思います。
(なお、私自身がLinuxでのプログラミングが初めてだったので私に質問されても分かりません・・・。)
これを使ってPHPでAPIを書いてみます。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
<?php
header('Content-Type: text/javascript; charset=utf-8');
$command = '/var/www/eject/eject_status /dev/cdrom1';
$result = exec($command, $r1, $r2);
if($r2 == "-1" || $r2 == "0"){
$ret = array('code'=>-1, 'message'=>'error');
}
if($r2 == "2"){
$ret = array('code'=>1, 'message'=>'Open');
}
else {
$ret = array('code'=>0, 'message'=>'Close');
}
echo(json_encode($ret));
|
シンプルですね。
返り値0はNO_INFOMATION(情報を取得できない)なので、一応エラーにしていますがこのへんは適宜改造してください。
これで光学ドライブの状態が取得できます。
便利ですね!
皆さんもぜひ、使ってみて下さい。
以上です。ではまた。
おまけ
こんな感じで利用するといいですよーというサンプル。
PHPでejectを行う場合に、「今の呼び出して”開いた”のか”閉じた”のか」がわかりますね。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
<?php
header('Content-Type: text/javascript; charset=utf-8');
$eject_com = '/var/www/eject/eject.sh';
//作ったプログラムでステータスの取得
$status_com = '/var/www/eject/eject_status /dev/cdrom1';
$eject_r2 = -1;
$status_result = exec($status_com, $status_r1, $status_r2);
if($status_r2 != "0" && $status_r1 != "-1" && $status_r2 != "255"){
$eject_result = exec($eject_com, $eject_r1, $eject_r2);
}
if($status_r2 == "-1" || $eject_r2 == '-1'){
$ret = array('code'=>-1, 'message'=>'Error!');
}
else if($status_r2 != "2" && $eject_r2 == "0"){
$ret = array('code'=>0, 'message'=>'Eject Successful [Open]');
}
else if($status_r2 == "2" && $eject_r2 == "0"){
$ret = array('code'=>1, 'message'=>'Eject Successful [Close]');
}
else{
$ret = array('code'=>-1, 'message'=>'Error!');
}
$ret_json = json_encode($ret);
echo $ret_json;
|
また、このコードでは、ステータスを取得した場合にエラーだったらEjectを実行しないので比較的安全に使えるかと思います。
(コードがグチャグチャで構造化できてないのは、実験として適当に書いただけだからあまりツッコまないであげて)
以上です。