FreeCalypso > hg > fc-rfcal-tools
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 } |