diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-09-07 23:22:08 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-09-07 23:22:08 +0000 |
commit | 8d89bed8401bfbca9c5ef18f201439b3502e733b (patch) | |
tree | b5db7bd373d32b4891610cd2c58f6307d4808447 | |
parent | ee9deb863e089e1b607cc5771123257c3223bea0 (diff) | |
download | busybox-w32-8d89bed8401bfbca9c5ef18f201439b3502e733b.tar.gz busybox-w32-8d89bed8401bfbca9c5ef18f201439b3502e733b.tar.bz2 busybox-w32-8d89bed8401bfbca9c5ef18f201439b3502e733b.zip |
watchdog: add -T option
function old new delta
watchdog_main 159 219 +60
mdev: support match by major,minor. See bug 4714.
+100 bytes.
-rw-r--r-- | debianutils/start_stop_daemon.c | 2 | ||||
-rw-r--r-- | docs/mdev.txt | 6 | ||||
-rw-r--r-- | include/usage.h | 7 | ||||
-rw-r--r-- | libpwdgrp/uidgid_get.c | 5 | ||||
-rw-r--r-- | miscutils/watchdog.c | 59 | ||||
-rwxr-xr-x | testsuite/mdev.tests | 13 | ||||
-rw-r--r-- | util-linux/mdev.c | 55 |
7 files changed, 81 insertions, 66 deletions
diff --git a/debianutils/start_stop_daemon.c b/debianutils/start_stop_daemon.c index 875eca511..99864d0a4 100644 --- a/debianutils/start_stop_daemon.c +++ b/debianutils/start_stop_daemon.c | |||
@@ -428,7 +428,7 @@ int start_stop_daemon_main(int argc UNUSED_PARAM, char **argv) | |||
428 | write_pidfile(pidfile); | 428 | write_pidfile(pidfile); |
429 | } | 429 | } |
430 | if (opt & OPT_c) { | 430 | if (opt & OPT_c) { |
431 | struct bb_uidgid_t ugid; | 431 | struct bb_uidgid_t ugid = { -1, -1 }; |
432 | parse_chown_usergroup_or_die(&ugid, chuid); | 432 | parse_chown_usergroup_or_die(&ugid, chuid); |
433 | if (ugid.gid != (gid_t) -1) xsetgid(ugid.gid); | 433 | if (ugid.gid != (gid_t) -1) xsetgid(ugid.gid); |
434 | if (ugid.uid != (uid_t) -1) xsetuid(ugid.uid); | 434 | if (ugid.uid != (uid_t) -1) xsetuid(ugid.uid); |
diff --git a/docs/mdev.txt b/docs/mdev.txt index 63ad40602..a8a816ce9 100644 --- a/docs/mdev.txt +++ b/docs/mdev.txt | |||
@@ -51,9 +51,11 @@ device nodes if your system needs something more than the default root/root | |||
51 | 660 permissions. | 51 | 660 permissions. |
52 | 52 | ||
53 | The file has the format: | 53 | The file has the format: |
54 | <device regex> <uid>:<gid> <octal permissions> | 54 | <device regex> <uid>:<gid> <octal permissions> |
55 | or @<maj[,min1[-min2]]> <uid>:<gid> <octal permissions> | ||
56 | |||
55 | For example: | 57 | For example: |
56 | hd[a-z][0-9]* 0:3 660 | 58 | hd[a-z][0-9]* 0:3 660 |
57 | 59 | ||
58 | The config file parsing stops at the first matching line. If no line is | 60 | The config file parsing stops at the first matching line. If no line is |
59 | matched, then the default of 0:0 660 is used. To set your own default, simply | 61 | matched, then the default of 0:0 660 is used. To set your own default, simply |
diff --git a/include/usage.h b/include/usage.h index c0b81efd1..fdad63a4f 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -4561,14 +4561,15 @@ | |||
4561 | "Mon Dec 17 10:31:44 GMT 2000" | 4561 | "Mon Dec 17 10:31:44 GMT 2000" |
4562 | 4562 | ||
4563 | #define watchdog_trivial_usage \ | 4563 | #define watchdog_trivial_usage \ |
4564 | "[-t N[ms]] [-F] DEV" | 4564 | "[-t N[ms]] [-T N[ms]] [-F] DEV" |
4565 | #define watchdog_full_usage "\n\n" \ | 4565 | #define watchdog_full_usage "\n\n" \ |
4566 | "Periodically write to watchdog device DEV\n" \ | 4566 | "Periodically write to watchdog device DEV\n" \ |
4567 | "\nOptions:" \ | 4567 | "\nOptions:" \ |
4568 | "\n -t N Timer period (default 30)" \ | 4568 | "\n -T N Reboot after N seconds if not reset (default 60)" \ |
4569 | "\n -t N Reset every N seconds (default 30)" \ | ||
4569 | "\n -F Run in foreground" \ | 4570 | "\n -F Run in foreground" \ |
4570 | "\n" \ | 4571 | "\n" \ |
4571 | "\nUse -t 500ms to specify period in milliseconds" \ | 4572 | "\nUse 500ms to specify period in milliseconds" \ |
4572 | 4573 | ||
4573 | #define wc_trivial_usage \ | 4574 | #define wc_trivial_usage \ |
4574 | "[OPTION]... [FILE]..." | 4575 | "[OPTION]... [FILE]..." |
diff --git a/libpwdgrp/uidgid_get.c b/libpwdgrp/uidgid_get.c index ebc7fc58c..92290bfdb 100644 --- a/libpwdgrp/uidgid_get.c +++ b/libpwdgrp/uidgid_get.c | |||
@@ -87,15 +87,12 @@ void FAST_FUNC xget_uidgid(struct bb_uidgid_t *u, const char *ug) | |||
87 | * ":group" sets gid only | 87 | * ":group" sets gid only |
88 | * "user:" sets uid and gid (to user's primary group id) | 88 | * "user:" sets uid and gid (to user's primary group id) |
89 | * "user:group" sets uid and gid | 89 | * "user:group" sets uid and gid |
90 | * ('unset' uid or gid is actually set to -1) | 90 | * ('unset' uid or gid retains the value it has on entry) |
91 | */ | 91 | */ |
92 | void FAST_FUNC parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group) | 92 | void FAST_FUNC parse_chown_usergroup_or_die(struct bb_uidgid_t *u, char *user_group) |
93 | { | 93 | { |
94 | char *group; | 94 | char *group; |
95 | 95 | ||
96 | u->uid = -1; | ||
97 | u->gid = -1; | ||
98 | |||
99 | /* Check if there is a group name */ | 96 | /* Check if there is a group name */ |
100 | group = strchr(user_group, '.'); /* deprecated? */ | 97 | group = strchr(user_group, '.'); /* deprecated? */ |
101 | if (!group) | 98 | if (!group) |
diff --git a/miscutils/watchdog.c b/miscutils/watchdog.c index 9b1a110ea..e102a598a 100644 --- a/miscutils/watchdog.c +++ b/miscutils/watchdog.c | |||
@@ -4,14 +4,17 @@ | |||
4 | * | 4 | * |
5 | * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org> | 5 | * Copyright (C) 2003 Paul Mundt <lethal@linux-sh.org> |
6 | * Copyright (C) 2006 Bernhard Fischer <busybox@busybox.net> | 6 | * Copyright (C) 2006 Bernhard Fischer <busybox@busybox.net> |
7 | * Copyright (C) 2008 Darius Augulis <augulis.darius@gmail.com> | ||
7 | * | 8 | * |
8 | * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. | 9 | * Licensed under the GPL v2 or later, see the file LICENSE in this tarball. |
9 | */ | 10 | */ |
10 | 11 | ||
11 | #include "libbb.h" | 12 | #include "libbb.h" |
13 | #include "linux/watchdog.h" | ||
12 | 14 | ||
13 | #define OPT_FOREGROUND 0x01 | 15 | #define OPT_FOREGROUND (1 << 0) |
14 | #define OPT_TIMER 0x02 | 16 | #define OPT_STIMER (1 << 1) |
17 | #define OPT_HTIMER (1 << 2) | ||
15 | 18 | ||
16 | static void watchdog_shutdown(int sig UNUSED_PARAM) | 19 | static void watchdog_shutdown(int sig UNUSED_PARAM) |
17 | { | 20 | { |
@@ -26,38 +29,42 @@ static void watchdog_shutdown(int sig UNUSED_PARAM) | |||
26 | int watchdog_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 29 | int watchdog_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
27 | int watchdog_main(int argc, char **argv) | 30 | int watchdog_main(int argc, char **argv) |
28 | { | 31 | { |
29 | unsigned opts; | 32 | static const struct suffix_mult suffixes[] = { |
30 | unsigned timer_duration = 30000; /* Userspace timer duration, in milliseconds */ | 33 | { "ms", 1 }, |
31 | char *t_arg; | 34 | { "", 1000 }, |
35 | { } | ||
36 | }; | ||
32 | 37 | ||
33 | opt_complementary = "=1"; /* must have 1 argument */ | 38 | unsigned opts; |
34 | opts = getopt32(argv, "Ft:", &t_arg); | 39 | unsigned stimer_duration; /* how often to restart */ |
40 | unsigned htimer_duration = 60000; /* reboots after N ms if not restarted */ | ||
41 | char *st_arg; | ||
42 | char *ht_arg; | ||
35 | 43 | ||
36 | if (opts & OPT_TIMER) { | 44 | opt_complementary = "=1"; /* must have exactly 1 argument */ |
37 | static const struct suffix_mult suffixes[] = { | 45 | opts = getopt32(argv, "Ft:T:", &st_arg, &ht_arg); |
38 | { "ms", 1 }, | ||
39 | { "", 1000 }, | ||
40 | { } | ||
41 | }; | ||
42 | timer_duration = xatou_sfx(t_arg, suffixes); | ||
43 | } | ||
44 | 46 | ||
45 | if (!(opts & OPT_FOREGROUND)) { | 47 | if (opts & OPT_HTIMER) |
46 | bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); | 48 | htimer_duration = xatou_sfx(ht_arg, suffixes); |
47 | } | 49 | stimer_duration = htimer_duration / 2; |
50 | if (opts & OPT_STIMER) | ||
51 | stimer_duration = xatou_sfx(st_arg, suffixes); | ||
48 | 52 | ||
49 | bb_signals(BB_FATAL_SIGS, watchdog_shutdown); | 53 | bb_signals(BB_FATAL_SIGS, watchdog_shutdown); |
50 | 54 | ||
51 | /* Use known fd # - avoid needing global 'int fd' */ | 55 | /* Use known fd # - avoid needing global 'int fd' */ |
52 | xmove_fd(xopen(argv[argc - 1], O_WRONLY), 3); | 56 | xmove_fd(xopen(argv[argc - 1], O_WRONLY), 3); |
53 | 57 | ||
54 | // TODO? | 58 | ioctl_or_warn(3, WDIOC_SETTIMEOUT, &htimer_duration); |
55 | // if (!(opts & OPT_TIMER)) { | 59 | #if 0 |
56 | // if (ioctl(fd, WDIOC_GETTIMEOUT, &timer_duration) == 0) | 60 | ioctl_or_warn(3, WDIOC_GETTIMEOUT, &htimer_duration); |
57 | // timer_duration *= 500; | 61 | printf("watchdog: SW timer is %dms, HW timer is %dms\n", |
58 | // else | 62 | stimer_duration, htimer_duration * 1000); |
59 | // timer_duration = 30000; | 63 | #endif |
60 | // } | 64 | |
65 | if (!(opts & OPT_FOREGROUND)) { | ||
66 | bb_daemonize_or_rexec(DAEMON_CHDIR_ROOT, argv); | ||
67 | } | ||
61 | 68 | ||
62 | while (1) { | 69 | while (1) { |
63 | /* | 70 | /* |
@@ -65,7 +72,7 @@ int watchdog_main(int argc, char **argv) | |||
65 | * is undefined at this point -- PFM | 72 | * is undefined at this point -- PFM |
66 | */ | 73 | */ |
67 | write(3, "", 1); /* write zero byte */ | 74 | write(3, "", 1); /* write zero byte */ |
68 | usleep(timer_duration * 1000L); | 75 | usleep(stimer_duration * 1000L); |
69 | } | 76 | } |
70 | return EXIT_SUCCESS; /* - not reached, but gcc 4.2.1 is too dumb! */ | 77 | return EXIT_SUCCESS; /* - not reached, but gcc 4.2.1 is too dumb! */ |
71 | } | 78 | } |
diff --git a/testsuite/mdev.tests b/testsuite/mdev.tests index dad5bddb8..22855791a 100755 --- a/testsuite/mdev.tests +++ b/testsuite/mdev.tests | |||
@@ -98,7 +98,6 @@ brw-r--r-- 1 0 0 a_sda | |||
98 | 98 | ||
99 | # continuing to use directory structure from prev test | 99 | # continuing to use directory structure from prev test |
100 | rm -rf mdev.testdir/dev/* | 100 | rm -rf mdev.testdir/dev/* |
101 | # here we complicate things by having non-matching group 1 and using %0 | ||
102 | echo "sda 0:0 644 @echo @echo TEST" >mdev.testdir/etc/mdev.conf | 101 | echo "sda 0:0 644 @echo @echo TEST" >mdev.testdir/etc/mdev.conf |
103 | testing "mdev command" \ | 102 | testing "mdev command" \ |
104 | "env - PATH=$PATH ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1; | 103 | "env - PATH=$PATH ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1; |
@@ -110,6 +109,18 @@ brw-r--r-- 1 0 0 8,0 sda | |||
110 | " \ | 109 | " \ |
111 | "" "" | 110 | "" "" |
112 | 111 | ||
112 | # continuing to use directory structure from prev test | ||
113 | rm -rf mdev.testdir/dev/* | ||
114 | echo "@8,0 :1 644" >mdev.testdir/etc/mdev.conf | ||
115 | testing "mdev #maj,min and no explicit uid" \ | ||
116 | "env - PATH=$PATH ACTION=add DEVPATH=/block/sda chroot mdev.testdir /mdev 2>&1; | ||
117 | ls -lnR mdev.testdir/dev | $FILTER_LS" \ | ||
118 | "\ | ||
119 | mdev.testdir/dev: | ||
120 | brw-r--r-- 1 0 1 8,0 sda | ||
121 | " \ | ||
122 | "" "" | ||
123 | |||
113 | # clean up | 124 | # clean up |
114 | rm -rf mdev.testdir | 125 | rm -rf mdev.testdir |
115 | 126 | ||
diff --git a/util-linux/mdev.c b/util-linux/mdev.c index d0d010382..5ac801555 100644 --- a/util-linux/mdev.c +++ b/util-linux/mdev.c | |||
@@ -59,8 +59,7 @@ static void make_device(char *path, int delete) | |||
59 | int major, minor, type, len; | 59 | int major, minor, type, len; |
60 | int mode = 0660; | 60 | int mode = 0660; |
61 | #if ENABLE_FEATURE_MDEV_CONF | 61 | #if ENABLE_FEATURE_MDEV_CONF |
62 | uid_t uid = 0; | 62 | struct bb_uidgid_t ugid = { 0, 0 }; |
63 | gid_t gid = 0; | ||
64 | parser_t *parser; | 63 | parser_t *parser; |
65 | char *tokens[5]; | 64 | char *tokens[5]; |
66 | #endif | 65 | #endif |
@@ -78,9 +77,10 @@ static void make_device(char *path, int delete) | |||
78 | 77 | ||
79 | /* Try to read major/minor string. Note that the kernel puts \n after | 78 | /* Try to read major/minor string. Note that the kernel puts \n after |
80 | * the data, so we don't need to worry about null terminating the string | 79 | * the data, so we don't need to worry about null terminating the string |
81 | * because sscanf() will stop at the first nondigit, which \n is. We | 80 | * because sscanf() will stop at the first nondigit, which \n is. |
82 | * also depend on path having writeable space after it. | 81 | * We also depend on path having writeable space after it. |
83 | */ | 82 | */ |
83 | major = -1; | ||
84 | if (!delete) { | 84 | if (!delete) { |
85 | strcpy(dev_maj_min, "/dev"); | 85 | strcpy(dev_maj_min, "/dev"); |
86 | len = open_read_close(path, dev_maj_min + 1, 64); | 86 | len = open_read_close(path, dev_maj_min + 1, 64); |
@@ -90,6 +90,8 @@ static void make_device(char *path, int delete) | |||
90 | return; | 90 | return; |
91 | /* no "dev" file, so just try to run script */ | 91 | /* no "dev" file, so just try to run script */ |
92 | *dev_maj_min = '\0'; | 92 | *dev_maj_min = '\0'; |
93 | } else if (sscanf(dev_maj_min, "%u:%u", &major, &minor) != 2) { | ||
94 | major = -1; | ||
93 | } | 95 | } |
94 | } | 96 | } |
95 | 97 | ||
@@ -113,8 +115,23 @@ static void make_device(char *path, int delete) | |||
113 | 115 | ||
114 | /* Fields: regex uid:gid mode [alias] [cmd] */ | 116 | /* Fields: regex uid:gid mode [alias] [cmd] */ |
115 | 117 | ||
116 | /* 1st field: regex to match this device */ | 118 | /* 1st field: @<numeric maj,min>... */ |
117 | { | 119 | if (tokens[0][0] == '@') { |
120 | /* @major,minor[-last] */ | ||
121 | /* (useful when name is ambiguous: | ||
122 | * "/sys/class/usb/lp0" and | ||
123 | * "/sys/class/printer/lp0") */ | ||
124 | int cmaj, cmin0, cmin1, sc; | ||
125 | if (major < 0) | ||
126 | continue; /* no dev, no match */ | ||
127 | sc = sscanf(tokens[0], "@%u,%u-%u", &cmaj, &cmin0, &cmin1); | ||
128 | if (sc < 1 || major != cmaj | ||
129 | || (sc == 2 && minor != cmin0) | ||
130 | || (sc == 3 && (minor < cmin0 || minor > cmin1)) | ||
131 | ) { | ||
132 | continue; /* no match */ | ||
133 | } | ||
134 | } else { /* ... or regex to match device name */ | ||
118 | regex_t match; | 135 | regex_t match; |
119 | int result; | 136 | int result; |
120 | 137 | ||
@@ -144,27 +161,7 @@ static void make_device(char *path, int delete) | |||
144 | * after parsing the rest of fields */ | 161 | * after parsing the rest of fields */ |
145 | 162 | ||
146 | /* 2nd field: uid:gid - device ownership */ | 163 | /* 2nd field: uid:gid - device ownership */ |
147 | { | 164 | parse_chown_usergroup_or_die(&ugid, tokens[1]); |
148 | struct passwd *pass; | ||
149 | struct group *grp; | ||
150 | char *str_uid = tokens[1]; | ||
151 | char *str_gid = strchrnul(str_uid, ':'); | ||
152 | |||
153 | if (*str_gid) | ||
154 | *str_gid++ = '\0'; | ||
155 | /* Parse UID */ | ||
156 | pass = getpwnam(str_uid); | ||
157 | if (pass) | ||
158 | uid = pass->pw_uid; | ||
159 | else | ||
160 | uid = strtoul(str_uid, NULL, 10); | ||
161 | /* Parse GID */ | ||
162 | grp = getgrnam(str_gid); | ||
163 | if (grp) | ||
164 | gid = grp->gr_gid; | ||
165 | else | ||
166 | gid = strtoul(str_gid, NULL, 10); | ||
167 | } | ||
168 | 165 | ||
169 | /* 3rd field: mode - device permissions */ | 166 | /* 3rd field: mode - device permissions */ |
170 | mode = strtoul(tokens[2], NULL, 8); | 167 | mode = strtoul(tokens[2], NULL, 8); |
@@ -243,7 +240,7 @@ static void make_device(char *path, int delete) | |||
243 | config_close(parser); | 240 | config_close(parser); |
244 | #endif /* ENABLE_FEATURE_MDEV_CONF */ | 241 | #endif /* ENABLE_FEATURE_MDEV_CONF */ |
245 | 242 | ||
246 | if (!delete && sscanf(dev_maj_min, "%u:%u", &major, &minor) == 2) { | 243 | if (!delete && major >= 0) { |
247 | 244 | ||
248 | if (ENABLE_FEATURE_MDEV_RENAME) | 245 | if (ENABLE_FEATURE_MDEV_RENAME) |
249 | unlink(device_name); | 246 | unlink(device_name); |
@@ -255,7 +252,7 @@ static void make_device(char *path, int delete) | |||
255 | symlink(device_name, "root"); | 252 | symlink(device_name, "root"); |
256 | 253 | ||
257 | #if ENABLE_FEATURE_MDEV_CONF | 254 | #if ENABLE_FEATURE_MDEV_CONF |
258 | chown(device_name, uid, gid); | 255 | chown(device_name, ugid.uid, ugid.gid); |
259 | 256 | ||
260 | #if ENABLE_FEATURE_MDEV_RENAME | 257 | #if ENABLE_FEATURE_MDEV_RENAME |
261 | if (alias) { | 258 | if (alias) { |