システムコール (ほんとうは、システムコールをラップした関数) のopen,close,read,writeを使ったサンプルコードです。
一度openしたファイルをreadするときは、readで読み取った分を記録して、再度readで呼び出すと続きから読み込んでくれるという仕様になっています。
また、readは読み取ったbyte数を返す関数なので、0になるまでwhileでループさせて上げることで終わりまで読み込むことができます。
/* open */
# include <fcntl.h>
/* read */
# include <sys/types.h>
# include <sys/uio.h>
/* read & write & close */
# include <unistd.h>
# define BUF_SIZE 1024
int main(int ac, char **av)
{
int fd;
int rc;
char buf[BUF_SIZE];
if (ac != 2)
{
write(1, "error\n", 6);
return (0);
}
if ((fd = open(av[1], O_RDONLY)) == -1)
{
write(1, "error\n", 6);
return (0);
}
while ((rc = read(fd, buf, BUF_SIZE)))
{
if (rc == -1)
{
write(1, "error\n", 6);
return (0);
}
write(1, buf, rc);
}
close(fd);
return (0);
}
追記 (おまけ)
catコマンドの実装の中身を見ていてwriteに対してもエラー処理をしているのを見つけました。
freebsd/freebsd: FreeBSD src tree (read-only mirror)
writeは外部とつながってないので、エラーの可能性を考慮していなかったのですが、一考の余地ありそうです。
while ((nr = read(rfd, buf, bsize)) > 0)
for (off = 0; nr; nr -= nw, off += nw)
if ((nw = write(wfd, buf + off, (size_t)nr)) < 0)
err(1, "stdout");
if (nr < 0)
{
warn("%s", filename);
rval = 1;
}
ちなみに、close関数に関してはエラーの処理はされていませんでした。