diff options
author | Ron Yorston <rmy@pobox.com> | 2014-05-06 20:41:10 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2014-05-06 20:41:10 +0100 |
commit | d3bef66324a8ca5eed9ad7c15ead3a1cc9a9151e (patch) | |
tree | 4b364ba4b6b9e96c2629fe382fef0248d76833dd /util-linux | |
parent | 7905d97aeece18da362a5a1e066abff2d2e5c16b (diff) | |
parent | d257608a8429b64e1a04c7cb6d99975eeb2c3955 (diff) | |
download | busybox-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.src | 9 | ||||
-rw-r--r-- | util-linux/rtcwake.c | 55 | ||||
-rw-r--r-- | util-linux/script.c | 7 | ||||
-rw-r--r-- | util-linux/swaponoff.c | 248 |
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 | ||
602 | config 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 | |||
602 | config FEATURE_SWAPON_PRI | 611 | config 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 | ||
56 | static NOINLINE bool may_wakeup(const char *rtcname) | 55 | static 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) | |||
122 | int rtcwake_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 121 | int rtcwake_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
123 | int rtcwake_main(int argc UNUSED_PARAM, char **argv) | 122 | int 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 | ||
42 | struct globals { | 61 | struct 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 */ | ||
78 | enum { | ||
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 | |||
52 | static int swap_enable_disable(char *device) | 91 | static 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 | ||
80 | static int do_em_all(void) | 126 | #if ENABLE_FEATURE_SWAPON_DISCARD |
127 | static 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) | 151 | static 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 | |||
170 | static 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 | ||
211 | static 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 | |||
123 | int swap_on_off_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 236 | int swap_on_off_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
124 | int swap_on_off_main(int argc UNUSED_PARAM, char **argv) | 237 | int 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 | } |