basic_cat.c
#define _LARGEFILE64_SOURCE 1
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <err.h>
static void io_fd_unset_o_nonblock(int fd)
{
int flags = 0;
if ((flags = fcntl(fd, F_GETFL)) == -1)
err(EXIT_FAILURE, "fcntl(F_GETFL)");
if (flags & O_NONBLOCK)
if (fcntl(fd, F_SETFL, flags & ~O_NONBLOCK) == -1)
err(EXIT_FAILURE, "fcntl(F_SETFL, ~O_NONBLOCK)");
}
static void full_write(int fd, const void *buf, size_t len)
{
while (len > 0)
{
ssize_t ret = write(fd, buf, len);
if ((ret == -1) && (errno != EINTR))
err(EXIT_FAILURE, "write");
buf += (size_t)ret;
len -= (size_t)ret;
}
}
static void ex_cat_read_fd_write_stdout(int fd)
{
char buf[BUFSIZ];
ssize_t ret = 0;
while ((ret = read(fd, buf, sizeof(buf))) != 0)
{
if ((ret == -1) && (errno != EINTR))
err(EXIT_FAILURE, "read");
full_write(STDOUT_FILENO, buf, ret);
}
}
int main(int argc, char *argv[])
{
int count = 1;
io_fd_unset_o_nonblock(STDOUT_FILENO);
io_fd_unset_o_nonblock(STDERR_FILENO);
if (count >= argc)
{
io_fd_unset_o_nonblock(STDIN_FILENO);
ex_cat_read_fd_write_stdout(STDIN_FILENO);
}
while (count < argc)
{
int fd = open64(argv[count], O_RDONLY);
if (fd == -1)
err(EXIT_FAILURE, "open(%s)", argv[count]);
ex_cat_read_fd_write_stdout(fd);
if (close(fd) == -1)
warn("close(%s)", argv[count]);
++count;
}
exit (EXIT_SUCCESS);
}