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  }