2009年03月12日

ファイル操作 その2?

昨日時間関連の取得と変更をしたのでパーミッションやら削除やらの確認をした。
system関数を使っても同じだろうが一応同じような関数で同じことができる。
Windowsでそうコーディングしていたせいか絶対パスを渡していたのだが
なんのことはないパス名を除いたファイル名でもちゃんと動作した。
ちなみに文字処理用ワークエリアとして

#define BUFSIZE 16384
char tmp[BUFSIZE];

を宣言している前提。

カレントパスについては

getcwd(buf, BUFSIZE)

でも取得できるようだがバッファーが必要なので面倒
やっぱり

getenv("PWD")

の方がよさそうだ。

ファイル作成はopenでいいがディレクトリーの場合はmkdirのようだ。
この場合

mkdir(name,mode);

とパーミッションが必須らしい。

renameも

rename(a,b);

でできる。
おもしろいというかrenameは書き込み中のファイルにもできるようで
隙間無くバックアップできそうである反面
タイミングを間違えると開き直せなくなるわけでブロック方法を考える必要があると感じた。

ファイル削除はrmdirやunlinkもあるもののremoveで一貫して行えるが
ディレクトリーの削除の場合はディレクトリー内にファイルがあるとエラーがでた。
これは不用意な削除を防ぐにはファイルを置けばいいだけである反面
再帰型のルーチンを書かねばならず面倒くさい。


sprintf(buf,"rm -r ",dir_name);
system(buf);

とすればすっきりできるのだが、それじゃ今やっているのは何ということになる。
短くrm -rをコーディングする事も課題になりそうだ。

statで取得した4つの時間関連以外のパラメータだが
st_sizeはそのままファイルサイズのようだ。

sizeof(f_info.st_size);

とすると8なので普通にint64らしい。(long long int ?)

st_uidからユーザー名を求めるには

#include <pwd.h>

をインクルードしておいて

struct passwd p_wd;
struct passwd *p_id;

を宣言しておき


p_id=getpwuid(f_info.st_uid);

でpasswd構造体にアクセスできる。
freeしたらコアダンプしたのでOSが管理しているstaticな構造体のポインタのようだ。
つまり実は変数が無くても

puts(getpwuid(f_info.st_uid)->pw_name);

とすれば名前が出力される。
passwd構造体で取得できるパスワードは「*」になる。

名前から構造体を求めるにはgetpwnam_rを使って

result = getpwnam_r("root", &p_wd, buf, BUFSIZE, &p_id);

みたいに求める。
データの場所をこちらで用意している以外は同じ。
普通はmallocでいちいち確保するところだろうか。

st_gidからグループ名を求める場合

#include <grp.h>

をインクルードして


struct group *g_id;

を用意


g_id=getgrgid(f_info.st_gid);

として構造体のポインタを取得できるが
これもstaticなデータなのでuid同様


getgrgid(f_info.st_gid)->gr_name

で直接取得できる。
strlenとってからコピーするなりそのままアドレスを配列に入れるなりやりようはあるだろう。

次にパーミッションだが
st_modeの値は

printf("modes:%o\n",f_info.st_mode);

と8進数で表示すると下3桁がいわゆるパーミッションらしい事が分かる。

で上位の数字が何か調べたら
要は

S_IFCHR:0x2000
S_IFDIR:0x4000
S_IFBLK:0x6000
S_IFREG:0x8000
S_IFMT :0xF000

ということでS_IFREGが一般ファイル、S_IFDIRがディレクトリーらしい。
これについてはマクロだかユーティリティだかで

result=S_ISREG(f_info.st_mode)

みたいな感じで判定できる関数があるのでこれで判断できるがreaddirの方が手っ取り早い。

パーミッションの個別取得はint aが最適化してくれることを期待して

a=f_info.st_mode;
printf("user:%o\n", (a & 0x1c0)>>6);
printf("group:%o\n", (a & 0x38)>>3);
printf("other:%o\n", (a & 7));

なんぞと分離表示できる。パラメータの置換は配列でも使ってやるのが良いと思う。

シンボリックリンクは

symlink("Etb.jpg","Etb2.jpg");

で生成できる。
通常のファイルアクセスの場合Etb2.jpgのアクセスを通して実体がアクセスされる。
statも実態へのアクセスなのでlstat命令を使う必要がある。
リンク先についてはreadlinkでできる。
何も考えずにreadlinkしたところバッファーが残ったままだった。

result=readlink(name,buf,BUFSIZE);
if (result!=-1){
buf[result]=0;
puts(buf);
}

とnullを付け加えるかどこぞに移すがよいだろう。
ぼちぼちCにも慣れてきた感じではある。
posted by Xo_ox at 18:23| Comment(0) | FreeBSDアプリ | このブログの読者になる | 更新情報をチェックする
この記事へのコメント
コメントを書く
お名前:

メールアドレス:

ホームページアドレス:

コメント:

認証コード: [必須入力]


※画像の中の文字を半角で入力してください。
×

この広告は180日以上新しい記事の投稿がないブログに表示されております。