Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 1 | /* vi: set sw=4 ts=4: */ |
| 2 | /* |
| 3 | * Mini watch implementation for busybox |
| 4 | * |
| 5 | * Copyright (C) 2001 by Michael Habermann <mhabermann@gmx.de> |
| 6 | * |
| 7 | * This program is free software; you can redistribute it and/or modify |
| 8 | * it under the terms of the GNU General Public License as published by |
| 9 | * the Free Software Foundation; either version 2 of the License, or |
| 10 | * (at your option) any later version. |
| 11 | * |
| 12 | * This program is distributed in the hope that it will be useful, |
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 | * General Public License for more details. |
| 16 | * |
| 17 | * You should have received a copy of the GNU General Public License |
| 18 | * along with this program; if not, write to the Free Software |
| 19 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
| 20 | * |
| 21 | */ |
| 22 | |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 23 | /* BB_AUDIT SUSv3 N/A */ |
| 24 | /* BB_AUDIT GNU defects -- only option -n is supported. */ |
| 25 | |
| 26 | /* Mar 16, 2003 Manuel Novoa III (mjn3@codepoet.org) |
| 27 | * |
| 28 | * Removed dependency on date_main(), added proper error checking, and |
| 29 | * reduced size. |
| 30 | */ |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 31 | |
| 32 | #include <stdio.h> |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 33 | #include <stdlib.h> |
| 34 | #include <string.h> |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 35 | #include <limits.h> |
| 36 | #include <time.h> |
| 37 | #include <assert.h> |
| 38 | #include <unistd.h> |
Eric Andersen | 29f9b2f | 2002-12-11 04:25:02 +0000 | [diff] [blame] | 39 | #include <sys/wait.h> |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 40 | #include "busybox.h" |
| 41 | |
| 42 | extern int watch_main(int argc, char **argv) |
| 43 | { |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 44 | const int header_len = 40; |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 45 | time_t t; |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 46 | pid_t pid; |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 47 | unsigned period = 2; |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 48 | int old_stdout; |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 49 | int len, len2; |
| 50 | char **watched_argv; |
| 51 | char header[header_len + 1]; |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 52 | |
| 53 | if (argc < 2) { |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 54 | bb_show_usage(); |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 55 | } |
| 56 | |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 57 | /* don't use getopt, because it permutes the arguments */ |
| 58 | ++argv; |
| 59 | if ((argc > 3) && !strcmp(*argv, "-n") |
| 60 | ) { |
| 61 | period = bb_xgetularg10_bnd(argv[1], 1, UINT_MAX); |
| 62 | argv += 2; |
| 63 | } |
| 64 | watched_argv = argv; |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 65 | |
| 66 | /* create header */ |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 67 | |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 68 | len = snprintf(header, header_len, "Every %ds:", period); |
| 69 | /* Don't bother checking for len < 0, as it should never happen. |
| 70 | * But, just to be prepared... */ |
| 71 | assert(len >= 0); |
| 72 | do { |
| 73 | len2 = strlen(*argv); |
| 74 | if (len + len2 >= header_len-1) { |
| 75 | break; |
| 76 | } |
| 77 | header[len] = ' '; |
| 78 | memcpy(header+len+1, *argv, len2); |
| 79 | len += len2+1; |
| 80 | } while (*++argv); |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 81 | |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 82 | header[len] = 0; |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 83 | |
| 84 | /* thanks to lye, who showed me how to redirect stdin/stdout */ |
| 85 | old_stdout = dup(1); |
| 86 | |
| 87 | while (1) { |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 88 | time(&t); |
| 89 | /* Use dprintf to avoid fflush()ing stdout. */ |
| 90 | if (dprintf(1, "\033[H\033[J%-*s%s\n", header_len, header, ctime(&t)) < 0) { |
| 91 | bb_perror_msg_and_die("printf"); |
| 92 | } |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 93 | |
| 94 | pid = vfork(); /* vfork, because of ucLinux */ |
| 95 | if (pid > 0) { |
| 96 | //parent |
| 97 | wait(0); |
| 98 | sleep(period); |
| 99 | } else if (0 == pid) { |
| 100 | //child |
| 101 | close(1); |
| 102 | dup(old_stdout); |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 103 | if (execvp(*watched_argv, watched_argv)) { |
| 104 | bb_error_msg_and_die("Couldn't run command\n"); |
| 105 | } |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 106 | } else { |
Manuel Novoa III | cad5364 | 2003-03-19 09:13:01 +0000 | [diff] [blame] | 107 | bb_error_msg_and_die("Couldn't vfork\n"); |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 108 | } |
| 109 | } |
Glenn L McGrath | 18b76e6 | 2002-09-16 09:10:04 +0000 | [diff] [blame] | 110 | } |