APUE Memo

Chapter 5 Standard I/O Library

#include <stdio.h>
#include <wchar.h>
int fwide(FILE *stream, int mode);

A stream is associated with an external file (which may be a physical device) by opening a file, which may involve creating a new file. Creating an existing file causes its former contents to be discarded. …

5.4 バッファリング

完全バッファリング

行バッファリング

アンバッファド

標準バッファリングの慣習

バッファ方法の設定

5.5 オープン

オープンのモード

The fdopen() function associates a stream with the exsisting file descriptor, fd. The mode of the stream (…) must be compatible with the mode of the file descriptor. The file position indicator of the new stream is set to that belonging to fd, and the error and end-of-file indicators are cleared. Modes “w” or “w+” do not cause transaction of the file. The file descriptor is not dup’ed, and will be closed when the stream created by fdopen is closed. …

ファイルのクローズ

5.6-5.8 文字出力

入力 getc, fgetc, getchar

出力 putc, fputc, putchar

行単位の入出力

This daemon program accepts connection from remote programs, reads a single line of input, and then sends back output matching the received request. * ワームはバッファオーバーフローを意図的に引き起こして、スタックフレームを書き換え、プログラムの振る舞いを変えた。

効率

echof.c: 関数 ver

| real | user | system | | .068 | .058 | .014 | | .057 | .049 | .014 | | .058 | .046 | .014 | | .065 | .053 | .020 | | .065 | .051 | .017 | | .058 | .047 | .016 |

echo.c: 関数かもしれない ver

| real | user | system | | .060 | .050 | .015 | | .062 | .052 | .014 | | .058 | .046 | .016 | | .055 | .042 | .018 | | .055 | .046 | .013 | | .056 | .047 | .012 |

echol.c: 行バッファ ver

| real | user | system | | .017 | .003 | .019 | | .012 | .003 | .013 | | .019 | .008 | .017 | | .017 | .004 | .017 | | .018 | .005 | .018 | | .015 | .006 | .014 |

echosys.c: read システムコール, バッファサイズ=1

| real | user | system | | .724 | .081 | .647 | | .742 | .092 | .654 | | .715 | .085 | .632 | | .721 | .094 | .631 | | .750 | .084 | .670 | | .709 | .094 | .618 | | .743 | .094 | .652 |

5.9-5.10 バイナリ操作

float data[10];
if ( fwrite(&data[2], sizeof(float), 4, fp) != 4 ) {
   // error handing...
}
struct {
  short count;
  long total;
  char name[NAMESIZE]
} item;
if (fwrite(&item, sizeof(item), 1, fp) != 1) {
   // error handing...
}

異なるシステム間で使いにくい

$ od -t cx1 user.bin 
0000000      \0  \0  \0   f   f   f   ?   a   n   n  \0                
         20  00  00  00  66  66  66  3f  61  6e  6e  00  20  20  20  20
0000020                
         20  20  20  20
0000024
$ od -t cx1 user.bin 
0000000      \0  \0  \0   f   f   f   ?   a   n   n  \0                
         20  00  00  00  66  66  66  3f  61  6e  6e  00  20  20  20  20
0000020                
         20  20  20  20
0000024

5.11 書式付き入出力

5.12 FILE ストリームの定義

サンプル: 標準入出力ライブラリバッファリングの表示

#include <stdio.h>

void pr_stdio(const char *, FILE *);
int buffer_size(FILE *fp);

int main(int argc, char *argv[])
{
  FILE *fp;

  fputs("enter any char\n", stdout);
  if ( getchar() == EOF )
    return 0;
  fputs("one line to stderr\n", stderr);

  pr_stdio("stdin", stdin);
  pr_stdio("stdout", stdout);
  pr_stdio("stderr", stderr);
}

void pr_stdio(const char* name, FILE *fp)
{
  printf("stream = %s ", name);
  printf("%x, ", fp->_flags);
  if ( fp->_flags & _IO_UNBUFFERED ) {
    printf("unbuffered");
  } else if ( fp->_flags & _IO_LINE_BUF ) {
    printf("line buffered");
  } else {
    printf("fully buffered");
  }
  printf(", buffer size=%d\n", buffer_size(fp));
}

int buffer_size(FILE *fp)
{
  return(fp->_IO_buf_end - fp->_IO_buf_base);
}
xxx@penguin:~/root$ ./chk_bfr 
enter any char

one line to stderr
stream = stdin fbad2288, line buffered, buffer size=1024
stream = stdout fbad2a84, line buffered, buffer size=1024
stream = stderr fbad2887, unbuffered, buffer size=1
xxx@penguin:~/root$ ./chk_bfr <./chk_bfr.c >chk_bfr.log 2>chk_bfr.err
xxx@penguin:~/root$ cat chk_bfr.log
enter any char
stream = stdin fbad2088, fully buffered, buffer size=4096
stream = stdout fbad2884, fully buffered, buffer size=4096
stream = stderr fbad2887, unbuffered, buffer size=1

5.13 一時ファイル

関係ないけど、 man fcntl に File and Directory change notification (dnotify) があった。 シグナルで教えてくれるらしいが、どこのプロセスへのシグナル?

5.14 メモリストリーム

fmemopen した後のファイル位置

他のメモリストリーム

5.15 欠点