5.8 練習問題の解答

P100
練習問題。

1. 本章で作ったcatコマンドを改造して、コマンドライン引数でファイル名が渡されなかったら標準入力を読むようにしなさい。

do_cat()をオーバーロードして、

static void do_cat( const char *path );
static void do_cat( int fd );

として1番目の中でopen()して2番目のやつを呼んでclose()すれば今まで通りで、標準入力の場合は2番目を直接呼べばいいと思ったんだけどコンパイルエラーになりました。

cat.c:10: error: conflicting types for `do_cat'
cat.c:9: error: previous declaration of `do_cat'

オーバーロードってC++だっけ?
こうした。

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>

#define BUF_SIZE 1024

static void do_cat( const char *pfile );
static void do_cat_with_fd( int fd );
static void die( const char *s );

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

    if ( argc < 2 ) {
        //fprintf( stderr, "%s: file name is not given.?n", argv[0] );
        do_cat_with_fd(STDIN_FILENO);
        exit(1);
    }

    for ( i = 1; i < argc; i++ ) {
        do_cat(argv[i]);
    }

    exit(0);
}

static void
do_cat( const char *pfile ) {
    int fd = open( pfile, O_RDONLY );
    if (fd < 0) die(pfile);
    
    do_cat_with_fd(fd);

    if ( close (fd) < 0 ) die(pfile);
}

static void
do_cat_with_fd ( int fd ) {
    unsigned char buf[BUF_SIZE];

    while (1) {
        int buf_read = read(fd, buf, sizeof buf);
        if (buf_read < 0)  die("");
        if (buf_read == 0) break;
        if ( write(STDOUT_FILENO, buf, buf_read) < 0 ) die("");
    }
}

static void
die ( const char *s ) {
    perror(s);
    exit(1);
}

関数名がダサイ。
P443
解答。

サンプルコードのcat3.cを参照してください。

ふつうのLinuxプログラミング
でさ、このcat3.cがどうみてもこの章で作ったcatから派生したものとは思えないんですけど。
やれやれ。