summaryrefslogtreecommitdiff
path: root/util-linux
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2014-05-06 20:41:10 +0100
committerRon Yorston <rmy@pobox.com>2014-05-06 20:41:10 +0100
commitd3bef66324a8ca5eed9ad7c15ead3a1cc9a9151e (patch)
tree4b364ba4b6b9e96c2629fe382fef0248d76833dd /util-linux
parent7905d97aeece18da362a5a1e066abff2d2e5c16b (diff)
parentd257608a8429b64e1a04c7cb6d99975eeb2c3955 (diff)
downloadbusybox-w32-d3bef66324a8ca5eed9ad7c15ead3a1cc9a9151e.tar.gz
busybox-w32-d3bef66324a8ca5eed9ad7c15ead3a1cc9a9151e.tar.bz2
busybox-w32-d3bef66324a8ca5eed9ad7c15ead3a1cc9a9151e.zip
Merge branch 'busybox' into merge
Conflicts: debianutils/which.c editors/vi.c libbb/executable.c
Diffstat (limited to 'util-linux')
-rw-r--r--util-linux/Config.src9
-rw-r--r--util-linux/rtcwake.c55
-rw-r--r--util-linux/script.c7
-rw-r--r--util-linux/swaponoff.c248
4 files changed, 231 insertions, 88 deletions
diff --git a/util-linux/Config.src b/util-linux/Config.src
index 5a8b0063b..c1cd6daa4 100644
--- a/util-linux/Config.src
+++ b/util-linux/Config.src
@@ -599,6 +599,15 @@ config SWAPONOFF
599 space. If you are not using any swap space, you can leave this 599 space. If you are not using any swap space, you can leave this
600 option disabled. 600 option disabled.
601 601
602config FEATURE_SWAPON_DISCARD
603 bool "Support discard option -d"
604 default y
605 depends on SWAPONOFF
606 help
607 Enable support for discarding swap area blocks at swapon and/or as
608 the kernel frees them. This option enables both the -d option on
609 'swapon' and the 'discard' option for swap entries in /etc/fstab.
610
602config FEATURE_SWAPON_PRI 611config FEATURE_SWAPON_PRI
603 bool "Support priority option -p" 612 bool "Support priority option -p"
604 default y 613 default y
diff --git a/util-linux/rtcwake.c b/util-linux/rtcwake.c
index 735a29822..33cdbfad4 100644
--- a/util-linux/rtcwake.c
+++ b/util-linux/rtcwake.c
@@ -51,7 +51,6 @@
51 51
52#define SYS_RTC_PATH "/sys/class/rtc/%s/device/power/wakeup" 52#define SYS_RTC_PATH "/sys/class/rtc/%s/device/power/wakeup"
53#define SYS_POWER_PATH "/sys/power/state" 53#define SYS_POWER_PATH "/sys/power/state"
54#define DEFAULT_MODE "standby"
55 54
56static NOINLINE bool may_wakeup(const char *rtcname) 55static NOINLINE bool may_wakeup(const char *rtcname)
57{ 56{
@@ -122,17 +121,16 @@ static NOINLINE void setup_alarm(int fd, time_t *wakeup, time_t rtc_time)
122int rtcwake_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 121int rtcwake_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
123int rtcwake_main(int argc UNUSED_PARAM, char **argv) 122int rtcwake_main(int argc UNUSED_PARAM, char **argv)
124{ 123{
125 time_t rtc_time;
126
127 unsigned opt; 124 unsigned opt;
128 const char *rtcname = NULL; 125 const char *rtcname = NULL;
129 const char *suspend; 126 const char *suspend = "standby";
130 const char *opt_seconds; 127 const char *opt_seconds;
131 const char *opt_time; 128 const char *opt_time;
132 129
130 time_t rtc_time;
133 time_t sys_time; 131 time_t sys_time;
134 time_t alarm_time = 0; 132 time_t alarm_time = alarm_time;
135 unsigned seconds = 0; 133 unsigned seconds = seconds; /* for compiler */
136 int utc = -1; 134 int utc = -1;
137 int fd; 135 int fd;
138 136
@@ -148,6 +146,8 @@ int rtcwake_main(int argc UNUSED_PARAM, char **argv)
148 ; 146 ;
149 applet_long_options = rtcwake_longopts; 147 applet_long_options = rtcwake_longopts;
150#endif 148#endif
149 /* Must have -s or -t, exclusive */
150 opt_complementary = "s:t:s--t:t--s";
151 opt = getopt32(argv, "alud:m:s:t:", &rtcname, &suspend, &opt_seconds, &opt_time); 151 opt = getopt32(argv, "alud:m:s:t:", &rtcname, &suspend, &opt_seconds, &opt_time);
152 152
153 /* this is the default 153 /* this is the default
@@ -156,17 +156,17 @@ int rtcwake_main(int argc UNUSED_PARAM, char **argv)
156 */ 156 */
157 if (opt & (RTCWAKE_OPT_UTC | RTCWAKE_OPT_LOCAL)) 157 if (opt & (RTCWAKE_OPT_UTC | RTCWAKE_OPT_LOCAL))
158 utc = opt & RTCWAKE_OPT_UTC; 158 utc = opt & RTCWAKE_OPT_UTC;
159 if (!(opt & RTCWAKE_OPT_SUSPEND_MODE)) 159 if (opt & RTCWAKE_OPT_SECONDS) {
160 suspend = DEFAULT_MODE;
161 if (opt & RTCWAKE_OPT_SECONDS)
162 /* alarm time, seconds-to-sleep (relative) */ 160 /* alarm time, seconds-to-sleep (relative) */
163 seconds = xatoi(opt_seconds); 161 seconds = xatou(opt_seconds);
164 if (opt & RTCWAKE_OPT_TIME) 162 } else {
163 /* RTCWAKE_OPT_TIME */
165 /* alarm time, time_t (absolute, seconds since 1/1 1970 UTC) */ 164 /* alarm time, time_t (absolute, seconds since 1/1 1970 UTC) */
166 alarm_time = xatol(opt_time); 165 if (sizeof(alarm_time) <= sizeof(long))
167 166 alarm_time = xatol(opt_time);
168 if (!alarm_time && !seconds) 167 else
169 bb_error_msg_and_die("must provide wake time"); 168 alarm_time = xatoll(opt_time);
169 }
170 170
171 if (utc == -1) 171 if (utc == -1)
172 utc = rtc_adjtime_is_utc(); 172 utc = rtc_adjtime_is_utc();
@@ -177,8 +177,9 @@ int rtcwake_main(int argc UNUSED_PARAM, char **argv)
177 /* this RTC must exist and (if we'll sleep) be wakeup-enabled */ 177 /* this RTC must exist and (if we'll sleep) be wakeup-enabled */
178 fd = rtc_xopen(&rtcname, O_RDONLY); 178 fd = rtc_xopen(&rtcname, O_RDONLY);
179 179
180 if (strcmp(suspend, "on") && !may_wakeup(rtcname)) 180 if (strcmp(suspend, "on") != 0)
181 bb_error_msg_and_die("%s not enabled for wakeup events", rtcname); 181 if (!may_wakeup(rtcname))
182 bb_error_msg_and_die("%s not enabled for wakeup events", rtcname);
182 183
183 /* relative or absolute alarm time, normalized to time_t */ 184 /* relative or absolute alarm time, normalized to time_t */
184 sys_time = time(NULL); 185 sys_time = time(NULL);
@@ -188,21 +189,29 @@ int rtcwake_main(int argc UNUSED_PARAM, char **argv)
188 rtc_time = rtc_tm2time(&tm_time, utc); 189 rtc_time = rtc_tm2time(&tm_time, utc);
189 } 190 }
190 191
191 192 if (opt & RTCWAKE_OPT_TIME) {
192 if (alarm_time) { 193 /* Correct for RTC<->system clock difference */
193 if (alarm_time < sys_time) 194 alarm_time += rtc_time - sys_time;
195 if (alarm_time < rtc_time)
196 /*
197 * Compat message text.
198 * I'd say "RTC time is already ahead of ..." instead.
199 */
194 bb_error_msg_and_die("time doesn't go backward to %s", ctime(&alarm_time)); 200 bb_error_msg_and_die("time doesn't go backward to %s", ctime(&alarm_time));
195 alarm_time += sys_time - rtc_time;
196 } else 201 } else
197 alarm_time = rtc_time + seconds + 1; 202 alarm_time = rtc_time + seconds + 1;
198 setup_alarm(fd, &alarm_time, rtc_time);
199 203
204 setup_alarm(fd, &alarm_time, rtc_time);
200 sync(); 205 sync();
206#if 0 /*debug*/
207 printf("sys_time: %s", ctime(&sys_time));
208 printf("rtc_time: %s", ctime(&rtc_time));
209#endif
201 printf("wakeup from \"%s\" at %s", suspend, ctime(&alarm_time)); 210 printf("wakeup from \"%s\" at %s", suspend, ctime(&alarm_time));
202 fflush_all(); 211 fflush_all();
203 usleep(10 * 1000); 212 usleep(10 * 1000);
204 213
205 if (strcmp(suspend, "on")) 214 if (strcmp(suspend, "on") != 0)
206 xopen_xwrite_close(SYS_POWER_PATH, suspend); 215 xopen_xwrite_close(SYS_POWER_PATH, suspend);
207 else { 216 else {
208 /* "fake" suspend ... we'll do the delay ourselves */ 217 /* "fake" suspend ... we'll do the delay ourselves */
diff --git a/util-linux/script.c b/util-linux/script.c
index 8fb991d15..abcd73bff 100644
--- a/util-linux/script.c
+++ b/util-linux/script.c
@@ -77,8 +77,15 @@ int script_main(int argc UNUSED_PARAM, char **argv)
77 if (!(opt & OPT_q)) { 77 if (!(opt & OPT_q)) {
78 printf("Script started, file is %s\n", fname); 78 printf("Script started, file is %s\n", fname);
79 } 79 }
80
80 shell = get_shell_name(); 81 shell = get_shell_name();
81 82
83 /* Some people run "script ... 0>&-".
84 * Our code assumes that STDIN_FILENO != pty.
85 * Ensure STDIN_FILENO is not closed:
86 */
87 bb_sanitize_stdio();
88
82 pty = xgetpty(pty_line); 89 pty = xgetpty(pty_line);
83 90
84 /* get current stdin's tty params */ 91 /* get current stdin's tty params */
diff --git a/util-linux/swaponoff.c b/util-linux/swaponoff.c
index 3f223343e..75487267b 100644
--- a/util-linux/swaponoff.c
+++ b/util-linux/swaponoff.c
@@ -8,10 +8,14 @@
8 */ 8 */
9 9
10//usage:#define swapon_trivial_usage 10//usage:#define swapon_trivial_usage
11//usage: "[-a]" IF_FEATURE_SWAPON_PRI(" [-p PRI]") " [DEVICE]" 11//usage: "[-a]" IF_FEATURE_SWAPON_DISCARD(" [-d[POL]]") IF_FEATURE_SWAPON_PRI(" [-p PRI]") " [DEVICE]"
12//usage:#define swapon_full_usage "\n\n" 12//usage:#define swapon_full_usage "\n\n"
13//usage: "Start swapping on DEVICE\n" 13//usage: "Start swapping on DEVICE\n"
14//usage: "\n -a Start swapping on all swap devices" 14//usage: "\n -a Start swapping on all swap devices"
15//usage: IF_FEATURE_SWAPON_DISCARD(
16//usage: "\n -d[POL] Discard blocks at swapon (POL=once),"
17//usage: "\n as freed (POL=pages), or both (POL omitted)"
18//usage: )
15//usage: IF_FEATURE_SWAPON_PRI( 19//usage: IF_FEATURE_SWAPON_PRI(
16//usage: "\n -p PRI Set swap device priority" 20//usage: "\n -p PRI Set swap device priority"
17//usage: ) 21//usage: )
@@ -38,78 +42,162 @@
38# define MNTTYPE_SWAP "swap" 42# define MNTTYPE_SWAP "swap"
39#endif 43#endif
40 44
41#if ENABLE_FEATURE_SWAPON_PRI 45#if ENABLE_FEATURE_SWAPON_DISCARD
46#ifndef SWAP_FLAG_DISCARD
47#define SWAP_FLAG_DISCARD 0x10000
48#endif
49#ifndef SWAP_FLAG_DISCARD_ONCE
50#define SWAP_FLAG_DISCARD_ONCE 0x20000
51#endif
52#ifndef SWAP_FLAG_DISCARD_PAGES
53#define SWAP_FLAG_DISCARD_PAGES 0x40000
54#endif
55#define SWAP_FLAG_DISCARD_MASK \
56 (SWAP_FLAG_DISCARD | SWAP_FLAG_DISCARD_ONCE | SWAP_FLAG_DISCARD_PAGES)
57#endif
58
59
60#if ENABLE_FEATURE_SWAPON_DISCARD || ENABLE_FEATURE_SWAPON_PRI
42struct globals { 61struct globals {
43 int flags; 62 int flags;
44} FIX_ALIASING; 63} FIX_ALIASING;
45#define G (*(struct globals*)&bb_common_bufsiz1) 64#define G (*(struct globals*)&bb_common_bufsiz1)
46#define g_flags (G.flags) 65#define g_flags (G.flags)
66#define save_g_flags() int save_g_flags = g_flags
67#define restore_g_flags() g_flags = save_g_flags
47#else 68#else
48#define g_flags 0 69#define g_flags 0
70#define save_g_flags() ((void)0)
71#define restore_g_flags() ((void)0)
49#endif 72#endif
50#define INIT_G() do { } while (0) 73#define INIT_G() do { } while (0)
51 74
75#define do_swapoff (applet_name[5] == 'f')
76
77/* Command line options */
78enum {
79 OPTBIT_a, /* -a all */
80 IF_FEATURE_SWAPON_DISCARD( OPTBIT_d ,) /* -d discard */
81 IF_FEATURE_SWAPON_PRI ( OPTBIT_p ,) /* -p priority */
82 OPT_a = 1 << OPTBIT_a,
83 OPT_d = IF_FEATURE_SWAPON_DISCARD((1 << OPTBIT_d)) + 0,
84 OPT_p = IF_FEATURE_SWAPON_PRI ((1 << OPTBIT_p)) + 0,
85};
86
87#define OPT_ALL (option_mask32 & OPT_a)
88#define OPT_DISCARD (option_mask32 & OPT_d)
89#define OPT_PRIO (option_mask32 & OPT_p)
90
52static int swap_enable_disable(char *device) 91static int swap_enable_disable(char *device)
53{ 92{
54 int status; 93 int err = 0;
94 int quiet = 0;
55 struct stat st; 95 struct stat st;
56 96
57 resolve_mount_spec(&device); 97 resolve_mount_spec(&device);
58 xstat(device, &st);
59 98
60#if ENABLE_DESKTOP 99 if (do_swapoff) {
61 /* test for holes */ 100 err = swapoff(device);
62 if (S_ISREG(st.st_mode)) 101 /* Don't complain on OPT_ALL if not a swap device or if it doesn't exist */
63 if (st.st_blocks * (off_t)512 < st.st_size) 102 quiet = (OPT_ALL && (errno == EINVAL || errno == ENOENT));
64 bb_error_msg("warning: swap file has holes"); 103 } else {
65#endif 104 /* swapon */
66 105 err = stat(device, &st);
67 if (applet_name[5] == 'n') 106 if (!err) {
68 status = swapon(device, g_flags); 107 if (ENABLE_DESKTOP && S_ISREG(st.st_mode)) {
69 else 108 if (st.st_blocks * (off_t)512 < st.st_size) {
70 status = swapoff(device); 109 bb_error_msg("%s: file has holes", device);
110 return 1;
111 }
112 }
113 err = swapon(device, g_flags);
114 /* Don't complain on swapon -a if device is already in use */
115 quiet = (OPT_ALL && errno == EBUSY);
116 }
117 }
71 118
72 if (status != 0) { 119 if (err && !quiet) {
73 bb_simple_perror_msg(device); 120 bb_simple_perror_msg(device);
74 return 1; 121 return 1;
75 } 122 }
76
77 return 0; 123 return 0;
78} 124}
79 125
80static int do_em_all(void) 126#if ENABLE_FEATURE_SWAPON_DISCARD
127static void set_discard_flag(char *s)
81{ 128{
82 struct mntent *m; 129 /* Unset the flag first to allow fstab options to override */
83 FILE *f; 130 /* options set on the command line */
84 int err; 131 g_flags = (g_flags & ~SWAP_FLAG_DISCARD_MASK) | SWAP_FLAG_DISCARD;
132
133 if (!s) /* No optional policy value on the commandline */
134 return;
135 /* Skip prepended '=' */
136 if (*s == '=')
137 s++;
138 /* For fstab parsing: remove other appended options */
139 *strchrnul(s, ',') = '\0';
140
141 if (strcmp(s, "once") == 0)
142 g_flags |= SWAP_FLAG_DISCARD_ONCE;
143 if (strcmp(s, "pages") == 0)
144 g_flags |= SWAP_FLAG_DISCARD_PAGES;
145}
146#else
147#define set_discard_flag(s) ((void)0)
148#endif
85 149
86 f = setmntent("/etc/fstab", "r"); 150#if ENABLE_FEATURE_SWAPON_PRI
87 if (f == NULL) 151static void set_priority_flag(char *s)
88 bb_perror_msg_and_die("/etc/fstab"); 152{
153 unsigned prio;
154
155 /* For fstab parsing: remove other appended options */
156 *strchrnul(s, ',') = '\0';
157 /* Max allowed 32767 (== SWAP_FLAG_PRIO_MASK) */
158 prio = bb_strtou(s, NULL, 10);
159 if (!errno) {
160 /* Unset the flag first to allow fstab options to override */
161 /* options set on the command line */
162 g_flags = (g_flags & ~SWAP_FLAG_PRIO_MASK) | SWAP_FLAG_PREFER |
163 MIN(prio, SWAP_FLAG_PRIO_MASK);
164 }
165}
166#else
167#define set_priority_flag(s) ((void)0)
168#endif
169
170static int do_em_all_in_fstab(void)
171{
172 struct mntent *m;
173 int err = 0;
174 FILE *f = xfopen_for_read("/etc/fstab");
89 175
90 err = 0;
91 while ((m = getmntent(f)) != NULL) { 176 while ((m = getmntent(f)) != NULL) {
92 if (strcmp(m->mnt_type, MNTTYPE_SWAP) == 0) { 177 if (strcmp(m->mnt_type, MNTTYPE_SWAP) == 0) {
93 /* swapon -a should ignore entries with noauto, 178 /* swapon -a should ignore entries with noauto,
94 * but swapoff -a should process them */ 179 * but swapoff -a should process them
95 if (applet_name[5] != 'n' 180 */
96 || hasmntopt(m, MNTOPT_NOAUTO) == NULL 181 if (do_swapoff || hasmntopt(m, MNTOPT_NOAUTO) == NULL) {
97 ) { 182 /* each swap space might have different flags */
98#if ENABLE_FEATURE_SWAPON_PRI 183 /* save global flags for the next round */
99 char *p; 184 save_g_flags();
100 g_flags = 0; /* each swap space might have different flags */ 185 if (ENABLE_FEATURE_SWAPON_DISCARD) {
101 p = hasmntopt(m, "pri"); 186 char *p = hasmntopt(m, "discard");
102 if (p) { 187 if (p) {
103 /* Max allowed 32767 (==SWAP_FLAG_PRIO_MASK) */ 188 /* move to '=' or to end of string */
104 unsigned int swap_prio = MIN(bb_strtou(p + 4 , NULL, 10), SWAP_FLAG_PRIO_MASK); 189 p += 7;
105 /* We want to allow "NNNN,foo", thus errno == EINVAL is allowed too */ 190 set_discard_flag(p);
106 if (errno != ERANGE) {
107 g_flags = SWAP_FLAG_PREFER |
108 (swap_prio << SWAP_FLAG_PRIO_SHIFT);
109 } 191 }
110 } 192 }
111#endif 193 if (ENABLE_FEATURE_SWAPON_PRI) {
112 err += swap_enable_disable(m->mnt_fsname); 194 char *p = hasmntopt(m, "pri");
195 if (p) {
196 set_priority_flag(p + 4);
197 }
198 }
199 err |= swap_enable_disable(m->mnt_fsname);
200 restore_g_flags();
113 } 201 }
114 } 202 }
115 } 203 }
@@ -120,38 +208,68 @@ static int do_em_all(void)
120 return err; 208 return err;
121} 209}
122 210
211static int do_all_in_proc_swaps(void)
212{
213 char *line;
214 int err = 0;
215 FILE *f = fopen_for_read("/proc/swaps");
216 /* Don't complain if missing */
217 if (f) {
218 while ((line = xmalloc_fgetline(f)) != NULL) {
219 if (line[0] == '/') {
220 *strchrnul(line, ' ') = '\0';
221 err |= swap_enable_disable(line);
222 }
223 free(line);
224 }
225 if (ENABLE_FEATURE_CLEAN_UP)
226 fclose(f);
227 }
228
229 return err;
230}
231
232#define OPTSTR_SWAPON "a" \
233 IF_FEATURE_SWAPON_DISCARD("d::") \
234 IF_FEATURE_SWAPON_PRI("p:")
235
123int swap_on_off_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 236int swap_on_off_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
124int swap_on_off_main(int argc UNUSED_PARAM, char **argv) 237int swap_on_off_main(int argc UNUSED_PARAM, char **argv)
125{ 238{
126 int ret; 239 IF_FEATURE_SWAPON_PRI(char *prio;)
240 IF_FEATURE_SWAPON_DISCARD(char *discard = NULL;)
241 int ret = 0;
127 242
128 INIT_G(); 243 INIT_G();
129 244
130#if !ENABLE_FEATURE_SWAPON_PRI 245 getopt32(argv, do_swapoff ? "a" : OPTSTR_SWAPON
131 ret = getopt32(argv, "a"); 246 IF_FEATURE_SWAPON_DISCARD(, &discard)
132#else 247 IF_FEATURE_SWAPON_PRI(, &prio)
133 if (applet_name[5] == 'n') 248 );
134 opt_complementary = "p+";
135 ret = getopt32(argv, (applet_name[5] == 'n') ? "ap:" : "a", &g_flags);
136
137 if (ret & 2) { // -p
138 g_flags = SWAP_FLAG_PREFER |
139 ((g_flags & SWAP_FLAG_PRIO_MASK) << SWAP_FLAG_PRIO_SHIFT);
140 ret &= 1;
141 }
142#endif
143
144 if (ret /* & 1: not needed */) // -a
145 return do_em_all();
146 249
147 argv += optind; 250 argv += optind;
148 if (!*argv)
149 bb_show_usage();
150 251
151 /* ret = 0; redundant */ 252 if (OPT_DISCARD) {
152 do { 253 set_discard_flag(discard);
153 ret += swap_enable_disable(*argv); 254 }
154 } while (*++argv); 255 if (OPT_PRIO) {
256 set_priority_flag(prio);
257 }
155 258
259 if (OPT_ALL) {
260 /* swapoff -a does also /proc/swaps */
261 if (do_swapoff)
262 ret = do_all_in_proc_swaps();
263 ret |= do_em_all_in_fstab();
264 } else if (!*argv) {
265 /* if not -a we need at least one arg */
266 bb_show_usage();
267 }
268 /* Unset -a now to allow for more messages in swap_enable_disable */
269 option_mask32 = option_mask32 & ~OPT_a;
270 /* Now process devices on the commandline if any */
271 while (*argv) {
272 ret |= swap_enable_disable(*argv++);
273 }
156 return ret; 274 return ret;
157} 275}