unix_programming4章_1

「Unix/Linuxプログラミング 理論と実践」読み進めています。

4章課題について進んでいきます。

4章はファイルシステムに関する章になります。
inodeだとかデータ領域だとかその辺のお話がメインです。
が、実際中身は3章とそんなに大差ないです。

1つめ。mkdir -pを実装せよ。
今まで読んでいる方は気づいているかもしれないですが、今オプションの処理をしてません。
それはそれで別の機会に実装すればよいのでは今は機能それ自体に集中してます。

さて実装ですが、下記のような感じに仕上げました。
mkdirはディレクトリを作成できますから、再帰的に処理するのが一番しっくり来るのではないかと想定して、再帰関数にしてます。
遡っていって、ディレクトリが存在した時点で探索を終了し、あとは巻き戻っていくと同時にディレクトリを逐次作成していきます。

この手の関数を作ってて思うのは・・・特にやっていることは上級言語と変わらないですね。
unixプログラミングといえど、もはやOS自体は洗礼されていますから、私達プログラマがやるのは適切なシステムコールやライブラリ関数をパズルのようにつないでいくことだけです。

ちょいと文字列やメモリの扱いがシビア(というか感覚が違うだけ)ですがそれにさえ慣れてしまえば、そんなに大したことはないのかな。
早く実務に耐えうるレベルまで学習していきたいと思います。

#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include <string.h>

int recursive_mkdir(const char *path, mode_t mode);

//
// 4.15
// implements mkdir -r
//
int main(int argc, char *argv[])
{
	if (argc < 2) {
		printf("usage -- ./a.out [dir_path]\n");
		exit(-1);
	}

	recursive_mkdir(argv[1], 0644);
}

int recursive_mkdir(const char *path, mode_t mode)
{
	struct stat dir;
	char *ppath;
	int i=0, idx=0, len=0;

	// check existence.
	if (!stat(path, &dir)) {
		if (S_ISDIR(dir.st_mode)) {
			return 1;
		}
	}

	if (strcmp(path, "/") == 0) {
		return 1;
	}

	// trim last segment.
	len = strlen(path);
	for (i=0; i<len; i++) {
		if (path[i] == '/') {
			idx = i;
		}
	}

	if (idx > 0) {
		ppath = malloc(sizeof(char) * (idx+1));
		ppath = strncpy(ppath, path, idx);
		ppath[idx] = '\0';
		if (recursive_mkdir(ppath, mode) == -1) {
			free(ppath);
			return -1;
		}
	}

	// mkdir
	if (mkdir(path, mode) == -1) {
		perror("failed to mkdir.");
		exit(-1);
	}

	return 1;
}

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です