Skip to content

Instantly share code, notes, and snippets.

@orumin
Last active September 3, 2020 05:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save orumin/90139630ebb7562addfde3f908c17fb5 to your computer and use it in GitHub Desktop.
Save orumin/90139630ebb7562addfde3f908c17fb5 to your computer and use it in GitHub Desktop.
modified tee test
#include <sys/types.h>
#include <unistd.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#define check(v) \
do { \
if ((v) < 0) { \
fprintf(stderr, "%s:%d: %s", __func__, __LINE__, strerror(errno)); \
exit(EXIT_FAILURE); \
} \
} while (0)
void usage(const char* name)
{
fprintf(stderr, "Usage: %s [-n 1/2] filename command\n", name);
exit(EXIT_FAILURE);
}
int main(int argc, char **argv)
{
int opt;
int choosed_fileno = 1;
while ((opt=getopt(argc, argv, "n:")) != -1) {
switch (opt) {
case 'n':
choosed_fileno = atoi(optarg);
if (choosed_fileno == 1 || choosed_fileno == 2)
break;
default:
usage(argv[0]);
}
}
if (optind >= argc) {
usage(argv[0]);
}
int idx=optind;
const char* filename = argv[idx];
idx++;
if (idx >= argc) {
usage(argv[0]);
}
const char* comm_name = argv[idx];
idx++;
int pipe_fd[2], pipe_fd2[2];
check(pipe(pipe_fd));
check(pipe(pipe_fd2));
const pid_t pid = fork();
check(pid);
if (pid == 0) {
close(pipe_fd[0]);
close(pipe_fd2[0]);
dup2(pipe_fd[1],STDOUT_FILENO);
dup2(pipe_fd2[1],STDERR_FILENO);
execv(comm_name, &argv[idx]);
} else {
close(pipe_fd[1]);
close(pipe_fd2[1]);
FILE *logfile = filename? fopen(filename, "a") : NULL;
if (filename && !logfile) {
fprintf(stderr, "cannot open file: %s: %s\n", filename, strerror(errno));
exit(EXIT_FAILURE);
}
char ch, ch2;
int err, err2;
err=read(pipe_fd[0],&ch,1);
err2=read(pipe_fd2[0], &ch2, 1);
do {
if (err>0) {
putchar(ch);
if (ch == '\n')
fflush(stdout);
if (choosed_fileno == 1) {
fputc(ch, logfile);
if (ch == '\n')
fflush(logfile);
}
err=read(pipe_fd[0],&ch,1);
}
if (err2>0) {
putchar(ch2);
if (ch2 == '\n')
fflush(stdout);
if (choosed_fileno == 2) {
fputc(ch2, logfile);
if (ch2 == '\n')
fflush(logfile);
}
err2=read(pipe_fd2[0], &ch2, 1);
}
} while (err > 0 || err2 > 0);
putchar('\n');
fputc('\n', logfile);
close(pipe_fd[0]);
close(pipe_fd2[0]);
fclose(logfile);
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment