aboutsummaryrefslogtreecommitdiff
path: root/miscutils
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2013-08-27 16:10:53 +0100
committerRon Yorston <rmy@pobox.com>2013-08-27 16:10:53 +0100
commit3fd34651ea72ea1c335d3170f234cb0517fd897f (patch)
tree36e8fc40cffd464ffda4759020777dd3ca23ca31 /miscutils
parente3ac39098326de084a805d0dd31db9666b734f20 (diff)
parentd6ae4fb446daedfe3073d67be655942e9fa7eb18 (diff)
downloadbusybox-w32-3fd34651ea72ea1c335d3170f234cb0517fd897f.tar.gz
busybox-w32-3fd34651ea72ea1c335d3170f234cb0517fd897f.tar.bz2
busybox-w32-3fd34651ea72ea1c335d3170f234cb0517fd897f.zip
Merge branch 'busybox' into merge
Diffstat (limited to 'miscutils')
-rw-r--r--miscutils/chrt.c3
-rw-r--r--miscutils/less.c29
-rw-r--r--miscutils/man.c2
-rw-r--r--miscutils/setsid.c14
-rw-r--r--miscutils/ubi_tools.c305
5 files changed, 216 insertions, 137 deletions
diff --git a/miscutils/chrt.c b/miscutils/chrt.c
index 91b5397c4..f2f559fd7 100644
--- a/miscutils/chrt.c
+++ b/miscutils/chrt.c
@@ -23,9 +23,6 @@
23 23
24#include <sched.h> 24#include <sched.h>
25#include "libbb.h" 25#include "libbb.h"
26#ifndef _POSIX_PRIORITY_SCHEDULING
27#warning your system may be foobared
28#endif
29 26
30static const struct { 27static const struct {
31 int policy; 28 int policy;
diff --git a/miscutils/less.c b/miscutils/less.c
index 5ce0a1203..60105f42b 100644
--- a/miscutils/less.c
+++ b/miscutils/less.c
@@ -1608,6 +1608,9 @@ static void sigwinch_handler(int sig UNUSED_PARAM)
1608int less_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 1608int less_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
1609int less_main(int argc, char **argv) 1609int less_main(int argc, char **argv)
1610{ 1610{
1611 char *tty_name;
1612 int tty_fd;
1613
1611 INIT_G(); 1614 INIT_G();
1612 1615
1613 /* TODO: -x: do not interpret backspace, -xx: tab also */ 1616 /* TODO: -x: do not interpret backspace, -xx: tab also */
@@ -1637,10 +1640,28 @@ int less_main(int argc, char **argv)
1637 if (option_mask32 & FLAG_TILDE) 1640 if (option_mask32 & FLAG_TILDE)
1638 empty_line_marker = ""; 1641 empty_line_marker = "";
1639 1642
1640 kbd_fd = open(CURRENT_TTY, O_RDONLY); 1643 /* Some versions of less can survive w/o controlling tty,
1641 if (kbd_fd < 0) 1644 * try to do the same. This also allows to specify an alternative
1642 return bb_cat(argv); 1645 * tty via "less 1<>TTY".
1643 ndelay_on(kbd_fd); 1646 * We don't try to use STDOUT_FILENO directly,
1647 * since we want to set this fd to non-blocking mode,
1648 * and not bother with restoring it on exit.
1649 */
1650 tty_name = xmalloc_ttyname(STDOUT_FILENO);
1651 if (tty_name) {
1652 tty_fd = open(tty_name, O_RDONLY);
1653 free(tty_name);
1654 if (tty_fd < 0)
1655 goto try_ctty;
1656 } else {
1657 /* Try controlling tty */
1658 try_ctty:
1659 tty_fd = open(CURRENT_TTY, O_RDONLY);
1660 if (tty_fd < 0)
1661 return bb_cat(argv);
1662 }
1663 ndelay_on(tty_fd);
1664 kbd_fd = tty_fd; /* save in a global */
1644 1665
1645 tcgetattr(kbd_fd, &term_orig); 1666 tcgetattr(kbd_fd, &term_orig);
1646 term_less = term_orig; 1667 term_less = term_orig;
diff --git a/miscutils/man.c b/miscutils/man.c
index b8b15b83b..429898643 100644
--- a/miscutils/man.c
+++ b/miscutils/man.c
@@ -162,7 +162,7 @@ int man_main(int argc UNUSED_PARAM, char **argv)
162 opt = getopt32(argv, "+aw"); 162 opt = getopt32(argv, "+aw");
163 argv += optind; 163 argv += optind;
164 164
165 sec_list = xstrdup("1:2:3:4:5:6:7:8:9"); 165 sec_list = xstrdup("0p:1:1p:2:3:3p:4:5:6:7:8:9");
166 /* Last valid man_path_list[] is [0x10] */ 166 /* Last valid man_path_list[] is [0x10] */
167 count_mp = 0; 167 count_mp = 0;
168 man_path_list = xzalloc(0x11 * sizeof(man_path_list[0])); 168 man_path_list = xzalloc(0x11 * sizeof(man_path_list[0]));
diff --git a/miscutils/setsid.c b/miscutils/setsid.c
index ad2c8a4de..637081b6c 100644
--- a/miscutils/setsid.c
+++ b/miscutils/setsid.c
@@ -31,7 +31,17 @@ int setsid_main(int argc UNUSED_PARAM, char **argv)
31 31
32 /* setsid() is allowed only when we are not a process group leader. 32 /* setsid() is allowed only when we are not a process group leader.
33 * Otherwise our PID serves as PGID of some existing process group 33 * Otherwise our PID serves as PGID of some existing process group
34 * and cannot be used as PGID of a new process group. */ 34 * and cannot be used as PGID of a new process group.
35 *
36 * Example: setsid() below fails when run alone in interactive shell:
37 * $ setsid PROG
38 * because shell's child (setsid) is put in a new process group.
39 * But doesn't fail if shell is not interactive
40 * (and therefore doesn't create process groups for pipes),
41 * or if setsid is not the first process in the process group:
42 * $ true | setsid PROG
43 * or if setsid is executed in backquotes (`setsid PROG`)...
44 */
35 if (setsid() < 0) { 45 if (setsid() < 0) {
36 pid_t pid = fork_or_rexec(argv); 46 pid_t pid = fork_or_rexec(argv);
37 if (pid != 0) { 47 if (pid != 0) {
@@ -43,7 +53,7 @@ int setsid_main(int argc UNUSED_PARAM, char **argv)
43 * However, the code is larger and upstream 53 * However, the code is larger and upstream
44 * does not do such trick. 54 * does not do such trick.
45 */ 55 */
46 exit(EXIT_SUCCESS); 56 return EXIT_SUCCESS;
47 } 57 }
48 58
49 /* child */ 59 /* child */
diff --git a/miscutils/ubi_tools.c b/miscutils/ubi_tools.c
index dd99a44f4..b71393532 100644
--- a/miscutils/ubi_tools.c
+++ b/miscutils/ubi_tools.c
@@ -66,14 +66,6 @@
66#endif 66#endif
67#include <mtd/ubi-user.h> 67#include <mtd/ubi-user.h>
68 68
69#define OPTION_M (1 << 0)
70#define OPTION_D (1 << 1)
71#define OPTION_n (1 << 2)
72#define OPTION_N (1 << 3)
73#define OPTION_s (1 << 4)
74#define OPTION_a (1 << 5)
75#define OPTION_t (1 << 6)
76
77#define do_attach (ENABLE_UBIATTACH && applet_name[3] == 'a') 69#define do_attach (ENABLE_UBIATTACH && applet_name[3] == 'a')
78#define do_detach (ENABLE_UBIDETACH && applet_name[3] == 'd') 70#define do_detach (ENABLE_UBIDETACH && applet_name[3] == 'd')
79#define do_mkvol (ENABLE_UBIMKVOL && applet_name[3] == 'm') 71#define do_mkvol (ENABLE_UBIMKVOL && applet_name[3] == 'm')
@@ -81,191 +73,250 @@
81#define do_rsvol (ENABLE_UBIRSVOL && applet_name[4] == 's') 73#define do_rsvol (ENABLE_UBIRSVOL && applet_name[4] == 's')
82#define do_update (ENABLE_UBIUPDATEVOL && applet_name[3] == 'u') 74#define do_update (ENABLE_UBIUPDATEVOL && applet_name[3] == 'u')
83 75
84//usage:#define ubiattach_trivial_usage 76static unsigned get_num_from_file(const char *path, unsigned max, const char *errmsg)
85//usage: "-m MTD_NUM [-d UBI_NUM] UBI_CTRL_DEV" 77{
86//usage:#define ubiattach_full_usage "\n\n" 78 char buf[sizeof(long long)*3];
87//usage: "Attach MTD device to UBI\n" 79 unsigned long long num;
88//usage: "\n -m MTD_NUM MTD device number to attach" 80
89//usage: "\n -d UBI_NUM UBI device number to assign" 81 if (open_read_close(path, buf, sizeof(buf)) < 0)
90//usage: 82 bb_perror_msg_and_die(errmsg, path);
91//usage:#define ubidetach_trivial_usage 83 /* It can be \n terminated, xatoull won't work well */
92//usage: "-d UBI_NUM UBI_CTRL_DEV" 84 if (sscanf(buf, "%llu", &num) != 1 || num > max)
93//usage:#define ubidetach_full_usage "\n\n" 85 bb_error_msg_and_die(errmsg, path);
94//usage: "Detach MTD device from UBI\n" 86 return num;
95//usage: "\n -d UBI_NUM UBI device number" 87}
96//usage:
97//usage:#define ubimkvol_trivial_usage
98//usage: "UBI_DEVICE -N NAME -s SIZE"
99//usage:#define ubimkvol_full_usage "\n\n"
100//usage: "Create UBI volume\n"
101//usage: "\n -a ALIGNMENT Volume alignment (default 1)"
102//usage: "\n -n VOLID Volume ID, if not specified, it"
103//usage: "\n will be assigned automatically"
104//usage: "\n -N NAME Volume name"
105//usage: "\n -s SIZE Size in bytes"
106//usage: "\n -t TYPE Volume type (static|dynamic)"
107//usage:
108//usage:#define ubirmvol_trivial_usage
109//usage: "UBI_DEVICE -n VOLID"
110//usage:#define ubirmvol_full_usage "\n\n"
111//usage: "Remove UBI volume\n"
112//usage: "\n -n VOLID Volume ID"
113//usage:
114//usage:#define ubirsvol_trivial_usage
115//usage: "UBI_DEVICE -n VOLID -s SIZE"
116//usage:#define ubirsvol_full_usage "\n\n"
117//usage: "Resize UBI volume\n"
118//usage: "\n -n VOLID Volume ID to resize"
119//usage: "\n -s SIZE Size in bytes"
120//usage:
121//usage:#define ubiupdatevol_trivial_usage
122//usage: "UBI_DEVICE [IMG_FILE]"
123//usage:#define ubiupdatevol_full_usage "\n\n"
124//usage: "Update UBI volume\n"
125//usage: "\n -t Truncate UBI volume"
126//usage: "\n -s SIZE Bytes in input (if reading stdin)"
127 88
89/* To prevent malloc(1G) accidents */
90#define MAX_SANE_ERASEBLOCK (16*1024*1024)
128 91
129int ubi_tools_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 92int ubi_tools_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
130int ubi_tools_main(int argc UNUSED_PARAM, char **argv) 93int ubi_tools_main(int argc UNUSED_PARAM, char **argv)
131{ 94{
95 static const struct suffix_mult size_suffixes[] = {
96 { "KiB", 1024 },
97 { "MiB", 1024*1024 },
98 { "GiB", 1024*1024*1024 },
99 { "", 0 }
100 };
101
132 unsigned opts; 102 unsigned opts;
133 char *ubi_ctrl; 103 char *ubi_ctrl;
134 //struct stat st;
135 int fd; 104 int fd;
136 int mtd_num; 105 int mtd_num;
137 int dev_num = UBI_DEV_NUM_AUTO; 106 int dev_num = UBI_DEV_NUM_AUTO;
138 int vol_id = UBI_VOL_NUM_AUTO; 107 int vol_id = UBI_VOL_NUM_AUTO;
139 char *vol_name = NULL; 108 char *vol_name;
140 int size_bytes; 109 unsigned long long size_bytes = size_bytes; /* for compiler */
110 char *size_bytes_str;
141 int alignment = 1; 111 int alignment = 1;
142 char *type = NULL; 112 char *type;
113 union {
114 struct ubi_attach_req attach_req;
115 struct ubi_mkvol_req mkvol_req;
116 struct ubi_rsvol_req rsvol_req;
117 } req_structs;
118#define attach_req req_structs.attach_req
119#define mkvol_req req_structs.mkvol_req
120#define rsvol_req req_structs.rsvol_req
121 char path[sizeof("/sys/class/ubi/ubi%d_%d/usable_eb_size")
122 + 2 * sizeof(int)*3 + /*just in case:*/ 16];
123#define path_sys_class_ubi_ubi (path + sizeof("/sys/class/ubi/ubi")-1)
124
125 strcpy(path, "/sys/class/ubi/ubi");
126 memset(&req_structs, 0, sizeof(req_structs));
127
128 if (do_mkvol) {
129 opt_complementary = "-1:d+:n+:a+";
130 opts = getopt32(argv, "md:n:N:s:a:t:",
131 &dev_num, &vol_id,
132 &vol_name, &size_bytes_str, &alignment, &type
133 );
134 } else {
135 opt_complementary = "-1:m+:d+:n+:a+";
136 opts = getopt32(argv, "m:d:n:N:s:a:t:",
137 &mtd_num, &dev_num, &vol_id,
138 &vol_name, &size_bytes_str, &alignment, &type
139 );
140 }
141#define OPTION_m (1 << 0)
142#define OPTION_d (1 << 1)
143#define OPTION_n (1 << 2)
144#define OPTION_N (1 << 3)
145#define OPTION_s (1 << 4)
146#define OPTION_a (1 << 5)
147#define OPTION_t (1 << 6)
143 148
144 opt_complementary = "-1:m+:d+:n+:s+:a+"; 149 if (opts & OPTION_s)
145 opts = getopt32(argv, "m:d:n:N:s:a:t::", 150 size_bytes = xatoull_sfx(size_bytes_str, size_suffixes);
146 &mtd_num, &dev_num, &vol_id, 151 argv += optind;
147 &vol_name, &size_bytes, &alignment, &type 152 ubi_ctrl = *argv++;
148 );
149 ubi_ctrl = argv[optind];
150 153
151 fd = xopen(ubi_ctrl, O_RDWR); 154 fd = xopen(ubi_ctrl, O_RDWR);
152 //xfstat(fd, &st, ubi_ctrl); 155 //xfstat(fd, &st, ubi_ctrl);
153 //if (!S_ISCHR(st.st_mode)) 156 //if (!S_ISCHR(st.st_mode))
154 // bb_error_msg_and_die("%s: not a char device", ubi_ctrl); 157 // bb_error_msg_and_die("%s: not a char device", ubi_ctrl);
155 158
159//usage:#define ubiattach_trivial_usage
160//usage: "-m MTD_NUM [-d UBI_NUM] UBI_CTRL_DEV"
161//usage:#define ubiattach_full_usage "\n\n"
162//usage: "Attach MTD device to UBI\n"
163//usage: "\n -m MTD_NUM MTD device number to attach"
164//usage: "\n -d UBI_NUM UBI device number to assign"
156 if (do_attach) { 165 if (do_attach) {
157 struct ubi_attach_req req; 166 if (!(opts & OPTION_m))
158 if (!(opts & OPTION_M))
159 bb_error_msg_and_die("%s device not specified", "MTD"); 167 bb_error_msg_and_die("%s device not specified", "MTD");
160 168
161 memset(&req, 0, sizeof(req)); 169 attach_req.mtd_num = mtd_num;
162 req.mtd_num = mtd_num; 170 attach_req.ubi_num = dev_num;
163 req.ubi_num = dev_num;
164 171
165 xioctl(fd, UBI_IOCATT, &req); 172 xioctl(fd, UBI_IOCATT, &attach_req);
166 } else 173 } else
174
175//usage:#define ubidetach_trivial_usage
176//usage: "-d UBI_NUM UBI_CTRL_DEV"
177//usage:#define ubidetach_full_usage "\n\n"
178//usage: "Detach MTD device from UBI\n"
179//usage: "\n -d UBI_NUM UBI device number"
167 if (do_detach) { 180 if (do_detach) {
168 if (!(opts & OPTION_D)) 181 if (!(opts & OPTION_d))
169 bb_error_msg_and_die("%s device not specified", "UBI"); 182 bb_error_msg_and_die("%s device not specified", "UBI");
170 183
184 /* FIXME? kernel expects int32_t* here: */
171 xioctl(fd, UBI_IOCDET, &dev_num); 185 xioctl(fd, UBI_IOCDET, &dev_num);
172 } else 186 } else
187
188//usage:#define ubimkvol_trivial_usage
189//usage: "UBI_DEVICE -N NAME [-s SIZE | -m]"
190//usage:#define ubimkvol_full_usage "\n\n"
191//usage: "Create UBI volume\n"
192//usage: "\n -a ALIGNMENT Volume alignment (default 1)"
193//usage: "\n -m Set volume size to maximum available"
194//usage: "\n -n VOLID Volume ID. If not specified,"
195//usage: "\n assigned automatically"
196//usage: "\n -N NAME Volume name"
197//usage: "\n -s SIZE Size in bytes"
198//usage: "\n -t TYPE Volume type (static|dynamic)"
173 if (do_mkvol) { 199 if (do_mkvol) {
174 struct ubi_mkvol_req req; 200 if (opts & OPTION_m) {
175 int vol_name_len; 201 unsigned leb_avail;
202 unsigned leb_size;
203 unsigned num;
204 char *p;
205
206 if (sscanf(ubi_ctrl, "/dev/ubi%u", &num) != 1)
207 bb_error_msg_and_die("wrong format of UBI device name");
208
209 p = path_sys_class_ubi_ubi + sprintf(path_sys_class_ubi_ubi, "%u/", num);
210
211 strcpy(p, "avail_eraseblocks");
212 leb_avail = get_num_from_file(path, UINT_MAX, "Can't get available eraseblocks from '%s'");
213
214 strcpy(p, "eraseblock_size");
215 leb_size = get_num_from_file(path, MAX_SANE_ERASEBLOCK, "Can't get eraseblock size from '%s'");
216
217 size_bytes = leb_avail * (unsigned long long)leb_size;
218 //if (size_bytes <= 0)
219 // bb_error_msg_and_die("%s invalid maximum size calculated", "UBI");
220 } else
176 if (!(opts & OPTION_s)) 221 if (!(opts & OPTION_s))
177 bb_error_msg_and_die("%s size not specified", "UBI"); 222 bb_error_msg_and_die("size not specified");
223
178 if (!(opts & OPTION_N)) 224 if (!(opts & OPTION_N))
179 bb_error_msg_and_die("%s name not specified", "UBI"); 225 bb_error_msg_and_die("name not specified");
180 vol_name_len = strlen(vol_name); 226
181 if (vol_name_len > UBI_MAX_VOLUME_NAME) 227 mkvol_req.vol_id = vol_id;
182 bb_error_msg_and_die("%s volume name too long", "UBI"); 228 mkvol_req.vol_type = UBI_DYNAMIC_VOLUME;
183 229 if ((opts & OPTION_t) && type[0] == 's')
184 memset(&req, 0, sizeof(req)); 230 mkvol_req.vol_type = UBI_STATIC_VOLUME;
185 req.vol_id = vol_id; 231 mkvol_req.alignment = alignment;
186 if ((opts & OPTION_t) && type) { 232 mkvol_req.bytes = size_bytes; /* signed int64_t */
187 if (type[0] == 's') 233 strncpy(mkvol_req.name, vol_name, UBI_MAX_VOLUME_NAME);
188 req.vol_type = UBI_STATIC_VOLUME; 234 mkvol_req.name_len = strlen(vol_name);
189 else 235 if (mkvol_req.name_len > UBI_MAX_VOLUME_NAME)
190 req.vol_type = UBI_DYNAMIC_VOLUME; 236 bb_error_msg_and_die("volume name too long: '%s'", vol_name);
191 } else {
192 req.vol_type = UBI_DYNAMIC_VOLUME;
193 }
194 req.alignment = alignment;
195 req.bytes = size_bytes;
196 strncpy(req.name, vol_name, UBI_MAX_VOLUME_NAME);
197 req.name_len = vol_name_len;
198 237
199 xioctl(fd, UBI_IOCMKVOL, &req); 238 xioctl(fd, UBI_IOCMKVOL, &mkvol_req);
200 } else 239 } else
240
241//usage:#define ubirmvol_trivial_usage
242//usage: "UBI_DEVICE -n VOLID"
243//usage:#define ubirmvol_full_usage "\n\n"
244//usage: "Remove UBI volume\n"
245//usage: "\n -n VOLID Volume ID"
201 if (do_rmvol) { 246 if (do_rmvol) {
202 if (!(opts & OPTION_n)) 247 if (!(opts & OPTION_n))
203 bb_error_msg_and_die("%s volume id not specified", "UBI"); 248 bb_error_msg_and_die("volume id not specified");
204 249
250 /* FIXME? kernel expects int32_t* here: */
205 xioctl(fd, UBI_IOCRMVOL, &vol_id); 251 xioctl(fd, UBI_IOCRMVOL, &vol_id);
206 } else 252 } else
253
254//usage:#define ubirsvol_trivial_usage
255//usage: "UBI_DEVICE -n VOLID -s SIZE"
256//usage:#define ubirsvol_full_usage "\n\n"
257//usage: "Resize UBI volume\n"
258//usage: "\n -n VOLID Volume ID"
259//usage: "\n -s SIZE Size in bytes"
207 if (do_rsvol) { 260 if (do_rsvol) {
208 struct ubi_rsvol_req req;
209 if (!(opts & OPTION_s)) 261 if (!(opts & OPTION_s))
210 bb_error_msg_and_die("%s size not specified", "UBI"); 262 bb_error_msg_and_die("size not specified");
211 if (!(opts & OPTION_n)) 263 if (!(opts & OPTION_n))
212 bb_error_msg_and_die("%s volume id not specified", "UBI"); 264 bb_error_msg_and_die("volume id not specified");
213 265
214 memset(&req, 0, sizeof(req)); 266 rsvol_req.bytes = size_bytes; /* signed int64_t */
215 req.bytes = size_bytes; 267 rsvol_req.vol_id = vol_id;
216 req.vol_id = vol_id;
217 268
218 xioctl(fd, UBI_IOCRSVOL, &req); 269 xioctl(fd, UBI_IOCRSVOL, &rsvol_req);
219 } else 270 } else
271
272//usage:#define ubiupdatevol_trivial_usage
273//usage: "UBI_DEVICE [-t | [-s SIZE] IMG_FILE]"
274//usage:#define ubiupdatevol_full_usage "\n\n"
275//usage: "Update UBI volume\n"
276//usage: "\n -t Truncate to zero size"
277//usage: "\n -s SIZE Size in bytes to resize to"
220 if (do_update) { 278 if (do_update) {
221 long long bytes; 279 int64_t bytes64;
222 280
223 if (opts & OPTION_t) { 281 if (opts & OPTION_t) {
224 // truncate the volume by starting an update for size 0 282 /* truncate the volume by starting an update for size 0 */
225 bytes = 0; 283 bytes64 = 0;
226 xioctl(fd, UBI_IOCVOLUP, &bytes); 284 /* this ioctl expects int64_t* parameter */
285 xioctl(fd, UBI_IOCVOLUP, &bytes64);
227 } 286 }
228 else { 287 else {
229 struct stat st; 288 struct stat st;
230 char buf[sizeof("/sys/class/ubi/ubi%d_%d/usable_eb_size") + 2 * sizeof(int)*3];
231 int input_fd;
232 unsigned ubinum, volnum; 289 unsigned ubinum, volnum;
233 unsigned leb_size; 290 unsigned leb_size;
234 ssize_t len; 291 ssize_t len;
235 char *input_data; 292 char *input_data;
236 293
237 // Make assumption that device not is in normal format. 294 /* Assume that device is in normal format. */
238 // Removes need for scanning sysfs tree as full libubi does 295 /* Removes need for scanning sysfs tree as full libubi does. */
239 if (sscanf(ubi_ctrl, "/dev/ubi%u_%u", &ubinum, &volnum) != 2) 296 if (sscanf(ubi_ctrl, "/dev/ubi%u_%u", &ubinum, &volnum) != 2)
240 bb_error_msg_and_die("%s volume node not in correct format", "UBI"); 297 bb_error_msg_and_die("wrong format of UBI device name");
241 298
242 sprintf(buf, "/sys/class/ubi/ubi%u_%u/usable_eb_size", ubinum, volnum); 299 sprintf(path_sys_class_ubi_ubi, "%u_%u/usable_eb_size", ubinum, volnum);
243 if (open_read_close(buf, buf, sizeof(buf)) <= 0) 300 leb_size = get_num_from_file(path, MAX_SANE_ERASEBLOCK, "Can't get usable eraseblock size from '%s'");
244 bb_error_msg_and_die("%s could not get LEB size", "UBI"); 301
245 if (sscanf(buf, "%u", &leb_size) != 1) 302 if (!(opts & OPTION_s)) {
246 bb_error_msg_and_die("%s could not get LEB size", "UBI"); 303 if (!*argv)
247
248 if (opts & OPTION_s) {
249 input_fd = 0;
250 } else {
251 if (!argv[optind+1])
252 bb_show_usage(); 304 bb_show_usage();
253 xstat(argv[optind+1], &st); 305 xstat(*argv, &st);
254 size_bytes = st.st_size; 306 size_bytes = st.st_size;
255 input_fd = xopen(argv[optind+1], O_RDONLY); 307 xmove_fd(xopen(*argv, O_RDONLY), STDIN_FILENO);
256 } 308 }
257 309
258 bytes = size_bytes; 310 bytes64 = size_bytes;
259 xioctl(fd, UBI_IOCVOLUP, &bytes); 311 /* this ioctl expects signed int64_t* parameter */
312 xioctl(fd, UBI_IOCVOLUP, &bytes64);
260 313
261 input_data = xmalloc(leb_size); 314 input_data = xmalloc(leb_size);
262 while ((len = full_read(input_fd, input_data, leb_size)) > 0) { 315 while ((len = full_read(STDIN_FILENO, input_data, leb_size)) > 0) {
263 xwrite(fd, input_data, len); 316 xwrite(fd, input_data, len);
264 } 317 }
265 if (len < 0) 318 if (len < 0)
266 bb_error_msg_and_die("%s volume update failed", "UBI"); 319 bb_perror_msg_and_die("UBI volume update failed");
267 if (ENABLE_FEATURE_CLEAN_UP)
268 close(input_fd);
269 } 320 }
270 } 321 }
271 322