UNIXworkcode

1 /* 2 * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 3 * Version 2, December 2004 4 * 5 * Copyright (C) 2016 Olaf Wintermann <olaf.wintermann@gmail.com> 6 * 7 * Everyone is permitted to copy and distribute verbatim or modified 8 * copies of this license document, and changing it is allowed as long 9 * as the name is changed. 10 * 11 * DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 12 * TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 13 * 14 * 0. You just DO WHAT THE FUCK YOU WANT TO. 15 */ 16 17 /* 18 * This program adds a log prefix to each stdout line 19 */ 20 21 #define _POSIX_SOURCE 22 #include <stdio.h> 23 #include <stdlib.h> 24 #include <unistd.h> 25 #include <pthread.h> 26 #include <time.h> 27 28 static int std_out_fd; 29 static int pipe_fds[2]; 30 31 void* pipe_filter_thread(void *data) { 32 FILE *std_out = fdopen(std_out_fd, "w"); 33 if(!std_out) { 34 return NULL; 35 } 36 FILE *pipe = fdopen(pipe_fds[0], "r"); 37 if(!pipe) { 38 fclose(std_out); 39 return NULL; 40 } 41 42 int newline = 1; 43 int c; 44 while((c = fgetc(pipe)) != EOF) { 45 if(newline) { 46 char datebuf[64]; 47 struct tm* tm; 48 time_t t; 49 time(&t); 50 tm = localtime(&t); 51 size_t len = strftime(datebuf, 64, "%Y-%m-%d %H:%M:%S stdout: ", tm); 52 fwrite(datebuf, 1, len, std_out); 53 newline = 0; 54 } 55 fputc(c, std_out); 56 if(c == '\n') { 57 newline = 1; 58 fflush(std_out); 59 } 60 } 61 62 fclose(std_out); 63 fclose(pipe); 64 65 return NULL; 66 } 67 68 int main(int argc, char** argv) { 69 std_out_fd = dup(STDOUT_FILENO); 70 if(pipe(pipe_fds) != 0) { 71 perror("pipe"); 72 return EXIT_FAILURE; 73 } 74 75 // make fd 1(stdout) refer to the new pipe 76 dup2(pipe_fds[1], STDOUT_FILENO); 77 close(pipe_fds[1]); 78 79 pthread_t tid; 80 if(pthread_create(&tid, NULL, pipe_filter_thread, NULL) != 0) { 81 perror("pthread_create"); 82 return EXIT_FAILURE; 83 } 84 85 printf("Hello World!\n"); 86 printf("some text\nanother line\n"); 87 fclose(stdout); 88 89 pthread_join(tid, NULL); 90 91 return (EXIT_SUCCESS); 92 } 93