An implementation of tee. The include statements contain tlpi_hdr.h, which can be found in Kerrisk’s book.
/* include libraries. /lib/tlpi_hdr.h is a library that
* is made/used in Linux programming interface*/
#include <sys/stat.h>
#include <fcntl.h>
#include <string.h>
#include <errno.h>
#include "/lib/tlpi_hdr.h"
#include <getopt.h>
#include <ctype.h>
#include <unistd.h>
/* Define buffers, these are directly from Linux Programming interface*/
#ifndef BUF_SIZE /*Allow "cc -D" to override definition */
#define BUF_SIZE 1024
#endif
int main(int argc, char *argv[])
{
int outputFd, openFlags; /* Initialize outputfile and flags*/
/*Command-line options.
* afnd is used to check if -a flag is found (see TLPI appendix B */
int opt, afnd;
mode_t filePerms; /* File permissions */
ssize_t numRead;
char buf[BUF_SIZE+1]; /*So that we have null byte */
afnd=0;
/* Check arguments*/
if(argc == 1 || strcmp(argv[1], "--help") == 0)
{
printf("Program needs at least 1 argument\n");
exit(EXIT_FAILURE);
}
/* Command-line arguments cases, this implementation only uses -a to check if we append*/
while((opt = getopt(argc, argv, ":a")) != -1)
{
switch(opt)
{
case 'a':
afnd++;
break;
case ':':
afnd=0;
break;
default:
afnd=0;
}
}
/* From command-line arguments we deduce appending or not.
* I use the approach in Appendix B for this*/
if(afnd!=0)
{
openFlags = O_CREAT | O_WRONLY | O_APPEND;
}
else
{
openFlags = O_CREAT | O_WRONLY | O_TRUNC;
}
filePerms = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
/* Create outputfile
* This may or may not be the optimal approach,
* using argv[optind] to determine all other command-line arguments*/
outputFd = open(argv[optind], openFlags, filePerms);
if(outputFd == -1)
{
printf("%s\n",strerror(errno));
exit(EXIT_FAILURE);
}
/* Reading using while
* Earlier implementations read in 1024 bytes and wrote just that
* but calling e.g.
* $ man man | .mytee outputfile.txt
* only wrote the first ~ 490 characters
* This works*/
while((numRead = read(STDIN_FILENO, buf, BUF_SIZE))>0)
{
if(write(outputFd,buf, numRead) != numRead)
{
printf("Could not write whole buffer\n");
exit(EXIT_FAILURE);
}
}
/* Add the terminating null byte since we make space for it*/
buf[numRead] = '\0';
write(outputFd, buf, numRead);
/* Check for errors*/
if(numRead == -1)
{
printf("%s\n",strerror(errno));
exit(EXIT_FAILURE);
}
/* Close the output file */
if(close(outputFd) == -1)
{
printf("%s\n", strerror(errno));
exit(EXIT_FAILURE);
}
exit(EXIT_SUCCESS);
}