Linuxシステムコールの勉強(その8)

Linuxシステムコール

Linuxシステムコール

前回はこちら


今回からシステムコールのioctl()を使用した端末の制御について説明します。


まずはある出力がリダイレクトされているのかどうかを調べるための関数isatty()を使ってみます。
# 関数名なんて読むんだろう?とウンウン悩んだのですが、どうやらis_a_ttyということらしいです。

/*** ファイルディスクリプタが端末かどうかを確認 ***/
// #include <unistd.h>
// 
// 第一引数 チェックするファイルディスクリプタ
//
// 返却値
//  端末ではない :  0
//  端末である  :  1
int isatty(int fd);
#include <stdio.h>
#include <unistd.h>

int main()
{
    char buff[BUFSIZ];

    if ( isatty(fileno(stdin)) == 0 || isatty(fileno(stdout)) == 0)
    {
            fprintf(stderr,"ファイルへリダイレクトしないでください\n");
            return 1;
    }

    printf("あなたの名前は? ");
    fgets(buff,BUFSIZ,stdin);

    buff[strlen(buff) - 1] = '\0';

    printf("こんにちは %s さん\n", buff);
    return 0;
}


実行結果は以下のとおりです。

itotto@itotto > gcc -o chktm checkterm1.c

itotto@itotto > ./chktm
あなたの名前は? itotto
こんにちはitotto さん

itotto@itotto > ./chktm > hogehoge.txt
ファイルへリダイレクトしないでください

itotto@itotto >

リダイレクトをしない場合には名前を入力させた後にそれを表示していますが、リダイレクトをした場合はisatty()が0を返すために警告のメッセージを表示して処理が終わります。


ではこのisatty()と同じ動作をする関数を、噂のioctl()を使って実装してみます。

/*** isatty()(自作版) ***/
// #include <sys/ioctl.h>
// 
// 第一引数 チェックするファイルディスクリプタ
// 第二引数 要求する処理
// 第三引数 使用するtermio構造体へのポインタ
//
// 返却値
//  処理成功 :   0
//  処理失敗 :  -1
int ioctl(int fd, intrequest, termio *tm);


第二、第三引数について書くと長くなりそうなので次回説明します。ひとまずソースをまとめます。

#include <sys/ioctl.h>
#include <stdio.h>

int my_isatty(int fd);

int main()
{
    char buff[BUFSIZ];

    if ( my_isatty(fileno(stdin)) == 0 || my_isatty(fileno(stdout)) == 0 )
    {
        fprintf(stderr, "ファイルへリダイレクトしないでください\n");
        return 1;
    }


    printf("あなたの名前は? ");
    fgets(buff,BUFSIZ,stdin);

    buff[strlen(buff) - 1] = '\0';

    printf("こんにちは%s さん\n", buff);

    return 0;
}

int my_isatty(int fd)
{
    struct termio tm;
    return ioctl(fd, TCGETA, &tm) ? 0 : 1;
}


出力結果は↑と同じです。


# 2007/11/7現在、上記のソースはコンパイルが通っていません
# BSDlinuxでヘッダーが違うのかなと思い調べてるとこです
# 修正したら通知します


このように、ioctl()を使えば端末の制御が細かく実装できそうです。次回はioctl()の第二、第三引数についての説明と、端末のCookedモードとRAWモードについて説明します。


次へ進む