C 言語で新しいディレクトリを作成する

胡金庫 2023年10月12日
  1. mkdir 関数を使って新しいディレクトリを作成する
  2. 関数 mkdirat を用いて新しいディレクトリを作成する
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 引数に指定されたパス名が相対パスである場合に使用されることに注意してください。この場合、パスは現在の作業ディレクトリではなく、指定されたディレクトリに対する相対パスとして解釈されます。

mkdiratmkdir と同じ戻り値を持ち、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);
}
著者: 胡金庫
胡金庫 avatar 胡金庫 avatar

DelftStack.comの創設者です。Jinku はロボティクスと自動車産業で8年以上働いています。自動テスト、リモートサーバーからのデータ収集、耐久テストからのレポート作成が必要となったとき、彼はコーディングスキルを磨きました。彼は電気/電子工学のバックグラウンドを持っていますが、組み込みエレクトロニクス、組み込みプログラミング、フロントエンド/バックエンドプログラミングへの関心を広げています。

LinkedIn Facebook

関連記事 - C File