プロが教えるわが家の防犯対策術!

下記のコードをMac OS XのXcodeのC言語の環境で実行してみたのですが、f1のファイルが
f2にコピーはされるのですが、何故か、f2ファイルの保護情報がPERMSで設定した0666(8進表示)
になってくれません。f1の保護情報を色々変えてやってみているのですが、f2の保護情報がどんな
場合でも、0644になってしまうようなのですが、何が悪いのでしょうか?
ご経験のある方、ご教示願えればと思います。


#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdarg.h>
#define BUFSIZE 10
#define PERMS 0666 /* 所有者、グループ、他人に対してRW */

void error(char *, ...);

int main(int argc, const char * argv[]) {
int f1, f2, n;
char buf[BUFSIZE];

if (argc != 3)
error("Usage: cp fro to");
if ((f1 = open(argv[1], O_RDONLY, 0)) == -1)
error("cp: ca'nt open %s", argv[1]);
if ((f2 = creat(argv[2], PERMS)) == -1)
error("cp: ca'nt create %s, mode %03o", argv[2], PERMS);
while ((n = (int)read(f1, buf, BUFSIZE)) > 0)
if (write(f2, buf, n) != n)
error("cp: write error on file %s", argv[2]);

return 0;
}

/* error: エラー・メッセージを印字して死ぬ */
void error(char *fmt, ...)
{
va_list args;

va_start(args, fmt);
fprintf(stderr, "error: ");
vfprintf(stderr, fmt, args);
fprintf(stderr, "\n");
va_end(args);

exit(1);
}

A 回答 (3件)

あなたの環境のumaskの値が0022になっているかと思います。


modeで指定した値はファイル生成時、mode&(~umask)の結果が実際のパーミッションとなります。
今回、umask=0022 -> ~umask=0755となり
0666 & 0755 = 0644となります。したがって、実際に生成されるファイルのパーミッションは0644となります。
これを回避するには2つの方法があります。
1案:
コマンドで umask 0 を実行・・・・umaskの一時設定
その後、当該プログラムを実行
コマンドで umask 0022を実行・・・・umaskの戻し
(パラメータを指定せずにumaskと入力すると、現在のumaskの内容が表示されます。
もし、現在のumaskが0022以外なら、その値を指定してumaskを戻してください)

2案:プログラム中でumaskの設定
umask(0);
の行をmainの頭で実行する。(if (argc != 3)の行の直前)
umaskの呼び出しは、以下のincludeが必要なので、必要があれば、下記を追加する。
#include <sys/types.h>
#include <sys/stat.h>
ここで、設定したumaskはそのプログラム内で有効なので、実行後は0022に戻っています。(つまりumaskの戻しは不要)
    • good
    • 0
この回答へのお礼

2案の方法でうまくいきました!!

ただ、1案は何故かうまくいきませんでした。
上記ファイルの置いてあるディレクトリで、ターミナルで、umask 0
を実行。umaskコマンドで実際にumaskが0000になっていることを確認後、元のプログラムを実行。

お礼日時:2016/09/23 20:40

No2です。


>ただ、1案は何故かうまくいきませんでした。
>上記ファイルの置いてあるディレクトリで、ターミナルで、umask 0
>を実行。umaskコマンドで実際にumaskが0000になっていることを確認後、元のプログラムを実行。

うーむ・・・・・。不思議ですね。こちらでは問題なく実行できています。(こちらのOSはCentOSなのでその違いかもしれません)
念の為、確認ですが
umask 0 を実行したターミナルと同じターミナルで元のプログラムを実行していますか?
別のターミナルで元のプログラムを実行した場合は、期待した結果は得られません。
    • good
    • 0
この回答へのお礼

ご指摘ありがとうございます。

プログラムの実行をXcode画面での実行ボタンで行っていました。
ファイルが置いてあるディレクトリにある実行ファイルでターミナルからバッチで実行するとうまくいきました。

ありがとうございました。

お礼日時:2016/09/24 06:05

umask って知ってますか?

    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!