C言語 - 標準ライブラリ - その他

 クラウディア
1. 概要
2. stat ファイル情報
3. dirname, basename ディレクトリ名
4. flock ファイル排他
5. scandir, alphasort ディレクトリ検索

1. 概要

 このあたりになると、プラットフォームや個々のコンパイラにより、ヘッダファイル名や動作にばらつきが見られてきます。

2. stat ファイル情報


#include <sys/types.h>
#include <sys/stat.h>

int stat(const char *path, struct stat *sb);
 「stat」は、「path」が指すファイルの情報を取得します。指定したファイルの読取り権、書込み権、実行権は必要ありません。  しかし、そのファイルへ至るパス名で列挙されたすべてのディレクトリは、検索可能であることが必要です。  成功して終了したときには値「0」を返します。  そうでない場合、値「-1」が返され、グローバル変数「errno」が設定されてエラーを示します。  わたしは、もっぱら、ファイルやディレクトリの有無を見るときに単に戻り値だけを見たりします。  正確には、「sb」の中も見なければだめなんですけどね。

3. dirname, basename ディレクトリ名


#include <libgen.h>

char *dirname(char *path);

char *basename(char *path);
 「dirname」は、「path」で示す、フルパスのファイル名より、ディレクトリの部分文字列を取得します。  「basename」は、「path」で示す、フルパスのファイル名より、ファイル名のみの部分文字列を取得します。

4. flock ファイル排他


#include <sys/file.h>
#define   LOCK_SH        0x01      /* 共有ファイルロック 				*/
#define   LOCK_EX        0x02      /* 排他的ファイルロック 				*/
#define   LOCK_NB        0x04      /* ロックするときにブロックしない 	*/
#define   LOCK_UN        0x08      /* ファイルをアンロックする 			*/

int flock(int fd, int operation);
 「flock」は、ファイル記述子「fd」(「open」の戻り値のファイルディスクリプタです)に対応するファイル上の 問合せ型ロックを適用または除去します。  ロックを適用するには、「operation」引数に「LOCK_SH」または「LOCK_EX」のいずれかと、必要であれば「LOCK_NB」を加えて指定します。  既存のロックをアンロックする場合は「operation」を「LOCK_UN」にします。  これ、使い方は、下記のサイトが参考になります。
ファイルに対してロックの適用・解除を行う – C言語入門講座
 いささか、長いですが、下記のソースを書いて・・・。
#include <limits.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/file.h>

int main(int argc, char *argv[])
{
	char afilename[PATH_MAX] = "./lock";
    int nfd = -1;

	printf("ロックします。\n");

    while(true)
    {
        if (nfd == -1)
        {
            nfd = open(afilename, O_WRONLY | O_CREAT);

            if (nfd == -1)
            {
                continue;
            }
        }

        if (flock(nfd, LOCK_EX) == 0)
        {
            break;
        }

        usleep(1000);
    }

	printf("ロックしました。\n");
	printf("[Enter] を入力してください。 ");
	getchar();
	printf("解除します。\n");

    flock(nfd, LOCK_UN);
    close(nfd);
    remove(afilename);

	printf("解除しました。\n");

	return 0;
}

 2つの端末で同じディレクトリで、上記のファイルから作成したロードモジュールを起動すると  先に起動した方が

ロックします。
ロックしました。
[Enter] を入力してください。
 の状態で止まり、後で起動した方が

ロックします。
 の状態で止まります。  先に起動した方に Enter を入力すると

解除します。
解除しました。
 で終了し、後で起動した方が

ロックしました。
[Enter] を入力してください。
 で止まって、ロックした状態になります。

5. scandir, alphasort ディレクトリ検索


#include <sys/types.h>
#include <dirent.h>

int scandir(const char *dirname, struct dirent ***namelist,
				int (*select)(struct dirent *), int (*compar)(const void *, const void *));

int alphasort(const void *d1, const void *d2);
 「scandir()」関数はディレクトリ「dirname」を読み取り、「malloc」を使用して、ディレクトリエントリを指すポインタの配列を作成します。  そして配列内のエントリの数を返します。  ディレクトリエントリの配列を指すポインタは、 「namelist」が参照する位置に保存されます。  「select」パラメータは、どのエントリを配列に入れるかを選択するために「scandir()」 によって呼び出される、ユーザ定義サブルーチンを指すポインタです。  選択ルーチンにはディレクトリエントリを指すポインタが渡されます。  また、ディレクトリエントリを配列に入れる場合は非 0 の値を返さなくてはなりません。  「select」が「NULL」の場合、すべてのディレクトリエントリが組み入れられます。  「compar」パラメータは、ユーザ定義サブルーチンを指すポインタであり、このサブルーチンは完成した配列をソートするために 「qsort」に渡されます。  このポインタが「NULL」の場合、配列はソートされません。  「alphasort()」関数は、「compar」パラメータに使用できるルーチンで、配列をアルファベット順にソートします。  配列用に割当てられたメモリを「free」で割当て解除できます。  その場合、配列内の各ポインタを解放してから、配列自体を解放してください。  わたしがよく使う使い方は

    no = scandir(ディレクトリ文字列, &namelist, 0, alphasort);

	for (i=0; i<no; i++)
	{
		//	namelist[i] にファイル名が 入っているので
		//	ファイルに対して何らかの処理を行います

        free(namelist[i]);
    }

    free(namelist);
 ループ内で、「namelist」の各配列を解放して、ループ外で、「namelist」自体を解放します。  この場合、ループ内部で、「continue」等により、配列内の開放を忘れないこと、戻り値が「-1」のときは、「namelist」自体にメモリが割り当てられていないので、解放してはいけないことを注意しなければなりません。
ハイスピードプランU-NEXT【usus ウズウズ】
 
 
カウンタバックグラウンド