Created
September 11, 2016 07:43
-
-
Save vergeev/a434ce4c20af225a61f570dc7862851f to your computer and use it in GitHub Desktop.
A copy of the command "tee" implemented using unix system calls.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <unistd.h> | |
#include <fcntl.h> | |
#include <string.h> | |
#define MAX_READ 1024 | |
#define MAX_OPEN 128 | |
void printerr(char*); | |
int main(int argc, char *argv[]) { | |
int opt, i; | |
ssize_t bytes_read; | |
char buff[MAX_READ]; | |
int fds[MAX_OPEN]; | |
char* fnames[MAX_OPEN]; | |
int flags = O_WRONLY | O_CREAT | O_TRUNC; | |
int opened = 0; | |
const mode_t perms = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH; | |
while ((opt = getopt(argc, argv, "a")) != -1) | |
switch (opt) { | |
case 'a': | |
flags ^= O_TRUNC; | |
flags |= O_APPEND; | |
} | |
/* open the files */ | |
for (i = optind; i < argc; i++) | |
if (opened < MAX_OPEN) { | |
fnames[opened] = argv[i]; | |
fds[opened] = open(fnames[opened], flags, perms); | |
if (fds[opened] == -1) | |
printerr(strcat(fnames[opened], | |
": can't be opened or created")); | |
else | |
opened++; | |
} else { | |
printerr(strcat(argv[i], | |
": too many files, skipping this and the rest")); | |
break; | |
} | |
/* read and write */ | |
while((bytes_read = read(STDIN_FILENO, buff, MAX_READ)) > 0) { | |
if (write(STDOUT_FILENO, buff, bytes_read) < bytes_read) | |
printerr("error while writing to standard output"); | |
for (i = 0; i < opened; i++) | |
if (write(fds[i], &buff, bytes_read) < bytes_read) | |
printerr(strcat(fnames[i], | |
": couldn't write some data")); | |
} | |
/* close the files */ | |
for (i = 0; i < opened; i++) | |
if (close(fds[i]) == -1) | |
printerr(strcat(fnames[i], | |
": couldn't close, some data may be lost")); | |
if (bytes_read == -1) | |
return 1; | |
return 0; | |
} | |
void printerr(char* msg) | |
{ | |
msg = strcat(msg, "\n"); | |
write(STDERR_FILENO, msg, strlen(msg)); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment