続きです。エラー処理を入れていきます。
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$


コメント