comparison scripts/fc-rfcal-tee.c @ 90:713749548df6

fc-rfcal-tri900 script and fc-rfcal-tee helper implemented
author Mychaela Falconia <falcon@freecalypso.org>
date Mon, 17 Jul 2017 05:51:31 +0000
parents
children
comparison
equal deleted inserted replaced
89:0937d34fb3ba 90:713749548df6
1 /*
2 * This C program is a workaround for a stupidity in Bourne shell.
3 * I would like to have a shell script like the following:
4 *
5 * set -e
6 * fc-rfcal-vcxo | tee vcxo
7 * fc-rfcal-rxband 900 | tee rx-900
8 * fc-rfcal-rxband 1800 | tee rx-1800
9 * ...
10 *
11 * and if one of the fc-rfcal-* steps encounters an error and returns
12 * a non-zero exit code, I want the script to stop right there, hence
13 * the set -e at the beginning. Sounds like a very simple and reasonable
14 * desire, doesn't it? But oh noes - because I am piping the output
15 * through tee in order to save it in log files, the process return
16 * codes from fc-rfcal-* get *ignored* by the shell (the always successful
17 * exit code from tee is all that counts), and it will keep executing
18 * the following lines without stopping.
19 *
20 * This C program is like tee, but with invokation of the "main" command
21 * whose output is to be saved built in. The process forks, the "main"
22 * command is executed in the child, the parent performs the tee function,
23 * and when the child terminates, the parent propagates its exit code.
24 */
25
26 #include <sys/types.h>
27 #include <sys/file.h>
28 #include <sys/wait.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32
33 char shell_pathname[] = "/bin/sh";
34 int log_fd;
35
36 tee_process(pipe_fd)
37 {
38 char buf[1024];
39 int cc;
40
41 while ((cc = read(pipe_fd, buf, sizeof buf)) > 0) {
42 write(1, buf, cc);
43 if (log_fd > 2)
44 write(log_fd, buf, cc);
45 }
46 }
47
48 main(argc, argv)
49 char **argv;
50 {
51 int p[2];
52 pid_t child, waitres;
53 int status;
54
55 if (argc != 3) {
56 fprintf(stderr, "usage: %s command logfile\n", argv[0]);
57 exit(1);
58 }
59 if (pipe(p) < 0) {
60 perror("pipe");
61 exit(1);
62 }
63 child = fork();
64 if (child < 0) {
65 perror("fork");
66 exit(1);
67 }
68 if (!child) {
69 dup2(p[1], 1);
70 close(p[0]);
71 close(p[1]);
72 execl(shell_pathname, "sh", "-c", argv[1], 0);
73 perror(shell_pathname);
74 exit(1);
75 }
76 close(p[1]);
77 log_fd = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC, 0666);
78 if (log_fd < 0)
79 perror(argv[2]);
80 tee_process(p[0]);
81 waitres = waitpid(child, &status, 0);
82 if (waitres == child && WIFEXITED(status))
83 exit(WEXITSTATUS(status));
84 else
85 exit(1);
86 }