• ベストアンサー

mmap()を使ったファイルへの書き込みで…

chirubouの回答

  • ベストアンサー
  • chirubou
  • ベストアンサー率37% (189/502)
回答No.1

お酒が入っているので、確認しません。記憶だけで。 「この流れをループで行っていると1万回を超えたあたりでopen()がNGになりますが、何故でしょう?」 munmap() していないので、メモリ空間が無くなったのではないでしょうか?mmap() のサイズが 4KB とすると 1000回やって 4GB ですから。メモリ空間(あるいは mmap() できるアドレス空間)が足りなくなっても不思議ではないですね。 「ちなみにループの中でclose()するのを忘れると1千回を超えたあたりでopen()がNGになるのは #define FD_SETSIZE 1024 だからという予想で合っているでしょうか?」 ここはちょっと OS 依存ですが、Linux(Unix) だったらプロセスがオープンできるファイル数の上限が setrlimit() で設定できます。FD_SETSIZE は select(2) で使われる struct fdset における fd の上限というのが正しいハズ。勿論実装によっては FD_SETSIZE 以上にファイルをオープンできない、というのは十分に考えられます。

uya_15
質問者

お礼

ご指摘通りメモリの枯渇だったみたいです

関連するQ&A

  • mmapで自作cat

    はじめまして。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 }

  • Pythonでのmmapの使い方

    よろしくお願いします。 現在、SH3LSR7706マイコンのLEDを点滅させるプログラムをPythonで実装しています。 そこで、 http://mes.sourceforge.jp/mes2/index-j.html こちらにあるプログラムを参考にさせていただいてるのですが C言語で以下のように書いてある部分をPythonで書くにはどうすればよいでしょうか? <<< code mmaped = (volatile unsigned char*)mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0xa4000000); >>> Pythonのドキュメントよると http://www.python.jp/doc/2.4/lib/module-mmap.html mmapメソッドにoffsetの引数を渡すところがないので、↑プログラムの「0xa4000000」の部分をどうすればよいのか教えてください。 今は、↓のように書いてますがこれだとオフセットの指定がないので意図した意図したアドレスにアクセスできません。(Pythonのバージョンは2.5です) <<< code mmap.mmap(fd.fileno(), mmap.PAGESIZE, mmap.MAP_SHARED, mmap.PROT_READ | mmap.PROT_WRITE) >>> よろしくお願いします。 参考にさせて頂いているプログラム <<< code #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> #include <stdlib.h> #include <stdio.h> #include <string.h> #include <sys/mman.h> #include <asm/page.h> #define SCPDR 0x136 #define LED 0x10 int main() { volatile unsigned char *mmaped, scpdr; int fd, i; fd = open("/dev/mem",O_RDWR); if(fd < 0) { fprintf(stderr,"cannot open /dev/mem\n"); return 1; } mmaped = (volatile unsigned char*)mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0xa4000000); close(fd); if(mmaped == MAP_FAILED) { fprintf(stderr,"cannot mmap\n"); return 1; } for(i = 0;i < 3;i++) { mmaped[SCPDR] |= LED; sleep(1); mmaped[SCPDR] &= ~LED; sleep(1); } munmap((char*)mmaped, PAGE_SIZE); return 0; } >>>

  • テキストファイルが開けません。

    main関数に2つの引数をとり、第1引数で指定したファイルの内容を第2引数で指定したファイルにコピーするプログラムを以下のように作りました。 #include<stdio.h> #include<fcntl.h> int main(int argc, char* argv[]){ int fd1, fd2, rs, ws; char buffer[10000]; if(argc!=3){ write(2, "使用法:実行ファイル コピー元ファイル コピー先ファイル\n", 54); exit(1); } fd1=open(argv[1], O_RDONLY); if(fd1<0){ fprintf(stderr, "can't open file '%s'.\n", argv[1]); exit(1); } fd2=open(argv[2], O_WRONLY|O_CREAT|O_TRUNC); if(fd2<0){ fprintf(stderr, "can't open file '%s'.\n", argv[2]); exit(1); } while((rs=read(fd1, buffer, 10000))>0){ if((ws=write(fd2, buffer, rs))!=rs){ write(2, "an error occurred while copying.\n"); exit(1); } } close(fd1); close(fd2); } コンパイル、実行ともに正常終了したのですが、 コピー先のテキストファイルを開こうとすると、 「アクセスは拒否されました。」というダイアログが表示されて 開くことができません。 なぜなのでしょうか。 よろしくお願いします。 ちなみにOSはWindows Vistaで、 プログラムはcygwin上で実行しました。

  • 低水準ファイル入出力

    openを用いてファイル:"test.dat"を開き、そのファイルにbuffに示すような適当なデータを書き込みたいのですが、 下記の様に記述してコンパイル、実行した結果"test.dat"内には何も記述されていませんでした。 自分でも調べてみたのですがどうしても上手くいかず、この場で質問させて頂きます。 ご指摘の程宜しくお願いします<(_ _)> #include <stdio.h> #include <sys/stat.h> #include <sys/types.h> #include <fcntl.h> int main(void) {  char buff[]={"test123456789"};  int fd;  fd=open("test.dat",O_CREAT,S_IREAD|S_IWRITE);  if(fd==-1)   {    close(fd);    fd=open("test.dat",O_WRONLY);    if(fd == -1)    {      printf("open error <file>");      return 1;    }   }  write(fd,buff,sizeof(buff));  close(fd);  return 1; } ---- 私の環境 ---- Vine Linux 2.6r4

  • このプログラムの動作について教えてください

    #include<stdio.h> #include<unistd.h> #define SIZE 10 int main(int argc,char *argv[]){ int fd; char buf[SIZE]; fd=open("data",0); read(fd,buf,10) write(1,buf,10); close(fd); rerutn 0; } というプログラムで dataの中身が以下のテキストファイルとなっているようなのんですが dataの内容:abcdefghijklmnopqrstuvwxyz このプログラムの出力結果がabcabcabce となるとの事なのですが何故でしょうか? 普通に先頭から10バイト分読み込んで出力するならabcdefghijとなるのではないのでしょうか? どうぞご教授お願いします

  • C言語で自作したcpコマンドが上手く動作しません

    当方、プログラミングを勉強中の学生です。 先日、ファイル入出力関数を用いてcpコマンドを自作しました。 一応、コンパイルは通るのですが、コピーしたファイルを開くことができません。 そのファイルのパーミッションを確認してみたところ 「----------」となっており、読み書き実行すべて不可となっていました。 ソースは以下の通りなのですが、何が問題でしょうか。 回答よろしくお願い致します。 #include<stdio.h> #include<fcntl.h> #include <string.h> #include <errno.h> #include <sys/types.h> #include <sys/uio.h> #include <unistd.h> #define SIZE 8192 int main(int argc, char *argv[]) { int fd1, fd2; char buf[SIZE]; if ( argc != 3 ){ char err_message[] = "ファイル名を指定して下さい。\n"; write(2, err_message, strlen(err_message)); return 1; } argv[0] = "mycopy"; fd1 = open(argv[1], O_RDONLY); fd2 = open(argv[2], O_WRONLY | O_CREAT); if (fd1 < 0 || fd2 < 0) { char err_message[] = "ファイルをオープンできません。"; write(2, err_message, strlen(err_message)); write(2, strerror(errno), strlen(strerror(errno))); write(2, "\n", 1); return 1; } while(1) { if (read(fd1, buf, SIZE) == 0) { break; } else if (read(fd1, buf, SIZE) > 0) { write(fd2, buf, SIZE); } else { char err_message[] = "エラーが発生しました。"; write(2, err_message, strlen(err_message)); write(2, strerror(errno), strlen(strerror(errno))); write(2, "\n", 1); return 1; } } close(fd1); close(fd2); return 0; }

  • ループ回数を、保存するファイル名に入れる方法

    FORTRANで、ループする毎に異なるファイルにデータを保存するプログラム(ファイル名の中にループ回数入れたい)を組みたいと思っており、自分で調べて、FORTRAN90なら例えば character*32 roop do i=1,100 write(roop,*)i open(1,FILE='file_'//adjustl(trim(roop))//'.dat') write(1,*)data close(1) enddo というようにwrite文で文字型変数に変換し、adjustlとtrimを使って余分な空白を取り除いて、//で結合すれば実現できることはわかったのですがこれと同じ事をFORTRAN77でやりたいと思っています。 困っているのはadjustlとtrimの部分をFORTRAN77で実現するところなのですが、なにかよい方法はありませんでしょうか? どうぞよろしくお願いいたします。

  • Perl 書き込み行の順番、読み込み

    #!/usr/bin/perl require "cgi-lib.pl"; print "Content-type: text/html\n\n"; ############ 書き込み ############# $file = "sample.txt"; print qq! <font size="1">コード入力<form method=POST action="./houkoku.cgi"> <input type="text" name="rank"> <br><br> <input type="submit" value="送信"> </form>!; use CGI; $query = CGI->new; $rank = $query->param('rank'); open( WRITE, ">> $file" ); print WRITE"$rank\n"; close ( WRITE ); ############ 読み込み ############# print "<table border=1>"; open( READ, "<$file" ); $adam = <READ>; while( $adam = <READ> ) { chomp ( $adam ); @column = split(",",$adam); print "<tr><td>@column[0]</td></tr>"; } close(READ); __END__ のようにして、送信されたものを表示していくようにしたいのですが、 新しい書き込みが下段に追加されてい行きます。 新しいものを上段へ表示したいのですが、 どのようにしたら良いでしょうか? sample.txtにも、新しいものが下に記入されています。 上段への書き込みのやりかたをご教授いただけたらと思います。、 よろしくお願いします。

    • ベストアンサー
    • Perl
  • 行数でなく内容を取得するには

    70<>9<>1日目<>3<>業務の流れについての概説<> こういった中身のtest.txtがあります。 open(READ_FILE,"<test.txt"); @file = <READ_FILE>; @data = split(/<>/,@file); close(READ_FILE); open(WRITE_FILE, ">test02.txt"); print WRITE_FILE "@data"; close(WRITE_FILE); このようにすれば、test2.txtは、次のようになると思ったのですが、 70 9 1日目pm 3 新薬開発の流れについての概説 行数を表示しているようで、「1」となります。 (ためしにtest.txtの行を増やしたらその行数を反映していました) どこが間違っているのかお教えいただけますでしょうか。

    • ベストアンサー
    • CGI
  • 配列のファイル出力について

    fortranでできるファイルへの配列の出力をC言語でどのようにプログラムするか教えて頂きたいと思います。 2次元配列a(i,j)の出力はfortranでは以下のようなプログラムになります。 open(10,.省略...) ファイルを指定して開く do j=1,ny                ループj   write(10,'(100f10.3)') (a(i,j),i=1,nx) ループi+書き出し enddo                  ループjの最後尾  close(10)                ファイルを閉じる 100f10.3というのは小数点3桁の実数で10カラムで表現したものが100個並ぶという意味です。これと同じことをやるC言語プログラムを教えて頂きたいのですが。私の手元にある本にはやり方が載っていません。 C言語にはfortranのような数字のカラムを指定するようなフォーマットの調整などできるのでしょうか。よろしくお願いします。