C 言語で新しいディレクトリを作成する
この記事では、C 言語で新しいディレクトリを作成する方法について複数の方法を示します。
mkdir
関数を使って新しいディレクトリを作成する
mkdir
は POSIX に準拠した関数であり、新しいディレクトリを作成するために用いることができます。第 1 引数は新しく作成するディレクトリのパス名を指す char
ポインタであり、第 2 引数はパーミッションビットを指定します。
以下の例では、ディレクトリ名として文字列定数変数を宣言し、S_IRWXU
モードビットを指定しているが、これはディレクトリの所有者がディレクトリの読み書き実行権限を持つことを意味します。
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
const char *name = "Arbitrary Directory";
int main(void) {
mkdir(name, S_IRWXU);
exit(EXIT_SUCCESS);
}
先ほどの例では mkdir
の呼び出しを一行で記述したが、本番レベルのコードを扱う際にはエラーチェックルーチンを実装しておくことが重要です。まず、新しいディレクトリが作成されているかどうかを確認し、それ以降の部分がそのディレクトリに依存していても正常に実行できるかどうかを確認する必要があります。mkdir
はエラーが発生した場合に -1
を返し、それに応じて errno
を設定することに注意します。今回は、switch
ステートメントを実装して、エラーコードをチェックし、それに対応するメッセージをコンソールに表示するようにした。
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
const char *name = "Arbitrary Directory";
int main(void) {
errno = 0;
int ret = mkdir(name, S_IRWXU);
if (ret == -1) {
switch (errno) {
case EACCES:
printf("the parent directory does not allow write");
exit(EXIT_FAILURE);
case EEXIST:
printf("pathname already exists");
exit(EXIT_FAILURE);
case ENAMETOOLONG:
printf("pathname is too long");
exit(EXIT_FAILURE);
default:
perror("mkdir");
exit(EXIT_FAILURE);
}
}
exit(EXIT_SUCCESS);
}
関数 mkdirat
を用いて新しいディレクトリを作成する
mkdirat
も同様に動作するシステムコールであるが、3つの引数を取ることを除いては似たような動作をします。最初の引数はディレクトリファイル記述子であり、dirfd
システムコールで取得できます。このファイル記述子は、第 2 引数に指定されたパス名が相対パスである場合に使用されることに注意してください。この場合、パスは現在の作業ディレクトリではなく、指定されたディレクトリに対する相対パスとして解釈されます。
mkdirat
は mkdir
と同じ戻り値を持ち、errno
の値もそれに応じてチェックすることができます (このページ の全リストを参照してください)。以下のコード例は、前のディレクトリから現在のディレクトリに新しいディレクトリを作成しようとするものです。
#include <dirent.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
const char *name = "Arbitrary Directory";
int main(void) {
DIR *dir = opendir("../");
int dfd = dirfd(dir);
errno = 0;
int ret = mkdirat(dfd, name, S_IRWXU);
if (ret == -1) {
switch (errno) {
case EACCES:
printf("the parent directory does not allow write");
exit(EXIT_FAILURE);
case EEXIST:
printf("pathname already exists");
exit(EXIT_FAILURE);
case ENAMETOOLONG:
printf("pathname is too long");
exit(EXIT_FAILURE);
default:
perror("mkdir");
exit(EXIT_FAILURE);
}
}
closedir(dir);
exit(EXIT_SUCCESS);
}