diff options
author | Ron Yorston <rmy@pobox.com> | 2021-10-13 14:37:51 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2021-10-13 14:37:51 +0100 |
commit | 0ecf1aea459571b48dc68ddc2b7b9265740fa960 (patch) | |
tree | 491d6184a44b8b525a4ca35759d622aecd7f6344 /libbb | |
parent | 4859ddcb20616718efbea12c6bf8b27c469b68de (diff) | |
parent | aaf3d5ba74c5da97ff80b61f30cb8dd225d39096 (diff) | |
download | busybox-w32-0ecf1aea459571b48dc68ddc2b7b9265740fa960.tar.gz busybox-w32-0ecf1aea459571b48dc68ddc2b7b9265740fa960.tar.bz2 busybox-w32-0ecf1aea459571b48dc68ddc2b7b9265740fa960.zip |
Merge branch 'busybox' into merge
Diffstat (limited to 'libbb')
-rw-r--r-- | libbb/Config.src | 185 | ||||
-rw-r--r-- | libbb/Kbuild.src | 1 | ||||
-rw-r--r-- | libbb/appletlib.c | 23 | ||||
-rw-r--r-- | libbb/const_hack.c | 16 | ||||
-rw-r--r-- | libbb/dump.c | 2 | ||||
-rw-r--r-- | libbb/lineedit.c | 94 | ||||
-rw-r--r-- | libbb/vfork_daemon_rexec.c | 16 | ||||
-rw-r--r-- | libbb/xreadlink.c | 75 |
8 files changed, 210 insertions, 202 deletions
diff --git a/libbb/Config.src b/libbb/Config.src index 58c5fad50..24b31fad9 100644 --- a/libbb/Config.src +++ b/libbb/Config.src | |||
@@ -61,32 +61,73 @@ config SHA3_SMALL | |||
61 | 64-bit x86: +270 bytes of code, 45% faster | 61 | 64-bit x86: +270 bytes of code, 45% faster |
62 | 32-bit x86: +450 bytes of code, 75% faster | 62 | 32-bit x86: +450 bytes of code, 75% faster |
63 | 63 | ||
64 | config FEATURE_FAST_TOP | 64 | config FEATURE_NON_POSIX_CP |
65 | bool "Faster /proc scanning code (+100 bytes)" | 65 | bool "Non-POSIX, but safer, copying to special nodes" |
66 | default n # all "fast or small" options default to small | 66 | default y |
67 | help | 67 | help |
68 | This option makes top and ps ~20% faster (or 20% less CPU hungry), | 68 | With this option, "cp file symlink" will delete symlink |
69 | but code size is slightly bigger. | 69 | and create a regular file. This does not conform to POSIX, |
70 | but prevents a symlink attack. | ||
71 | Similarly, "cp file device" will not send file's data | ||
72 | to the device. (To do that, use "cat file >device") | ||
70 | 73 | ||
71 | config FEATURE_ETC_NETWORKS | 74 | config FEATURE_VERBOSE_CP_MESSAGE |
72 | bool "Support /etc/networks" | 75 | bool "Give more precise messages when copy fails (cp, mv etc)" |
73 | default n | 76 | default n |
74 | help | 77 | help |
75 | Enable support for network names in /etc/networks. This is | 78 | Error messages with this feature enabled: |
76 | a rarely used feature which allows you to use names | ||
77 | instead of IP/mask pairs in route command. | ||
78 | 79 | ||
79 | config FEATURE_ETC_SERVICES | 80 | $ cp file /does_not_exist/file |
80 | bool "Consult /etc/services even for well-known ports" | 81 | cp: cannot create '/does_not_exist/file': Path does not exist |
81 | default n | 82 | $ cp file /vmlinuz/file |
83 | cp: cannot stat '/vmlinuz/file': Path has non-directory component | ||
84 | |||
85 | If this feature is not enabled, they will be, respectively: | ||
86 | |||
87 | cp: cannot create '/does_not_exist/file': No such file or directory | ||
88 | cp: cannot stat '/vmlinuz/file': Not a directory | ||
89 | |||
90 | This will cost you ~60 bytes. | ||
91 | |||
92 | config FEATURE_USE_SENDFILE | ||
93 | bool "Use sendfile system call" | ||
94 | default y | ||
95 | help | ||
96 | When enabled, busybox will use the kernel sendfile() function | ||
97 | instead of read/write loops to copy data between file descriptors | ||
98 | (for example, cp command does this a lot). | ||
99 | If sendfile() doesn't work, copying code falls back to read/write | ||
100 | loop. sendfile() was originally implemented for faster I/O | ||
101 | from files to sockets, but since Linux 2.6.33 it was extended | ||
102 | to work for many more file types. | ||
103 | |||
104 | config FEATURE_COPYBUF_KB | ||
105 | int "Copy buffer size, in kilobytes" | ||
106 | range 1 1024 | ||
107 | default 4 | ||
108 | help | ||
109 | Size of buffer used by cp, mv, install, wget etc. | ||
110 | Buffers which are 4 kb or less will be allocated on stack. | ||
111 | Bigger buffers will be allocated with mmap, with fallback to 4 kb | ||
112 | stack buffer if mmap fails. | ||
113 | |||
114 | config MONOTONIC_SYSCALL | ||
115 | bool "Use clock_gettime(CLOCK_MONOTONIC) syscall" | ||
116 | default y | ||
117 | help | ||
118 | Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring | ||
119 | time intervals (time, ping, traceroute etc need this). | ||
120 | Probably requires Linux 2.6+. If not selected, gettimeofday | ||
121 | will be used instead (which gives wrong results if date/time | ||
122 | is reset). | ||
123 | |||
124 | config IOCTL_HEX2STR_ERROR | ||
125 | bool "Use ioctl names rather than hex values in error messages" | ||
126 | default y | ||
82 | help | 127 | help |
83 | Look up e.g. "telnet" and "http" in /etc/services file | 128 | Use ioctl names rather than hex values in error messages |
84 | instead of assuming ports 23 and 80. | 129 | (e.g. VT_DISALLOCATE rather than 0x5608). If disabled this |
85 | This is almost never necessary (everybody uses standard ports), | 130 | saves about 1400 bytes. |
86 | and it makes sense to avoid reading this file. | ||
87 | If you disable this option, in the cases where port is explicitly | ||
88 | specified as a service name (e.g. "telnet HOST PORTNAME"), | ||
89 | it will still be looked up in /etc/services. | ||
90 | 131 | ||
91 | config FEATURE_EDITING | 132 | config FEATURE_EDITING |
92 | bool "Command line editing" | 133 | bool "Command line editing" |
@@ -302,107 +343,3 @@ config UNICODE_PRESERVE_BROKEN | |||
302 | For example, this means that entering 'l', 's', ' ', 0xff, [Enter] | 343 | For example, this means that entering 'l', 's', ' ', 0xff, [Enter] |
303 | at shell prompt will list file named 0xff (single char name | 344 | at shell prompt will list file named 0xff (single char name |
304 | with char value 255), not file named '?'. | 345 | with char value 255), not file named '?'. |
305 | |||
306 | config FEATURE_NON_POSIX_CP | ||
307 | bool "Non-POSIX, but safer, copying to special nodes" | ||
308 | default y | ||
309 | help | ||
310 | With this option, "cp file symlink" will delete symlink | ||
311 | and create a regular file. This does not conform to POSIX, | ||
312 | but prevents a symlink attack. | ||
313 | Similarly, "cp file device" will not send file's data | ||
314 | to the device. (To do that, use "cat file >device") | ||
315 | |||
316 | config FEATURE_VERBOSE_CP_MESSAGE | ||
317 | bool "Give more precise messages when copy fails (cp, mv etc)" | ||
318 | default n | ||
319 | help | ||
320 | Error messages with this feature enabled: | ||
321 | |||
322 | $ cp file /does_not_exist/file | ||
323 | cp: cannot create '/does_not_exist/file': Path does not exist | ||
324 | $ cp file /vmlinuz/file | ||
325 | cp: cannot stat '/vmlinuz/file': Path has non-directory component | ||
326 | |||
327 | If this feature is not enabled, they will be, respectively: | ||
328 | |||
329 | cp: cannot create '/does_not_exist/file': No such file or directory | ||
330 | cp: cannot stat '/vmlinuz/file': Not a directory | ||
331 | |||
332 | This will cost you ~60 bytes. | ||
333 | |||
334 | config FEATURE_USE_SENDFILE | ||
335 | bool "Use sendfile system call" | ||
336 | default y | ||
337 | help | ||
338 | When enabled, busybox will use the kernel sendfile() function | ||
339 | instead of read/write loops to copy data between file descriptors | ||
340 | (for example, cp command does this a lot). | ||
341 | If sendfile() doesn't work, copying code falls back to read/write | ||
342 | loop. sendfile() was originally implemented for faster I/O | ||
343 | from files to sockets, but since Linux 2.6.33 it was extended | ||
344 | to work for many more file types. | ||
345 | |||
346 | config FEATURE_COPYBUF_KB | ||
347 | int "Copy buffer size, in kilobytes" | ||
348 | range 1 1024 | ||
349 | default 4 | ||
350 | help | ||
351 | Size of buffer used by cp, mv, install, wget etc. | ||
352 | Buffers which are 4 kb or less will be allocated on stack. | ||
353 | Bigger buffers will be allocated with mmap, with fallback to 4 kb | ||
354 | stack buffer if mmap fails. | ||
355 | |||
356 | config FEATURE_SKIP_ROOTFS | ||
357 | bool "Skip rootfs in mount table" | ||
358 | default y | ||
359 | help | ||
360 | Ignore rootfs entry in mount table. | ||
361 | |||
362 | In Linux, kernel has a special filesystem, rootfs, which is initially | ||
363 | mounted on /. It contains initramfs data, if kernel is configured | ||
364 | to have one. Usually, another file system is mounted over / early | ||
365 | in boot process, and therefore most tools which manipulate | ||
366 | mount table, such as df, will skip rootfs entry. | ||
367 | |||
368 | However, some systems do not mount anything on /. | ||
369 | If you need to configure busybox for one of these systems, | ||
370 | you may find it useful to turn this option off to make df show | ||
371 | initramfs statistics. | ||
372 | |||
373 | Otherwise, choose Y. | ||
374 | |||
375 | config MONOTONIC_SYSCALL | ||
376 | bool "Use clock_gettime(CLOCK_MONOTONIC) syscall" | ||
377 | default y | ||
378 | help | ||
379 | Use clock_gettime(CLOCK_MONOTONIC) syscall for measuring | ||
380 | time intervals (time, ping, traceroute etc need this). | ||
381 | Probably requires Linux 2.6+. If not selected, gettimeofday | ||
382 | will be used instead (which gives wrong results if date/time | ||
383 | is reset). | ||
384 | |||
385 | config IOCTL_HEX2STR_ERROR | ||
386 | bool "Use ioctl names rather than hex values in error messages" | ||
387 | default y | ||
388 | help | ||
389 | Use ioctl names rather than hex values in error messages | ||
390 | (e.g. VT_DISALLOCATE rather than 0x5608). If disabled this | ||
391 | saves about 1400 bytes. | ||
392 | |||
393 | config FEATURE_HWIB | ||
394 | bool "Support infiniband HW" | ||
395 | default y | ||
396 | help | ||
397 | Support for printing infiniband addresses in network applets. | ||
398 | |||
399 | config FEATURE_TIMEZONE | ||
400 | bool "Allow timezone in dates" | ||
401 | default y | ||
402 | depends on DESKTOP | ||
403 | help | ||
404 | Permit the use of timezones when parsing user-provided data | ||
405 | strings, e.g. '1996-04-09 12:45:00 -0500'. | ||
406 | |||
407 | This requires support for the '%z' extension to strptime() which | ||
408 | may not be available in all implementations. | ||
diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src index 102e360af..60df3476f 100644 --- a/libbb/Kbuild.src +++ b/libbb/Kbuild.src | |||
@@ -21,6 +21,7 @@ lib-y += chomp.o | |||
21 | lib-y += compare_string_array.o | 21 | lib-y += compare_string_array.o |
22 | lib-y += concat_path_file.o | 22 | lib-y += concat_path_file.o |
23 | lib-y += concat_subpath_file.o | 23 | lib-y += concat_subpath_file.o |
24 | lib-y += const_hack.o | ||
24 | lib-y += copy_file.o | 25 | lib-y += copy_file.o |
25 | lib-y += copyfd.o | 26 | lib-y += copyfd.o |
26 | lib-y += crc32.o | 27 | lib-y += crc32.o |
diff --git a/libbb/appletlib.c b/libbb/appletlib.c index e1f8bf432..6c0be4a83 100644 --- a/libbb/appletlib.c +++ b/libbb/appletlib.c | |||
@@ -262,8 +262,7 @@ void lbb_prepare(const char *applet | |||
262 | IF_FEATURE_INDIVIDUAL(, char **argv)) | 262 | IF_FEATURE_INDIVIDUAL(, char **argv)) |
263 | { | 263 | { |
264 | #ifdef bb_cached_errno_ptr | 264 | #ifdef bb_cached_errno_ptr |
265 | (*(int **)not_const_pp(&bb_errno)) = get_perrno(); | 265 | ASSIGN_CONST_PTR(&bb_errno, get_perrno()); |
266 | barrier(); | ||
267 | #endif | 266 | #endif |
268 | applet_name = applet; | 267 | applet_name = applet; |
269 | 268 | ||
@@ -767,9 +766,9 @@ int scripted_main(int argc UNUSED_PARAM, char **argv) | |||
767 | int script = find_script_by_name(applet_name); | 766 | int script = find_script_by_name(applet_name); |
768 | if (script >= 0) | 767 | if (script >= 0) |
769 | # if ENABLE_SHELL_ASH | 768 | # if ENABLE_SHELL_ASH |
770 | exit(ash_main(-script - 1, argv)); | 769 | return ash_main(-script - 1, argv); |
771 | # elif ENABLE_SHELL_HUSH | 770 | # elif ENABLE_SHELL_HUSH |
772 | exit(hush_main(-script - 1, argv)); | 771 | return hush_main(-script - 1, argv); |
773 | # else | 772 | # else |
774 | return 1; | 773 | return 1; |
775 | # endif | 774 | # endif |
@@ -1161,10 +1160,10 @@ int scripted_main(int argc UNUSED_PARAM, char **argv) | |||
1161 | { | 1160 | { |
1162 | # if ENABLE_SHELL_ASH | 1161 | # if ENABLE_SHELL_ASH |
1163 | int script = 0; | 1162 | int script = 0; |
1164 | exit(ash_main(-script - 1, argv)); | 1163 | return ash_main(-script - 1, argv); |
1165 | # elif ENABLE_SHELL_HUSH | 1164 | # elif ENABLE_SHELL_HUSH |
1166 | int script = 0; | 1165 | int script = 0; |
1167 | exit(hush_main(-script - 1, argv)); | 1166 | return hush_main(-script - 1, argv); |
1168 | # else | 1167 | # else |
1169 | return 1; | 1168 | return 1; |
1170 | # endif | 1169 | # endif |
@@ -1282,7 +1281,7 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
1282 | 1281 | ||
1283 | full_write2_str(bb_basename(argv[0])); | 1282 | full_write2_str(bb_basename(argv[0])); |
1284 | full_write2_str(": no applets enabled\n"); | 1283 | full_write2_str(": no applets enabled\n"); |
1285 | exit(127); | 1284 | return 127; |
1286 | 1285 | ||
1287 | #else | 1286 | #else |
1288 | 1287 | ||
@@ -1314,8 +1313,14 @@ int main(int argc UNUSED_PARAM, char **argv) | |||
1314 | || ENABLE_FEATURE_PREFER_APPLETS | 1313 | || ENABLE_FEATURE_PREFER_APPLETS |
1315 | || !BB_MMU | 1314 | || !BB_MMU |
1316 | ) { | 1315 | ) { |
1317 | if (NUM_APPLETS > 1) | 1316 | if (NUM_APPLETS > 1) { |
1318 | set_task_comm(applet_name); | 1317 | /* Careful, do not trash comm of "SCRIPT.sh" - |
1318 | * the case when started from e.g. #!/bin/ash script. | ||
1319 | * (not limited to shells - #!/bin/awk scripts also exist) | ||
1320 | */ | ||
1321 | if (re_execed_comm()) | ||
1322 | set_task_comm(applet_name); | ||
1323 | } | ||
1319 | } | 1324 | } |
1320 | 1325 | ||
1321 | parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */ | 1326 | parse_config_file(); /* ...maybe, if FEATURE_SUID_CONFIG */ |
diff --git a/libbb/const_hack.c b/libbb/const_hack.c new file mode 100644 index 000000000..9575e6d67 --- /dev/null +++ b/libbb/const_hack.c | |||
@@ -0,0 +1,16 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * Trick to assign a const ptr with barrier for clang | ||
4 | * | ||
5 | * Copyright (C) 2021 by YU Jincheng <shana@zju.edu.cn> | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see file LICENSE in this source tree. | ||
8 | */ | ||
9 | #include "libbb.h" | ||
10 | |||
11 | #if defined(__clang_major__) && __clang_major__ >= 9 | ||
12 | void FAST_FUNC XZALLOC_CONST_PTR(const void *pptr, size_t size) | ||
13 | { | ||
14 | ASSIGN_CONST_PTR(pptr, xzalloc(size)); | ||
15 | } | ||
16 | #endif | ||
diff --git a/libbb/dump.c b/libbb/dump.c index ffae04786..d24057325 100644 --- a/libbb/dump.c +++ b/libbb/dump.c | |||
@@ -568,7 +568,7 @@ static void conv_u(PR *pr, unsigned char *p) | |||
568 | } | 568 | } |
569 | } | 569 | } |
570 | 570 | ||
571 | static void display(priv_dumper_t* dumper) | 571 | static NOINLINE void display(priv_dumper_t* dumper) |
572 | { | 572 | { |
573 | unsigned char *bp; | 573 | unsigned char *bp; |
574 | unsigned char savech = '\0'; | 574 | unsigned char savech = '\0'; |
diff --git a/libbb/lineedit.c b/libbb/lineedit.c index 7c46fa5db..8abc87976 100644 --- a/libbb/lineedit.c +++ b/libbb/lineedit.c | |||
@@ -135,10 +135,6 @@ enum { | |||
135 | : 0x7ff0 | 135 | : 0x7ff0 |
136 | }; | 136 | }; |
137 | 137 | ||
138 | #if ENABLE_USERNAME_OR_HOMEDIR | ||
139 | static const char null_str[] ALIGN1 = ""; | ||
140 | #endif | ||
141 | |||
142 | /* We try to minimize both static and stack usage. */ | 138 | /* We try to minimize both static and stack usage. */ |
143 | struct lineedit_statics { | 139 | struct lineedit_statics { |
144 | line_input_t *state; | 140 | line_input_t *state; |
@@ -161,12 +157,13 @@ struct lineedit_statics { | |||
161 | 157 | ||
162 | #if ENABLE_USERNAME_OR_HOMEDIR | 158 | #if ENABLE_USERNAME_OR_HOMEDIR |
163 | char *user_buf; | 159 | char *user_buf; |
164 | char *home_pwd_buf; /* = (char*)null_str; */ | 160 | char *home_pwd_buf; |
161 | smallint got_user_strings; | ||
165 | #endif | 162 | #endif |
166 | 163 | ||
167 | #if ENABLE_FEATURE_TAB_COMPLETION | 164 | #if ENABLE_FEATURE_TAB_COMPLETION |
168 | char **matches; | ||
169 | unsigned num_matches; | 165 | unsigned num_matches; |
166 | char **matches; | ||
170 | #endif | 167 | #endif |
171 | 168 | ||
172 | #if ENABLE_FEATURE_EDITING_WINCH | 169 | #if ENABLE_FEATURE_EDITING_WINCH |
@@ -192,7 +189,7 @@ struct lineedit_statics { | |||
192 | }; | 189 | }; |
193 | 190 | ||
194 | /* See lineedit_ptr_hack.c */ | 191 | /* See lineedit_ptr_hack.c */ |
195 | extern struct lineedit_statics *const lineedit_ptr_to_statics; | 192 | extern struct lineedit_statics *BB_GLOBAL_CONST lineedit_ptr_to_statics; |
196 | 193 | ||
197 | #define S (*lineedit_ptr_to_statics) | 194 | #define S (*lineedit_ptr_to_statics) |
198 | #define state (S.state ) | 195 | #define state (S.state ) |
@@ -207,15 +204,15 @@ extern struct lineedit_statics *const lineedit_ptr_to_statics; | |||
207 | #define prompt_last_line (S.prompt_last_line) | 204 | #define prompt_last_line (S.prompt_last_line) |
208 | #define user_buf (S.user_buf ) | 205 | #define user_buf (S.user_buf ) |
209 | #define home_pwd_buf (S.home_pwd_buf ) | 206 | #define home_pwd_buf (S.home_pwd_buf ) |
210 | #define matches (S.matches ) | 207 | #define got_user_strings (S.got_user_strings) |
211 | #define num_matches (S.num_matches ) | 208 | #define num_matches (S.num_matches ) |
209 | #define matches (S.matches ) | ||
212 | #define delptr (S.delptr ) | 210 | #define delptr (S.delptr ) |
213 | #define newdelflag (S.newdelflag ) | 211 | #define newdelflag (S.newdelflag ) |
214 | #define delbuf (S.delbuf ) | 212 | #define delbuf (S.delbuf ) |
215 | 213 | ||
216 | #define INIT_S() do { \ | 214 | #define INIT_S() do { \ |
217 | (*(struct lineedit_statics**)not_const_pp(&lineedit_ptr_to_statics)) = xzalloc(sizeof(S)); \ | 215 | XZALLOC_CONST_PTR(&lineedit_ptr_to_statics, sizeof(S)); \ |
218 | barrier(); \ | ||
219 | } while (0) | 216 | } while (0) |
220 | 217 | ||
221 | static void deinit_S(void) | 218 | static void deinit_S(void) |
@@ -227,14 +224,47 @@ static void deinit_S(void) | |||
227 | #endif | 224 | #endif |
228 | #if ENABLE_USERNAME_OR_HOMEDIR | 225 | #if ENABLE_USERNAME_OR_HOMEDIR |
229 | free(user_buf); | 226 | free(user_buf); |
230 | if (home_pwd_buf != null_str) | 227 | free(home_pwd_buf); |
231 | free(home_pwd_buf); | ||
232 | #endif | 228 | #endif |
233 | free(lineedit_ptr_to_statics); | 229 | free(lineedit_ptr_to_statics); |
234 | } | 230 | } |
235 | #define DEINIT_S() deinit_S() | 231 | #define DEINIT_S() deinit_S() |
236 | 232 | ||
237 | 233 | ||
234 | #if ENABLE_USERNAME_OR_HOMEDIR | ||
235 | /* Call getpwuid() only if necessary. | ||
236 | * E.g. if PS1=':', no user database reading is needed to generate prompt. | ||
237 | * (Unfortunately, default PS1='\w \$' needs it, \w abbreviates homedir | ||
238 | * as ~/... - for that it needs to *know* the homedir...) | ||
239 | */ | ||
240 | static void get_user_strings(void) | ||
241 | { | ||
242 | struct passwd *entry; | ||
243 | |||
244 | got_user_strings = 1; | ||
245 | entry = getpwuid(geteuid()); | ||
246 | if (entry) { | ||
247 | user_buf = xstrdup(entry->pw_name); | ||
248 | home_pwd_buf = xstrdup(entry->pw_dir); | ||
249 | } | ||
250 | } | ||
251 | |||
252 | static const char *get_username_str(void) | ||
253 | { | ||
254 | if (!got_user_strings) | ||
255 | get_user_strings(); | ||
256 | return user_buf ? user_buf : ""; | ||
257 | /* btw, bash uses "I have no name!" string if uid has no entry */ | ||
258 | } | ||
259 | |||
260 | static NOINLINE const char *get_homedir_or_NULL(void) | ||
261 | { | ||
262 | if (!got_user_strings) | ||
263 | get_user_strings(); | ||
264 | return home_pwd_buf; | ||
265 | } | ||
266 | #endif | ||
267 | |||
238 | #if ENABLE_UNICODE_SUPPORT | 268 | #if ENABLE_UNICODE_SUPPORT |
239 | static size_t load_string(const char *src) | 269 | static size_t load_string(const char *src) |
240 | { | 270 | { |
@@ -748,11 +778,11 @@ static char *username_path_completion(char *ud) | |||
748 | struct passwd *entry; | 778 | struct passwd *entry; |
749 | #endif | 779 | #endif |
750 | char *tilde_name = ud; | 780 | char *tilde_name = ud; |
751 | char *home = NULL; | 781 | const char *home = NULL; |
752 | 782 | ||
753 | ud++; /* skip ~ */ | 783 | ud++; /* skip ~ */ |
754 | if (*ud == '/') { /* "~/..." */ | 784 | if (*ud == '/') { /* "~/..." */ |
755 | home = home_pwd_buf; | 785 | home = get_homedir_or_NULL(); |
756 | # if !ENABLE_PLATFORM_MINGW32 | 786 | # if !ENABLE_PLATFORM_MINGW32 |
757 | } else { | 787 | } else { |
758 | /* "~user/..." */ | 788 | /* "~user/..." */ |
@@ -1881,7 +1911,7 @@ vi_back_motion(void) | |||
1881 | input_backward(1); | 1911 | input_backward(1); |
1882 | } | 1912 | } |
1883 | } | 1913 | } |
1884 | #endif | 1914 | #endif /* ENABLE_FEATURE_EDITING_VI */ |
1885 | 1915 | ||
1886 | /* Modelled after bash 4.0 behavior of Ctrl-<arrow> */ | 1916 | /* Modelled after bash 4.0 behavior of Ctrl-<arrow> */ |
1887 | static void ctrl_left(void) | 1917 | static void ctrl_left(void) |
@@ -1982,7 +2012,7 @@ static void ask_terminal(void) | |||
1982 | } | 2012 | } |
1983 | } | 2013 | } |
1984 | #else | 2014 | #else |
1985 | #define ask_terminal() ((void)0) | 2015 | # define ask_terminal() ((void)0) |
1986 | #endif | 2016 | #endif |
1987 | 2017 | ||
1988 | /* Note about multi-line PS1 (e.g. "\n\w \u@\h\n> ") and prompt redrawing: | 2018 | /* Note about multi-line PS1 (e.g. "\n\w \u@\h\n> ") and prompt redrawing: |
@@ -2091,7 +2121,7 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
2091 | 2121 | ||
2092 | switch (c) { | 2122 | switch (c) { |
2093 | case 'u': | 2123 | case 'u': |
2094 | pbuf = user_buf ? user_buf : (char*)""; | 2124 | pbuf = (char*)get_username_str(); |
2095 | break; | 2125 | break; |
2096 | case 'H': | 2126 | case 'H': |
2097 | case 'h': | 2127 | case 'h': |
@@ -2113,14 +2143,15 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
2113 | case 'w': /* current dir */ | 2143 | case 'w': /* current dir */ |
2114 | case 'W': /* basename of cur dir */ | 2144 | case 'W': /* basename of cur dir */ |
2115 | if (!cwd_buf) { | 2145 | if (!cwd_buf) { |
2146 | const char *home; | ||
2116 | cwd_buf = xrealloc_getcwd_or_warn(NULL); | 2147 | cwd_buf = xrealloc_getcwd_or_warn(NULL); |
2117 | if (!cwd_buf) | 2148 | if (!cwd_buf) |
2118 | cwd_buf = (char *)bb_msg_unknown; | 2149 | cwd_buf = (char *)bb_msg_unknown; |
2119 | else if (home_pwd_buf[0]) { | 2150 | else if ((home = get_homedir_or_NULL()) != NULL && home[0]) { |
2120 | char *after_home_user; | 2151 | char *after_home_user; |
2121 | 2152 | ||
2122 | /* /home/user[/something] -> ~[/something] */ | 2153 | /* /home/user[/something] -> ~[/something] */ |
2123 | after_home_user = is_prefixed_with(cwd_buf, home_pwd_buf); | 2154 | after_home_user = is_prefixed_with(cwd_buf, home); |
2124 | if (after_home_user | 2155 | if (after_home_user |
2125 | && (*after_home_user == '/' || *after_home_user == '\0') | 2156 | && (*after_home_user == '/' || *after_home_user == '\0') |
2126 | ) { | 2157 | ) { |
@@ -2176,7 +2207,7 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
2176 | if (c == '\n') | 2207 | if (c == '\n') |
2177 | cmdedit_prmt_len = 0; | 2208 | cmdedit_prmt_len = 0; |
2178 | else if (flg_not_length != ']') { | 2209 | else if (flg_not_length != ']') { |
2179 | #if ENABLE_UNICODE_SUPPORT | 2210 | # if ENABLE_UNICODE_SUPPORT |
2180 | if (n == 1) { | 2211 | if (n == 1) { |
2181 | /* Only count single-byte characters and the first of multi-byte characters */ | 2212 | /* Only count single-byte characters and the first of multi-byte characters */ |
2182 | if ((unsigned char)*pbuf < 0x80 /* single byte character */ | 2213 | if ((unsigned char)*pbuf < 0x80 /* single byte character */ |
@@ -2187,9 +2218,9 @@ static void parse_and_put_prompt(const char *prmt_ptr) | |||
2187 | } else { | 2218 | } else { |
2188 | cmdedit_prmt_len += unicode_strwidth(pbuf); | 2219 | cmdedit_prmt_len += unicode_strwidth(pbuf); |
2189 | } | 2220 | } |
2190 | #else | 2221 | # else |
2191 | cmdedit_prmt_len += n; | 2222 | cmdedit_prmt_len += n; |
2192 | #endif | 2223 | # endif |
2193 | } | 2224 | } |
2194 | } | 2225 | } |
2195 | prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_size+1), pbuf); | 2226 | prmt_mem_ptr = strcat(xrealloc(prmt_mem_ptr, prmt_size+1), pbuf); |
@@ -2416,7 +2447,7 @@ static int32_t reverse_i_search(int timeout) | |||
2416 | } | 2447 | } |
2417 | 2448 | ||
2418 | /* Append this char */ | 2449 | /* Append this char */ |
2419 | #if ENABLE_UNICODE_SUPPORT | 2450 | # if ENABLE_UNICODE_SUPPORT |
2420 | if (unicode_status == UNICODE_ON) { | 2451 | if (unicode_status == UNICODE_ON) { |
2421 | mbstate_t mbstate = { 0 }; | 2452 | mbstate_t mbstate = { 0 }; |
2422 | char buf[MB_CUR_MAX + 1]; | 2453 | char buf[MB_CUR_MAX + 1]; |
@@ -2427,7 +2458,7 @@ static int32_t reverse_i_search(int timeout) | |||
2427 | strcpy(match_buf + match_buf_len, buf); | 2458 | strcpy(match_buf + match_buf_len, buf); |
2428 | } | 2459 | } |
2429 | } else | 2460 | } else |
2430 | #endif | 2461 | # endif |
2431 | if (match_buf_len < sizeof(match_buf) - 1) { | 2462 | if (match_buf_len < sizeof(match_buf) - 1) { |
2432 | match_buf[match_buf_len] = ic; | 2463 | match_buf[match_buf_len] = ic; |
2433 | match_buf[match_buf_len + 1] = '\0'; | 2464 | match_buf[match_buf_len + 1] = '\0'; |
@@ -2479,7 +2510,7 @@ static int32_t reverse_i_search(int timeout) | |||
2479 | 2510 | ||
2480 | return ic; | 2511 | return ic; |
2481 | } | 2512 | } |
2482 | #endif | 2513 | #endif /* ENABLE_FEATURE_REVERSE_SEARCH */ |
2483 | 2514 | ||
2484 | #if ENABLE_FEATURE_EDITING_WINCH | 2515 | #if ENABLE_FEATURE_EDITING_WINCH |
2485 | static void sigaction2(int sig, struct sigaction *act) | 2516 | static void sigaction2(int sig, struct sigaction *act) |
@@ -2521,7 +2552,6 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2521 | //command_len = 0; - done by INIT_S() | 2552 | //command_len = 0; - done by INIT_S() |
2522 | //cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */ | 2553 | //cmdedit_y = 0; /* quasireal y, not true if line > xt*yt */ |
2523 | cmdedit_termw = 80; | 2554 | cmdedit_termw = 80; |
2524 | IF_USERNAME_OR_HOMEDIR(home_pwd_buf = (char*)null_str;) | ||
2525 | IF_FEATURE_EDITING_VI(delptr = delbuf;) | 2555 | IF_FEATURE_EDITING_VI(delptr = delbuf;) |
2526 | 2556 | ||
2527 | #if !ENABLE_PLATFORM_MINGW32 | 2557 | #if !ENABLE_PLATFORM_MINGW32 |
@@ -2589,18 +2619,6 @@ int FAST_FUNC read_line_input(line_input_t *st, const char *prompt, char *comman | |||
2589 | tcsetattr_stdin_TCSANOW(&new_settings); | 2619 | tcsetattr_stdin_TCSANOW(&new_settings); |
2590 | #endif | 2620 | #endif |
2591 | 2621 | ||
2592 | #if ENABLE_USERNAME_OR_HOMEDIR | ||
2593 | { | ||
2594 | struct passwd *entry; | ||
2595 | |||
2596 | entry = getpwuid(geteuid()); | ||
2597 | if (entry) { | ||
2598 | user_buf = xstrdup(entry->pw_name); | ||
2599 | home_pwd_buf = xstrdup(entry->pw_dir); | ||
2600 | } | ||
2601 | } | ||
2602 | #endif | ||
2603 | |||
2604 | #if 0 | 2622 | #if 0 |
2605 | for (i = 0; i <= state->max_history; i++) | 2623 | for (i = 0; i <= state->max_history; i++) |
2606 | bb_error_msg("history[%d]:'%s'", i, state->history[i]); | 2624 | bb_error_msg("history[%d]:'%s'", i, state->history[i]); |
diff --git a/libbb/vfork_daemon_rexec.c b/libbb/vfork_daemon_rexec.c index 885c19f1a..151739ae2 100644 --- a/libbb/vfork_daemon_rexec.c +++ b/libbb/vfork_daemon_rexec.c | |||
@@ -28,6 +28,22 @@ | |||
28 | # ifndef PR_GET_NAME | 28 | # ifndef PR_GET_NAME |
29 | # define PR_GET_NAME 16 | 29 | # define PR_GET_NAME 16 |
30 | # endif | 30 | # endif |
31 | # if ENABLE_FEATURE_SH_STANDALONE || ENABLE_FEATURE_PREFER_APPLETS || !BB_MMU | ||
32 | int FAST_FUNC re_execed_comm(void) | ||
33 | { | ||
34 | const char *e, *expected_comm; | ||
35 | char comm[16]; | ||
36 | |||
37 | BUILD_BUG_ON(CONFIG_BUSYBOX_EXEC_PATH[0] != '/'); | ||
38 | e = CONFIG_BUSYBOX_EXEC_PATH; | ||
39 | /* Hopefully (strrchr(e) - e) evaluates to constant at compile time: */ | ||
40 | expected_comm = bb_busybox_exec_path + (strrchr(e, '/') - e) + 1; | ||
41 | |||
42 | prctl(PR_GET_NAME, (long)comm, 0, 0, 0); | ||
43 | //bb_error_msg("comm:'%.*s' expected:'%s'", 16, comm, expected_comm); | ||
44 | return strcmp(comm, expected_comm) == 0; | ||
45 | } | ||
46 | # endif | ||
31 | void FAST_FUNC set_task_comm(const char *comm) | 47 | void FAST_FUNC set_task_comm(const char *comm) |
32 | { | 48 | { |
33 | /* okay if too long (truncates) */ | 49 | /* okay if too long (truncates) */ |
diff --git a/libbb/xreadlink.c b/libbb/xreadlink.c index 31680810b..024ee9047 100644 --- a/libbb/xreadlink.c +++ b/libbb/xreadlink.c | |||
@@ -130,7 +130,7 @@ char* FAST_FUNC xmalloc_realpath(const char *path) | |||
130 | #endif | 130 | #endif |
131 | } | 131 | } |
132 | 132 | ||
133 | char* FAST_FUNC xmalloc_realpath_coreutils(const char *path) | 133 | char* FAST_FUNC xmalloc_realpath_coreutils(char *path) |
134 | { | 134 | { |
135 | char *buf; | 135 | char *buf; |
136 | 136 | ||
@@ -144,32 +144,19 @@ char* FAST_FUNC xmalloc_realpath_coreutils(const char *path) | |||
144 | * (the directory must exist). | 144 | * (the directory must exist). |
145 | */ | 145 | */ |
146 | if (!buf && errno == ENOENT) { | 146 | if (!buf && errno == ENOENT) { |
147 | char *last_slash = strrchr(path, '/'); | 147 | char *target, c, *last_slash; |
148 | if (last_slash) { | 148 | size_t i; |
149 | *last_slash++ = '\0'; | 149 | |
150 | buf = xmalloc_realpath(path); | 150 | target = xmalloc_readlink(path); |
151 | if (buf) { | 151 | if (target) { |
152 | unsigned len = strlen(buf); | 152 | /* |
153 | buf = xrealloc(buf, len + strlen(last_slash) + 2); | 153 | * $ ln -s /bin/qwe symlink # note: /bin is a link to /usr/bin |
154 | buf[len++] = '/'; | 154 | * $ readlink -f symlink |
155 | strcpy(buf + len, last_slash); | 155 | * /usr/bin/qwe |
156 | } | 156 | * $ realpath symlink |
157 | } else { | 157 | * /usr/bin/qwe |
158 | char *target = xmalloc_readlink(path); | 158 | */ |
159 | if (target) { | 159 | if (target[0] != '/') { |
160 | char *cwd; | ||
161 | if (target[0] == '/') { | ||
162 | /* | ||
163 | * $ ln -s /bin/qwe symlink # note: /bin is a link to /usr/bin | ||
164 | * $ readlink -f symlink | ||
165 | * /usr/bin/qwe/target_does_not_exist | ||
166 | * $ realpath symlink | ||
167 | * /usr/bin/qwe/target_does_not_exist | ||
168 | */ | ||
169 | buf = xmalloc_realpath_coreutils(target); | ||
170 | free(target); | ||
171 | return buf; | ||
172 | } | ||
173 | /* | 160 | /* |
174 | * $ ln -s target_does_not_exist symlink | 161 | * $ ln -s target_does_not_exist symlink |
175 | * $ readlink -f symlink | 162 | * $ readlink -f symlink |
@@ -177,13 +164,41 @@ char* FAST_FUNC xmalloc_realpath_coreutils(const char *path) | |||
177 | * $ realpath symlink | 164 | * $ realpath symlink |
178 | * /CURDIR/target_does_not_exist | 165 | * /CURDIR/target_does_not_exist |
179 | */ | 166 | */ |
180 | cwd = xrealloc_getcwd_or_warn(NULL); | 167 | char *cwd = xrealloc_getcwd_or_warn(NULL); |
181 | buf = concat_path_file(cwd, target); | 168 | char *tmp = concat_path_file(cwd, target); |
182 | free(cwd); | 169 | free(cwd); |
183 | free(target); | 170 | free(target); |
184 | return buf; | 171 | target = tmp; |
172 | } | ||
173 | buf = xmalloc_realpath_coreutils(target); | ||
174 | free(target); | ||
175 | return buf; | ||
176 | } | ||
177 | |||
178 | /* ignore leading and trailing slashes */ | ||
179 | while (path[0] == '/' && path[1] == '/') | ||
180 | ++path; | ||
181 | i = strlen(path) - 1; | ||
182 | while (i > 0 && path[i] == '/') | ||
183 | i--; | ||
184 | c = path[i + 1]; | ||
185 | path[i + 1] = '\0'; | ||
186 | |||
187 | last_slash = strrchr(path, '/'); | ||
188 | if (last_slash == path) | ||
189 | buf = xstrdup(path); | ||
190 | else if (last_slash) { | ||
191 | *last_slash = '\0'; | ||
192 | buf = xmalloc_realpath(path); | ||
193 | *last_slash++ = '/'; | ||
194 | if (buf) { | ||
195 | unsigned len = strlen(buf); | ||
196 | buf = xrealloc(buf, len + strlen(last_slash) + 2); | ||
197 | buf[len++] = '/'; | ||
198 | strcpy(buf + len, last_slash); | ||
185 | } | 199 | } |
186 | } | 200 | } |
201 | path[i + 1] = c; | ||
187 | } | 202 | } |
188 | 203 | ||
189 | return buf; | 204 | return buf; |