アプリ版:「スタンプのみでお礼する」機能のリリースについて

はじめまして。C言語(というかプログラミング自体)まったくの初心者です。

mmapで自作catコマンドを作りたいのですが、
以下のソースコードでコンパイルできたものの、
a.outするとsegmentation faultとなってしまいます。
もしよろしければ何がいけないか、ご指摘いただけると嬉しいです。

1 #include<sys/types.h>
2 #include<sys/stat.h>
3 #include<sys/mman.h>
4 #include<fcntl.h>
5 #include<unistd.h>
6 #include<stdio.h>
7 #include<string.h>
8
9 int main (int argc, char*argv[]){
10
11 int fd;
12 char *m;
13 int size;
14
15 if(argc < 3){
16 open(argv[1],O_RDWR);
17 }
18
19 fd = open(argv[1], O_RDWR);
20 if(fd < 0){
21 printf("error\n");
22 }else{
23 fseek(0, 0L, SEEK_END);
24 size = ftell(0);
25 }
26
27 m = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
28
29 if(m == MAP_FAILED){
30 printf("error\n");
31 }else{
32 write(1,m,strlen(m));
33
34 close(fd);
35 return 0;
36 }
37 }

A 回答 (3件)

23行目のfseek()の最初の引数が 0 なのがおかしいです。

これが segmentation fault の原因です。ファイルポインタでなければいけません。ファイルディスクリプタの0番は指定できません。標準入力を意図したなら。

そもそもfopen()ではなくopen()でファイルを開いていますね。それなら23,24行目は下記のようにしてファイルサイズを調べた方がよいでしょう(これはファイルからの読み込みだけで標準入力は考えていません)。
 struct stat status;
 if (fstat(fd, &status)) {
  printf("error\n");
  close(fd);
  return 1;
 }
 size = (int) status.st_size;


15 ~ 17 行目は無意味ですね。コマンドライン引数が無いときエラーとすればよいでしょう。
 if(argc < 2){
  printf("error\n");
  return 1;
 }

21行目と30行目の直後も、エラー終了するためのreturnかexitを入れ忘れていますね。
まずは、プログラムをよく見直した方がよいでしょう。
    • good
    • 0

色々と原因が考えられます。


もうすこし落ち着いて、何をやっているのか考えた方がよいでしょう。
少なくとも、自分で書いたプログラムくらい解説できるくらいでないと。
勉強中なら、このようなことするには早すぎると思います。

> 15 if(argc < 3){
> 16 open(argv[1],O_RDWR);
> 17 }

ここでは何をやっているのですか?argc<3との関連が意味がわかりません。
openした結果を何も使ってません。

> 19 fd = open(argv[1], O_RDWR);
> 20 if(fd < 0){
> 21 printf("error\n");
> 22 }else{
> 23 fseek(0, 0L, SEEK_END);
> 24 size = ftell(0);
> 25 }

19で失敗すると、21行を実行します。ただそのまま26行目以降も実行していくので、
・失敗してファイルが開けず、-1が入ったままのfd
・初期化されていないため、なには入っているかわからないままのsize

> m = mmap(NULL, size, PROT_READ, MAP_SHARED, fd, 0);
に渡されます。
    • good
    • 0

>write(1,m,strlen(m));



なぜstrlen()してるのでしょう?
    • good
    • 0

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