続きです。エラー処理を入れていきます。
7 int main(int argc, char* argv[]) 8 { 9 FILE *fp; 10 int i,len,size=0; 11 int value=0; 12 int ch,tmp[100]; 13 struct stat buf; 14
tmp配列は必要なくなったので削除して、argvを多用していると、何の文字列だかわからなくなるので、filename変数を作りました。
7 int main(int argc, char* argv[]) 8 { 9 FILE *fp; 10 int i,len,size=0; 11 int value=0; >> int ch; 13 struct stat buf; >> char *filename;
以下のargv[optind]を、
34 for(; optind<argc; optind++){ 35 if(stat(argv[optind],&buf) != 0){ 36 fp = fopen(argv[optind],"w"); 37 for(i=0; i<size; i++) 38 fputc(value,fp); 39 fclose(fp); 40 }else{ 41 len = buf.st_size; 42 if(len < size){ 43 fp = fopen(argv[optind],"a"); 44 for(i=len; i<size; i++) 45 fputc(value,fp); 46 fclose(fp); 47 }else if(len > size){ 48 truncate(argv[optind],size); 49 } 50 } 51 }
filenameに置き換えます。
34 for(; optind<argc; optind++){ >> filename = argv[optind]; 35 if(stat(filename,&buf) != 0){ >> fp = fopen(filename,"w"); 37 for(i=0; i<size; i++) 38 fputc(value,fp); 39 fclose(fp); 40 }else{ 41 len = buf.st_size; 42 if(len < size){ >> fp = fopen(filename,"a"); 44 for(i=len; i<size; i++) 45 fputc(value,fp); 46 fclose(fp); 47 }else if(len > size){ >> truncate(filename,size); 49 } 50 } 51 }
随分見やすくなりました。
次は、fopenやtruncateを実行後にエラー処理を追加します。一律同じものを入れておきました。
34 for(; optind<argc; optind++){ filename = argv[optind]; 35 if(stat(filename,&buf) != 0){ fp = fopen(filename,"w"); >> if(fp == NULL){ >> perror(filename); >> continue; >> } 37 for(i=0; i<size; i++) 38 fputc(value,fp); 39 fclose(fp); 40 }else{ 41 len = buf.st_size; 42 if(len < size){ fp = fopen(filename,"a"); >> if(fp == NULL){ >> perror(filename); >> continue; >> } 44 for(i=len; i<size; i++) 45 fputc(value,fp); 46 fclose(fp); 47 }else if(len > size){ truncate(filename,size); >> if(fp == NULL){ >> perror(filename); >> continue; >> } 49 } 50 } 51 }
さてビルドして実行。
takk@deb9:~/tmp$ ./a.out -s3 -v100 {1..3}.bin takk@deb9:~/tmp$ ls 1.bin 2.bin 3.bin a.out mytruncate.c takk@deb9:~/tmp$ dump(){ > for i in $@;do echo -n $i ;od -tx1 -An $i;done > } takk@deb9:~/tmp$ dump *.bin 1.bin 64 64 64 2.bin 64 64 64 3.bin 64 64 64 takk@deb9:~/tmp$
新規作成は問題なさそうです。
takk@deb9:~/tmp$ ./a.out -s5 -v50 {1,3}.bin takk@deb9:~/tmp$ dump *.bin 1.bin 64 64 64 32 32 2.bin 64 64 64 3.bin 64 64 64 32 32 takk@deb9:~/tmp$
サイズ追加も大丈夫そうです。
次はサイズカット。
takk@deb9:~/tmp$ ./a.out -s2 3.bin 3.bin: Success takk@deb9:~/tmp$ dump *.bin 1.bin 64 64 64 32 32 2.bin 64 64 64 3.bin 64 64 takk@deb9:~/tmp$
あれ、3.binでSuccessと出てしまいました。
成功したのに、メッセージが出るということは、判定方法が真偽逆なのでしょうか。
grepしてみます。全部NULLかどうかのチェックを入れていたはずです。
takk@deb9:~/tmp$ grep -nC3 NULL mytruncate.c 36- filename = argv[optind]; 37- if(stat(filename,&buf) != 0){ 38- fp = fopen(filename,"w"); 39: if(fp == NULL){ 40- perror(filename); 41- continue; 42- } -- 47- len = buf.st_size; 48- if(len < size){ 49- fp = fopen(filename,"a"); 50: if(fp == NULL){ 51- perror(filename); 52- continue; 53- } -- 56- fclose(fp); 57- }else if(len > size){ 58- truncate(filename,size); 59: if(fp == NULL){ 60- perror(filename); 61- continue; 62- } takk@deb9:~/tmp$
ああtruncateのエラー処理、思いっきり間違えてます。ファイルポインタじゃないのに、fpと比較してます。truncateのmanを確認します。
man 2 truncate
返り値 成功した場合は 0 が返される。エラーの場合は -1 が返され、 errno が適切に設定される。
truncateの戻り値が-1かどうか判定するように修正。
58 if(truncate(filename,size) == -1){ 59 perror(filename); 60 continue; 61 }
ビルドして確認します。
takk@deb9:~/tmp$ !g gcc mytruncate.c takk@deb9:~/tmp$ !./a ./a.out -s2 3.bin takk@deb9:~/tmp$ !du dump *.bin 1.bin 64 64 64 32 32 2.bin 64 64 64 3.bin 64 64 takk@deb9:~/tmp$
OK。今度はSuccessは出ませんでした。
続いて、アクセス権限を変更して確認。
takk@deb9:~/tmp$ sudo chown root.root 2.bin takk@deb9:~/tmp$ sudo chmod 600 2.bin takk@deb9:~/tmp$ ./a.out -s9 *.bin 2.bin: Permission denied takk@deb9:~/tmp$ dump *.bin 1.bin 64 64 64 32 32 00 00 00 00 2.binod: 2.bin: 許可がありません 3.bin 64 64 00 00 00 00 00 00 00 takk@deb9:~/tmp$
Permission deniedと出てくれました。OKですね。
odでアクセスできないので、
lsでサイズを確認します。サイズも変わってません。
takk@deb9:~/tmp$ ls -l *.bin -rw-r--r-- 1 takk takk 9 4月 22 19:49 1.bin -rw------- 1 root root 3 4月 22 19:25 2.bin -rw-r--r-- 1 takk takk 9 4月 22 19:49 3.bin takk@deb9:~/tmp$
権限ありで再実行。
takk@deb9:~/tmp$ sudo ./a.out -s9 *.bin takk@deb9:~/tmp$ ls -l *.bin -rw-r--r-- 1 takk takk 9 4月 22 19:49 1.bin -rw------- 1 root root 9 4月 22 19:52 2.bin -rw-r--r-- 1 takk takk 9 4月 22 19:49 3.bin takk@deb9:~/tmp$
マイtruncateできました。
全ソースです。
takk@deb9:~/tmp$ cat -n mytruncate.c 1 #include <stdio.h> 2 #include <stdlib.h> 3 #include <sys/types.h> 4 #include <sys/stat.h> 5 #include <unistd.h> 6 7 int main(int argc, char* argv[]) 8 { 9 FILE *fp; 10 int i,len,size=0; 11 int value=0; 12 int ch; 13 struct stat buf; 14 char *filename; 15 16 while ((ch = getopt(argc, argv, "s:v:")) != -1){ 17 switch (ch) { 18 case 's': 19 size = atoi(optarg); 20 break; 21 case 'v': 22 value = atoi(optarg); 23 break; 24 default: 25 printf("parameter error\n"); 26 return 1; 27 } 28 } 29 30 if(optind >= argc){ 31 printf("parameter error\n"); 32 return 1; 33 } 34 35 for(; optind<argc; optind++){ 36 filename = argv[optind]; 37 if(stat(filename,&buf) != 0){ 38 fp = fopen(filename,"w"); 39 if(fp == NULL){ 40 perror(filename); 41 continue; 42 } 43 for(i=0; i<size; i++) 44 fputc(value,fp); 45 fclose(fp); 46 }else{ 47 len = buf.st_size; 48 if(len < size){ 49 fp = fopen(filename,"a"); 50 if(fp == NULL){ 51 perror(filename); 52 continue; 53 } 54 for(i=len; i<size; i++) 55 fputc(value,fp); 56 fclose(fp); 57 }else if(len > size){ 58 if(truncate(filename,size) == -1){ 59 perror(filename); 60 continue; 61 } 62 } 63 } 64 } 65 return 0; 66 } 67 takk@deb9:~/tmp$
コメント