スポンサーリンク

このドキュメントの内容は、以下の通りです。

はじめに

オペレーティングシステムでは、ストレージと呼ばれる記憶装置を管理しています。オペレーティングシステムはファイルシステムを利用して、ストレージを管理します。オペレーティングシステムで実行されるプログラムは、ファイルシステムのツリーに紐づけられます。親のプロセスに割り当てられているカレントディレクトリが子プロセスのカレントディレクトリになります。

たとえば、LinuxやFreeBSDなどのUnix系OSで、シェルからプログラムを起動したときに、実行されたプログラムがファイルを相対パスで開く場合、シェルのカレントディレクトリの位置から相対的にみたパスになります。

プログラムからカレントディレクトリを知る方法について説明致します。

プログラムからカレントディレクトリを知る方法

プログラムは、カレントディレクトリを知ることができます。カレントディレクトリを知るためには、C言語の場合は、 getcwd() と呼ばれる関数を利用します。

getcwdcwdは、current working directoryの略です。つまるところ、getcwdカレントワーキングディレクトリを取得(get)するという意味になります。

getcwd は、 使い方によっては、関数内で malloc で動的にメモリを確保するため、その場合には、明示的なメモリの解放が必要になるため、明示的なfreeが必要になりますので、ご注意下さい。

サンプルコード getcwd.c

getcwdのサンプルコードを以下に示します。

#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>
#include <sys/param.h>

char *
Getcwd (char *buf, size_t size) {
	char *p = getcwd (buf, size);
	if (! p) {
		perror ("getcwd");
	}
	return (p);
}

int main(int argc, char *argv[])
{

	char	path[MAXPATHLEN];

	if (Getcwd (path, sizeof (path) ) == NULL) {
		exit (EXIT_FAILURE);
	}

	(void) puts (path);

	exit (EXIT_SUCCESS);
}

コンパイル方法

サンプルプログラムのコンパイル方法は以下の通りです。
cc -Wall getcwd.c

サンプルコード getcwd_null.c

getcwdの第一引数には、NULLポインタを渡すこともできます。
NULLポインタを渡した場合、 getcwdの中で PATH_MAX分のメモリを動的に確保(malloc)します。その代わり、プログラマが getpwdによって確保されたメモリを明示的にfree(解放)する必要があります。メモリを解放せずに、何度も getcwd を呼び出すと、メモリリークの原因になります。

#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>
#include <sys/param.h>

char *
Getcwd (char *buf, size_t size) {
	char *p = getcwd (buf, size);
	if (! p) {
		perror ("getcwd");
	}
	return (p);
}

int main(int argc, char *argv[])
{

	char	*p;
	p = Getcwd (NULL, 0);

	if (p == NULL) {
		exit (EXIT_FAILURE);
	}

	(void) puts (p);
	free (p);

	exit (EXIT_SUCCESS);
}

コンパイル方法


cc -Wall getcwd_null.c

getwdについて

getwd()という関数がありますが、これは、 getcwdのバッファを MAXPATHLEN として呼び出したのと同じ意味になります。
p = getcwd(buf, MAXPATHLEN);

getcwd の定義について

FreeBSD の場合は、 getcwd の実装は /usr/src/lib/libc/gen/getcwd.cに定義されています。getcwd を読んでいくと、さらに __getcwd を呼び出してます。
__getcwd は、
システムコールの名前の一覧が /usr/src/sys/kern/syscalls.c に配列で定義されています。その中に __getcwd が含まれているため、 __getcwd はシステムコールとして実装されているようです。

getcwdのソース /usr/src/lib/libc/gen/getcwd.c をぼんやり見ていたら、 mallocの引数のところで、代入なんかしてて、たいしたことはありませんが、面白いです。

if ((pt = malloc(ptsize = PATH_MAX)) == NULL)
	return (NULL);
ept = pt + ptsize;

参考

FreeBSDドキュメント jman getcwd

2007/12/09追記

getcwdをgetpwdとタイポしていたところを修正しました。

C言語関連記事

[2008-05-03-1] FreeBSD C言語 kqueue/keventで簡易tail -fコマンドを作る
[2008-04-06-2] Unix C言語で超簡単なlsコマンドを作ってみる
[2007-12-27-2] C言語でCSVの文字列をsscanfで読み込む方法
[2007-12-22-1] FreeBSD C言語のerrnoの実装
[2007-09-23-3] C言語の_Boool型とC99とgccとstdbool.hのbool型
[2007-07-17-1] C言語による間違えトップ10
[2007-07-16-1] C言語使いのJavaScript strstr
[2007-07-02-4] Part1 オープンソース/C言語に学ぶ「ソースコードの読み方」
参照しているページ (サイト内): [2007-12-27-2]

スポンサーリンク
スポンサーリンク
 
いつもシェア、ありがとうございます!


もっと情報を探しませんか?

関連記事

最近の記事

人気のページ

スポンサーリンク
 

過去ログ

2020 : 01 02 03 04 05 06 07 08 09 10 11 12
2019 : 01 02 03 04 05 06 07 08 09 10 11 12
2018 : 01 02 03 04 05 06 07 08 09 10 11 12
2017 : 01 02 03 04 05 06 07 08 09 10 11 12
2016 : 01 02 03 04 05 06 07 08 09 10 11 12
2015 : 01 02 03 04 05 06 07 08 09 10 11 12
2014 : 01 02 03 04 05 06 07 08 09 10 11 12
2013 : 01 02 03 04 05 06 07 08 09 10 11 12
2012 : 01 02 03 04 05 06 07 08 09 10 11 12
2011 : 01 02 03 04 05 06 07 08 09 10 11 12
2010 : 01 02 03 04 05 06 07 08 09 10 11 12
2009 : 01 02 03 04 05 06 07 08 09 10 11 12
2008 : 01 02 03 04 05 06 07 08 09 10 11 12
2007 : 01 02 03 04 05 06 07 08 09 10 11 12
2006 : 01 02 03 04 05 06 07 08 09 10 11 12
2005 : 01 02 03 04 05 06 07 08 09 10 11 12
2004 : 01 02 03 04 05 06 07 08 09 10 11 12
2003 : 01 02 03 04 05 06 07 08 09 10 11 12

サイト

Vim入門

C言語入門

C++入門

JavaScript/Node.js入門

Python入門

FreeBSD入門

Ubuntu入門

セキュリティ入門

パソコン自作入門

ブログ

トップ


プライバシーポリシー