10 |
*/ |
*/ |
11 |
|
|
12 |
#include "libbb.h" |
#include "libbb.h" |
13 |
|
#include "linux/types.h" /* for __u32 */ |
14 |
#include "linux/watchdog.h" |
#include "linux/watchdog.h" |
15 |
|
|
16 |
#define OPT_FOREGROUND (1 << 0) |
#define OPT_FOREGROUND (1 << 0) |
33 |
static const struct suffix_mult suffixes[] = { |
static const struct suffix_mult suffixes[] = { |
34 |
{ "ms", 1 }, |
{ "ms", 1 }, |
35 |
{ "", 1000 }, |
{ "", 1000 }, |
36 |
{ } |
{ "", 0 } |
37 |
}; |
}; |
38 |
|
|
39 |
unsigned opts; |
unsigned opts; |
45 |
opt_complementary = "=1"; /* must have exactly 1 argument */ |
opt_complementary = "=1"; /* must have exactly 1 argument */ |
46 |
opts = getopt32(argv, "Ft:T:", &st_arg, &ht_arg); |
opts = getopt32(argv, "Ft:T:", &st_arg, &ht_arg); |
47 |
|
|
48 |
|
/* We need to daemonize *before* opening the watchdog as many drivers |
49 |
|
* will only allow one process at a time to do so. Since daemonizing |
50 |
|
* is not perfect (child may run before parent finishes exiting), we |
51 |
|
* can't rely on parent exiting before us (let alone *cleanly* releasing |
52 |
|
* the watchdog fd -- something else that may not even be allowed). |
53 |
|
*/ |
54 |
|
if (!(opts & OPT_FOREGROUND)) |
55 |
|
bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); |
56 |
|
|
57 |
if (opts & OPT_HTIMER) |
if (opts & OPT_HTIMER) |
58 |
htimer_duration = xatou_sfx(ht_arg, suffixes); |
htimer_duration = xatou_sfx(ht_arg, suffixes); |
59 |
stimer_duration = htimer_duration / 2; |
stimer_duration = htimer_duration / 2; |
67 |
|
|
68 |
/* WDIOC_SETTIMEOUT takes seconds, not milliseconds */ |
/* WDIOC_SETTIMEOUT takes seconds, not milliseconds */ |
69 |
htimer_duration = htimer_duration / 1000; |
htimer_duration = htimer_duration / 1000; |
70 |
|
#ifndef WDIOC_SETTIMEOUT |
71 |
|
# error WDIOC_SETTIMEOUT is not defined, cannot compile watchdog applet |
72 |
|
#else |
73 |
|
# if defined WDIOC_SETOPTIONS && defined WDIOS_ENABLECARD |
74 |
|
{ |
75 |
|
static const int enable = WDIOS_ENABLECARD; |
76 |
|
ioctl_or_warn(3, WDIOC_SETOPTIONS, (void*) &enable); |
77 |
|
} |
78 |
|
# endif |
79 |
ioctl_or_warn(3, WDIOC_SETTIMEOUT, &htimer_duration); |
ioctl_or_warn(3, WDIOC_SETTIMEOUT, &htimer_duration); |
80 |
|
#endif |
81 |
|
|
82 |
#if 0 |
#if 0 |
83 |
ioctl_or_warn(3, WDIOC_GETTIMEOUT, &htimer_duration); |
ioctl_or_warn(3, WDIOC_GETTIMEOUT, &htimer_duration); |
84 |
printf("watchdog: SW timer is %dms, HW timer is %dms\n", |
printf("watchdog: SW timer is %dms, HW timer is %ds\n", |
85 |
stimer_duration, htimer_duration * 1000); |
stimer_duration, htimer_duration * 1000); |
86 |
#endif |
#endif |
87 |
|
|
|
if (!(opts & OPT_FOREGROUND)) { |
|
|
bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); |
|
|
} |
|
|
|
|
88 |
while (1) { |
while (1) { |
89 |
/* |
/* |
90 |
* Make sure we clear the counter before sleeping, as the counter value |
* Make sure we clear the counter before sleeping, |
91 |
* is undefined at this point -- PFM |
* as the counter value is undefined at this point -- PFM |
92 |
*/ |
*/ |
93 |
write(3, "", 1); /* write zero byte */ |
write(3, "", 1); /* write zero byte */ |
94 |
usleep(stimer_duration * 1000L); |
usleep(stimer_duration * 1000L); |