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 } |
