diff options
author | Denys Vlasenko <vda.linux@googlemail.com> | 2009-05-20 12:20:48 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2009-05-20 12:20:48 +0200 |
commit | e18255d1dadc9686daa328fa121423b47d2f6af4 (patch) | |
tree | abea08a2f62c5fa9322086d5b0151b602636da2b | |
parent | e424423a7b164e0c343c180a944844fd27ccbe97 (diff) | |
parent | 38478a600f52eb8f00d260a2f99d8430b9aba1e8 (diff) | |
download | busybox-w32-e18255d1dadc9686daa328fa121423b47d2f6af4.tar.gz busybox-w32-e18255d1dadc9686daa328fa121423b47d2f6af4.tar.bz2 busybox-w32-e18255d1dadc9686daa328fa121423b47d2f6af4.zip |
Merge branch 'master' of git+ssh://vda@busybox.net/var/lib/git/busybox
-rw-r--r-- | include/applets.h | 1 | ||||
-rw-r--r-- | include/platform.h | 166 | ||||
-rw-r--r-- | include/usage.h | 10 | ||||
-rw-r--r-- | libbb/login.c | 2 | ||||
-rw-r--r-- | shell/hush.c | 35 | ||||
-rw-r--r-- | util-linux/Config.in | 7 | ||||
-rw-r--r-- | util-linux/Kbuild | 1 | ||||
-rw-r--r-- | util-linux/script.c | 59 | ||||
-rw-r--r-- | util-linux/scriptreplay.c | 38 |
9 files changed, 203 insertions, 116 deletions
diff --git a/include/applets.h b/include/applets.h index 359440def..7838757f5 100644 --- a/include/applets.h +++ b/include/applets.h | |||
@@ -326,6 +326,7 @@ IF_RUNSV(APPLET(runsv, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | |||
326 | IF_RUNSVDIR(APPLET(runsvdir, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 326 | IF_RUNSVDIR(APPLET(runsvdir, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) |
327 | IF_RX(APPLET(rx, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 327 | IF_RX(APPLET(rx, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) |
328 | IF_SCRIPT(APPLET(script, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) | 328 | IF_SCRIPT(APPLET(script, _BB_DIR_USR_BIN, _BB_SUID_NEVER)) |
329 | IF_SCRIPTREPLAY(APPLET(scriptreplay, _BB_DIR_BIN, _BB_SUID_NEVER)) | ||
329 | IF_SED(APPLET(sed, _BB_DIR_BIN, _BB_SUID_NEVER)) | 330 | IF_SED(APPLET(sed, _BB_DIR_BIN, _BB_SUID_NEVER)) |
330 | IF_SELINUXENABLED(APPLET(selinuxenabled, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) | 331 | IF_SELINUXENABLED(APPLET(selinuxenabled, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) |
331 | IF_SENDMAIL(APPLET(sendmail, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) | 332 | IF_SENDMAIL(APPLET(sendmail, _BB_DIR_USR_SBIN, _BB_SUID_NEVER)) |
diff --git a/include/platform.h b/include/platform.h index 317349fed..e2136a2ea 100644 --- a/include/platform.h +++ b/include/platform.h | |||
@@ -19,7 +19,7 @@ | |||
19 | /* __restrict is known in EGCS 1.2 and above. */ | 19 | /* __restrict is known in EGCS 1.2 and above. */ |
20 | #if !__GNUC_PREREQ(2,92) | 20 | #if !__GNUC_PREREQ(2,92) |
21 | # ifndef __restrict | 21 | # ifndef __restrict |
22 | # define __restrict /* Ignore */ | 22 | # define __restrict |
23 | # endif | 23 | # endif |
24 | #endif | 24 | #endif |
25 | 25 | ||
@@ -61,14 +61,14 @@ | |||
61 | # define DEPRECATED __attribute__ ((__deprecated__)) | 61 | # define DEPRECATED __attribute__ ((__deprecated__)) |
62 | # define UNUSED_PARAM_RESULT __attribute__ ((warn_unused_result)) | 62 | # define UNUSED_PARAM_RESULT __attribute__ ((warn_unused_result)) |
63 | # else | 63 | # else |
64 | # define DEPRECATED /* n/a */ | 64 | # define DEPRECATED |
65 | # define UNUSED_PARAM_RESULT /* n/a */ | 65 | # define UNUSED_PARAM_RESULT |
66 | # endif | 66 | # endif |
67 | #else | 67 | #else |
68 | # define ALWAYS_INLINE inline /* n/a */ | 68 | # define ALWAYS_INLINE inline |
69 | # define NOINLINE /* n/a */ | 69 | # define NOINLINE |
70 | # define DEPRECATED /* n/a */ | 70 | # define DEPRECATED |
71 | # define UNUSED_PARAM_RESULT /* n/a */ | 71 | # define UNUSED_PARAM_RESULT |
72 | #endif | 72 | #endif |
73 | 73 | ||
74 | /* -fwhole-program makes all symbols local. The attribute externally_visible | 74 | /* -fwhole-program makes all symbols local. The attribute externally_visible |
@@ -144,19 +144,19 @@ | |||
144 | 144 | ||
145 | /* SWAP_LEnn means "convert CPU<->little_endian by swapping bytes" */ | 145 | /* SWAP_LEnn means "convert CPU<->little_endian by swapping bytes" */ |
146 | #if BB_BIG_ENDIAN | 146 | #if BB_BIG_ENDIAN |
147 | #define SWAP_BE16(x) (x) | 147 | # define SWAP_BE16(x) (x) |
148 | #define SWAP_BE32(x) (x) | 148 | # define SWAP_BE32(x) (x) |
149 | #define SWAP_BE64(x) (x) | 149 | # define SWAP_BE64(x) (x) |
150 | #define SWAP_LE16(x) bswap_16(x) | 150 | # define SWAP_LE16(x) bswap_16(x) |
151 | #define SWAP_LE32(x) bswap_32(x) | 151 | # define SWAP_LE32(x) bswap_32(x) |
152 | #define SWAP_LE64(x) bswap_64(x) | 152 | # define SWAP_LE64(x) bswap_64(x) |
153 | #else | 153 | #else |
154 | #define SWAP_BE16(x) bswap_16(x) | 154 | # define SWAP_BE16(x) bswap_16(x) |
155 | #define SWAP_BE32(x) bswap_32(x) | 155 | # define SWAP_BE32(x) bswap_32(x) |
156 | #define SWAP_BE64(x) bswap_64(x) | 156 | # define SWAP_BE64(x) bswap_64(x) |
157 | #define SWAP_LE16(x) (x) | 157 | # define SWAP_LE16(x) (x) |
158 | #define SWAP_LE32(x) (x) | 158 | # define SWAP_LE32(x) (x) |
159 | #define SWAP_LE64(x) (x) | 159 | # define SWAP_LE64(x) (x) |
160 | #endif | 160 | #endif |
161 | 161 | ||
162 | /* ---- Unaligned access ------------------------------------ */ | 162 | /* ---- Unaligned access ------------------------------------ */ |
@@ -165,15 +165,15 @@ | |||
165 | * a lvalue. This makes it more likely to not swap them by mistake | 165 | * a lvalue. This makes it more likely to not swap them by mistake |
166 | */ | 166 | */ |
167 | #if defined(i386) || defined(__x86_64__) | 167 | #if defined(i386) || defined(__x86_64__) |
168 | #define move_from_unaligned16(v, u16p) ((v) = *(uint16_t*)(u16p)) | 168 | # define move_from_unaligned16(v, u16p) ((v) = *(uint16_t*)(u16p)) |
169 | #define move_from_unaligned32(v, u32p) ((v) = *(uint32_t*)(u32p)) | 169 | # define move_from_unaligned32(v, u32p) ((v) = *(uint32_t*)(u32p)) |
170 | #define move_to_unaligned32(u32p, v) (*(uint32_t*)(u32p) = (v)) | 170 | # define move_to_unaligned32(u32p, v) (*(uint32_t*)(u32p) = (v)) |
171 | /* #elif ... - add your favorite arch today! */ | 171 | /* #elif ... - add your favorite arch today! */ |
172 | #else | 172 | #else |
173 | /* performs reasonably well (gcc usually inlines memcpy here) */ | 173 | /* performs reasonably well (gcc usually inlines memcpy here) */ |
174 | #define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2)) | 174 | # define move_from_unaligned16(v, u16p) (memcpy(&(v), (u16p), 2)) |
175 | #define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4)) | 175 | # define move_from_unaligned32(v, u32p) (memcpy(&(v), (u32p), 4)) |
176 | #define move_to_unaligned32(u32p, v) do { \ | 176 | # define move_to_unaligned32(u32p, v) do { \ |
177 | uint32_t __t = (v); \ | 177 | uint32_t __t = (v); \ |
178 | memcpy((u32p), &__t, 4); \ | 178 | memcpy((u32p), &__t, 4); \ |
179 | } while (0) | 179 | } while (0) |
@@ -225,21 +225,21 @@ __extension__ typedef unsigned long long __u64; | |||
225 | 225 | ||
226 | #if defined __GLIBC__ || defined __UCLIBC__ \ | 226 | #if defined __GLIBC__ || defined __UCLIBC__ \ |
227 | || defined __dietlibc__ || defined _NEWLIB_VERSION | 227 | || defined __dietlibc__ || defined _NEWLIB_VERSION |
228 | #include <features.h> | 228 | # include <features.h> |
229 | #define HAVE_FEATURES_H | 229 | # define HAVE_FEATURES_H |
230 | #include <stdint.h> | 230 | # include <stdint.h> |
231 | #define HAVE_STDINT_H | 231 | # define HAVE_STDINT_H |
232 | #elif !defined __APPLE__ | 232 | #elif !defined __APPLE__ |
233 | /* Largest integral types. */ | 233 | /* Largest integral types. */ |
234 | #if __BIG_ENDIAN__ | 234 | # if __BIG_ENDIAN__ |
235 | typedef long intmax_t; | 235 | typedef long intmax_t; |
236 | typedef unsigned long uintmax_t; | 236 | typedef unsigned long uintmax_t; |
237 | #else | 237 | # else |
238 | __extension__ | 238 | __extension__ |
239 | typedef long long intmax_t; | 239 | typedef long long intmax_t; |
240 | __extension__ | 240 | __extension__ |
241 | typedef unsigned long long uintmax_t; | 241 | typedef unsigned long long uintmax_t; |
242 | #endif | 242 | # endif |
243 | #endif | 243 | #endif |
244 | 244 | ||
245 | /* Size-saving "small" ints (arch-dependent) */ | 245 | /* Size-saving "small" ints (arch-dependent) */ |
@@ -256,20 +256,20 @@ typedef unsigned smalluint; | |||
256 | /* ISO C Standard: 7.16 Boolean type and values <stdbool.h> */ | 256 | /* ISO C Standard: 7.16 Boolean type and values <stdbool.h> */ |
257 | #if (defined __digital__ && defined __unix__) | 257 | #if (defined __digital__ && defined __unix__) |
258 | /* old system without (proper) C99 support */ | 258 | /* old system without (proper) C99 support */ |
259 | #define bool smalluint | 259 | # define bool smalluint |
260 | #else | 260 | #else |
261 | /* modern system, so use it */ | 261 | /* modern system, so use it */ |
262 | #include <stdbool.h> | 262 | # include <stdbool.h> |
263 | #endif | 263 | #endif |
264 | 264 | ||
265 | /* Try to defeat gcc's alignment of "char message[]"-like data */ | 265 | /* Try to defeat gcc's alignment of "char message[]"-like data */ |
266 | #if 1 /* if needed: !defined(arch1) && !defined(arch2) */ | 266 | #if 1 /* if needed: !defined(arch1) && !defined(arch2) */ |
267 | #define ALIGN1 __attribute__((aligned(1))) | 267 | # define ALIGN1 __attribute__((aligned(1))) |
268 | #define ALIGN2 __attribute__((aligned(2))) | 268 | # define ALIGN2 __attribute__((aligned(2))) |
269 | #else | 269 | #else |
270 | /* Arches which MUST have 2 or 4 byte alignment for everything are here */ | 270 | /* Arches which MUST have 2 or 4 byte alignment for everything are here */ |
271 | #define ALIGN1 | 271 | # define ALIGN1 |
272 | #define ALIGN2 | 272 | # define ALIGN2 |
273 | #endif | 273 | #endif |
274 | 274 | ||
275 | 275 | ||
@@ -281,13 +281,13 @@ typedef unsigned smalluint; | |||
281 | #if ENABLE_NOMMU || \ | 281 | #if ENABLE_NOMMU || \ |
282 | (defined __UCLIBC__ && __UCLIBC_MAJOR__ >= 0 && __UCLIBC_MINOR__ >= 9 && \ | 282 | (defined __UCLIBC__ && __UCLIBC_MAJOR__ >= 0 && __UCLIBC_MINOR__ >= 9 && \ |
283 | __UCLIBC_SUBLEVEL__ > 28 && !defined __ARCH_USE_MMU__) | 283 | __UCLIBC_SUBLEVEL__ > 28 && !defined __ARCH_USE_MMU__) |
284 | #define BB_MMU 0 | 284 | # define BB_MMU 0 |
285 | #define USE_FOR_NOMMU(...) __VA_ARGS__ | 285 | # define USE_FOR_NOMMU(...) __VA_ARGS__ |
286 | #define USE_FOR_MMU(...) | 286 | # define USE_FOR_MMU(...) |
287 | #else | 287 | #else |
288 | #define BB_MMU 1 | 288 | # define BB_MMU 1 |
289 | #define USE_FOR_NOMMU(...) | 289 | # define USE_FOR_NOMMU(...) |
290 | #define USE_FOR_MMU(...) __VA_ARGS__ | 290 | # define USE_FOR_MMU(...) __VA_ARGS__ |
291 | #endif | 291 | #endif |
292 | 292 | ||
293 | /* Platforms that haven't got dprintf need to implement fdprintf() in | 293 | /* Platforms that haven't got dprintf need to implement fdprintf() in |
@@ -297,7 +297,7 @@ typedef unsigned smalluint; | |||
297 | /* Needed for: glibc */ | 297 | /* Needed for: glibc */ |
298 | /* Not needed for: dietlibc */ | 298 | /* Not needed for: dietlibc */ |
299 | /* Others: ?? (add as needed) */ | 299 | /* Others: ?? (add as needed) */ |
300 | #define fdprintf dprintf | 300 | # define fdprintf dprintf |
301 | #endif | 301 | #endif |
302 | 302 | ||
303 | #if defined(__dietlibc__) | 303 | #if defined(__dietlibc__) |
@@ -323,7 +323,6 @@ static ALWAYS_INLINE char* strchrnul(const char *s, char c) | |||
323 | # define PRIu32 "u" | 323 | # define PRIu32 "u" |
324 | /* use legacy setpgrp(pid_t,pid_t) for now. move to platform.c */ | 324 | /* use legacy setpgrp(pid_t,pid_t) for now. move to platform.c */ |
325 | # define bb_setpgrp() do { pid_t __me = getpid(); setpgrp(__me,__me); } while (0) | 325 | # define bb_setpgrp() do { pid_t __me = getpid(); setpgrp(__me,__me); } while (0) |
326 | |||
327 | # if !defined ADJ_OFFSET_SINGLESHOT && defined MOD_CLKA && defined MOD_OFFSET | 326 | # if !defined ADJ_OFFSET_SINGLESHOT && defined MOD_CLKA && defined MOD_OFFSET |
328 | # define ADJ_OFFSET_SINGLESHOT (MOD_CLKA | MOD_OFFSET) | 327 | # define ADJ_OFFSET_SINGLESHOT (MOD_CLKA | MOD_OFFSET) |
329 | # endif | 328 | # endif |
@@ -344,44 +343,53 @@ static ALWAYS_INLINE char* strchrnul(const char *s, char c) | |||
344 | #endif | 343 | #endif |
345 | 344 | ||
346 | #if defined(__linux__) | 345 | #if defined(__linux__) |
347 | #include <sys/mount.h> | 346 | # include <sys/mount.h> |
348 | /* Make sure we have all the new mount flags we actually try to use. */ | 347 | /* Make sure we have all the new mount flags we actually try to use. */ |
349 | #ifndef MS_BIND | 348 | # ifndef MS_BIND |
350 | #define MS_BIND (1<<12) | 349 | # define MS_BIND (1 << 12) |
351 | #endif | 350 | # endif |
352 | #ifndef MS_MOVE | 351 | # ifndef MS_MOVE |
353 | #define MS_MOVE (1<<13) | 352 | # define MS_MOVE (1 << 13) |
354 | #endif | 353 | # endif |
355 | #ifndef MS_RECURSIVE | 354 | # ifndef MS_RECURSIVE |
356 | #define MS_RECURSIVE (1<<14) | 355 | # define MS_RECURSIVE (1 << 14) |
357 | #endif | 356 | # endif |
358 | #ifndef MS_SILENT | 357 | # ifndef MS_SILENT |
359 | #define MS_SILENT (1<<15) | 358 | # define MS_SILENT (1 << 15) |
360 | #endif | 359 | # endif |
361 | |||
362 | /* The shared subtree stuff, which went in around 2.6.15. */ | 360 | /* The shared subtree stuff, which went in around 2.6.15. */ |
363 | #ifndef MS_UNBINDABLE | 361 | # ifndef MS_UNBINDABLE |
364 | #define MS_UNBINDABLE (1<<17) | 362 | # define MS_UNBINDABLE (1 << 17) |
365 | #endif | 363 | # endif |
366 | #ifndef MS_PRIVATE | 364 | # ifndef MS_PRIVATE |
367 | #define MS_PRIVATE (1<<18) | 365 | # define MS_PRIVATE (1 << 18) |
368 | #endif | 366 | # endif |
369 | #ifndef MS_SLAVE | 367 | # ifndef MS_SLAVE |
370 | #define MS_SLAVE (1<<19) | 368 | # define MS_SLAVE (1 << 19) |
371 | #endif | 369 | # endif |
372 | #ifndef MS_SHARED | 370 | # ifndef MS_SHARED |
373 | #define MS_SHARED (1<<20) | 371 | # define MS_SHARED (1 << 20) |
374 | #endif | 372 | # endif |
375 | #ifndef MS_RELATIME | 373 | # ifndef MS_RELATIME |
376 | #define MS_RELATIME (1 << 21) | 374 | # define MS_RELATIME (1 << 21) |
377 | #endif | 375 | # endif |
378 | 376 | ||
379 | #if !defined(BLKSSZGET) | 377 | # if !defined(BLKSSZGET) |
380 | #define BLKSSZGET _IO(0x12, 104) | 378 | # define BLKSSZGET _IO(0x12, 104) |
379 | # endif | ||
380 | # if !defined(BLKGETSIZE64) | ||
381 | # define BLKGETSIZE64 _IOR(0x12,114,size_t) | ||
382 | # endif | ||
381 | #endif | 383 | #endif |
382 | #if !defined(BLKGETSIZE64) | 384 | |
383 | #define BLKGETSIZE64 _IOR(0x12,114,size_t) | 385 | /* The field domainname of struct utsname is Linux specific. */ |
386 | #if !defined(__linux__) | ||
387 | # define HAVE_NO_UTSNAME_DOMAINNAME | ||
384 | #endif | 388 | #endif |
389 | |||
390 | /* If this system doesn't have IUCLC bit in struct termios::c_iflag... */ | ||
391 | #ifndef IUCLC | ||
392 | # define IUCLC 0 | ||
385 | #endif | 393 | #endif |
386 | 394 | ||
387 | #endif | 395 | #endif |
diff --git a/include/usage.h b/include/usage.h index 123462a02..1e327fb97 100644 --- a/include/usage.h +++ b/include/usage.h | |||
@@ -3512,6 +3512,11 @@ | |||
3512 | "\n -g Process group id(s)" \ | 3512 | "\n -g Process group id(s)" \ |
3513 | "\n -u Process user name(s) and/or id(s)" \ | 3513 | "\n -u Process user name(s) and/or id(s)" \ |
3514 | 3514 | ||
3515 | #define scriptreplay_trivial_usage \ | ||
3516 | "timingfile [typescript [divisor]]" | ||
3517 | #define scriptreplay_full_usage "\n\n" \ | ||
3518 | "Play back typescripts, using timing information" | ||
3519 | |||
3515 | #define reset_trivial_usage \ | 3520 | #define reset_trivial_usage \ |
3516 | "" | 3521 | "" |
3517 | #define reset_full_usage "\n\n" \ | 3522 | #define reset_full_usage "\n\n" \ |
@@ -3706,13 +3711,16 @@ | |||
3706 | "$ rx /tmp/foo\n" | 3711 | "$ rx /tmp/foo\n" |
3707 | 3712 | ||
3708 | #define script_trivial_usage \ | 3713 | #define script_trivial_usage \ |
3709 | "[-afq] [-c COMMAND] [OUTFILE]" | 3714 | "[-afq" IF_SCRIPTREPLAY("t") "] [-c COMMAND] [OUTFILE]" |
3710 | #define script_full_usage "\n\n" \ | 3715 | #define script_full_usage "\n\n" \ |
3711 | "Options:" \ | 3716 | "Options:" \ |
3712 | "\n -a Append output" \ | 3717 | "\n -a Append output" \ |
3713 | "\n -c Run COMMAND, not shell" \ | 3718 | "\n -c Run COMMAND, not shell" \ |
3714 | "\n -f Flush output after each write" \ | 3719 | "\n -f Flush output after each write" \ |
3715 | "\n -q Quiet" \ | 3720 | "\n -q Quiet" \ |
3721 | IF_SCRIPTREPLAY( \ | ||
3722 | "\n -t Send timing to stderr" \ | ||
3723 | ) | ||
3716 | 3724 | ||
3717 | #define sed_trivial_usage \ | 3725 | #define sed_trivial_usage \ |
3718 | "[-efinr] pattern [files...]" | 3726 | "[-efinr] pattern [files...]" |
diff --git a/libbb/login.c b/libbb/login.c index b3e199ce4..98e641cce 100644 --- a/libbb/login.c +++ b/libbb/login.c | |||
@@ -62,10 +62,12 @@ void FAST_FUNC print_login_issue(const char *issue_file, const char *tty) | |||
62 | case 'm': | 62 | case 'm': |
63 | outbuf = uts.machine; | 63 | outbuf = uts.machine; |
64 | break; | 64 | break; |
65 | #ifndef HAVE_NO_UTSNAME_DOMAINNAME | ||
65 | case 'D': | 66 | case 'D': |
66 | case 'o': | 67 | case 'o': |
67 | outbuf = uts.domainname; | 68 | outbuf = uts.domainname; |
68 | break; | 69 | break; |
70 | #endif | ||
69 | case 'd': | 71 | case 'd': |
70 | strftime(buf, sizeof(buf), fmtstr_d, localtime(&t)); | 72 | strftime(buf, sizeof(buf), fmtstr_d, localtime(&t)); |
71 | break; | 73 | break; |
diff --git a/shell/hush.c b/shell/hush.c index 370e0d71a..d6286b61c 100644 --- a/shell/hush.c +++ b/shell/hush.c | |||
@@ -445,6 +445,9 @@ struct globals { | |||
445 | int last_jobid; | 445 | int last_jobid; |
446 | pid_t saved_tty_pgrp; | 446 | pid_t saved_tty_pgrp; |
447 | struct pipe *job_list; | 447 | struct pipe *job_list; |
448 | # define G_saved_tty_pgrp (G.saved_tty_pgrp) | ||
449 | #else | ||
450 | # define G_saved_tty_pgrp 0 | ||
448 | #endif | 451 | #endif |
449 | smallint flag_SIGINT; | 452 | smallint flag_SIGINT; |
450 | #if ENABLE_HUSH_LOOPS | 453 | #if ENABLE_HUSH_LOOPS |
@@ -1055,8 +1058,8 @@ enum { | |||
1055 | | (1 << SIGINT) | 1058 | | (1 << SIGINT) |
1056 | | (1 << SIGHUP) | 1059 | | (1 << SIGHUP) |
1057 | , | 1060 | , |
1058 | #if ENABLE_HUSH_JOB | ||
1059 | SPECIAL_JOB_SIGS = 0 | 1061 | SPECIAL_JOB_SIGS = 0 |
1062 | #if ENABLE_HUSH_JOB | ||
1060 | | (1 << SIGTTIN) | 1063 | | (1 << SIGTTIN) |
1061 | | (1 << SIGTTOU) | 1064 | | (1 << SIGTTOU) |
1062 | | (1 << SIGTSTP) | 1065 | | (1 << SIGTSTP) |
@@ -1088,8 +1091,8 @@ static void sigexit(int sig) | |||
1088 | 1091 | ||
1089 | /* Careful: we can end up here after [v]fork. Do not restore | 1092 | /* Careful: we can end up here after [v]fork. Do not restore |
1090 | * tty pgrp then, only top-level shell process does that */ | 1093 | * tty pgrp then, only top-level shell process does that */ |
1091 | if (G.saved_tty_pgrp && getpid() == G.root_pid) | 1094 | if (G_saved_tty_pgrp && getpid() == G.root_pid) |
1092 | tcsetpgrp(G_interactive_fd, G.saved_tty_pgrp); | 1095 | tcsetpgrp(G_interactive_fd, G_saved_tty_pgrp); |
1093 | 1096 | ||
1094 | /* Not a signal, just exit */ | 1097 | /* Not a signal, just exit */ |
1095 | if (sig <= 0) | 1098 | if (sig <= 0) |
@@ -3400,7 +3403,7 @@ static int checkjobs_and_fg_shell(struct pipe* fg_pipe) | |||
3400 | { | 3403 | { |
3401 | pid_t p; | 3404 | pid_t p; |
3402 | int rcode = checkjobs(fg_pipe); | 3405 | int rcode = checkjobs(fg_pipe); |
3403 | if (G.saved_tty_pgrp) { | 3406 | if (G_saved_tty_pgrp) { |
3404 | /* Job finished, move the shell to the foreground */ | 3407 | /* Job finished, move the shell to the foreground */ |
3405 | p = getpgrp(); /* our process group id */ | 3408 | p = getpgrp(); /* our process group id */ |
3406 | debug_printf_jobs("fg'ing ourself: getpgrp()=%d\n", (int)p); | 3409 | debug_printf_jobs("fg'ing ourself: getpgrp()=%d\n", (int)p); |
@@ -3656,7 +3659,7 @@ static int run_pipe(struct pipe *pi) | |||
3656 | pgrp = getpid(); | 3659 | pgrp = getpid(); |
3657 | if (setpgid(0, pgrp) == 0 | 3660 | if (setpgid(0, pgrp) == 0 |
3658 | && pi->followup != PIPE_BG | 3661 | && pi->followup != PIPE_BG |
3659 | && G.saved_tty_pgrp /* we have ctty */ | 3662 | && G_saved_tty_pgrp /* we have ctty */ |
3660 | ) { | 3663 | ) { |
3661 | /* We do it in *every* child, not just first, | 3664 | /* We do it in *every* child, not just first, |
3662 | * to avoid races */ | 3665 | * to avoid races */ |
@@ -5954,7 +5957,7 @@ static void block_signals(int second_time) | |||
5954 | mask = (1 << SIGQUIT); | 5957 | mask = (1 << SIGQUIT); |
5955 | if (G_interactive_fd) { | 5958 | if (G_interactive_fd) { |
5956 | mask = (1 << SIGQUIT) | SPECIAL_INTERACTIVE_SIGS; | 5959 | mask = (1 << SIGQUIT) | SPECIAL_INTERACTIVE_SIGS; |
5957 | if (G.saved_tty_pgrp) /* we have ctty, job control sigs work */ | 5960 | if (G_saved_tty_pgrp) /* we have ctty, job control sigs work */ |
5958 | mask |= SPECIAL_JOB_SIGS; | 5961 | mask |= SPECIAL_JOB_SIGS; |
5959 | } | 5962 | } |
5960 | G.non_DFL_mask = mask; | 5963 | G.non_DFL_mask = mask; |
@@ -6235,10 +6238,10 @@ int hush_main(int argc, char **argv) | |||
6235 | */ | 6238 | */ |
6236 | #if ENABLE_HUSH_JOB | 6239 | #if ENABLE_HUSH_JOB |
6237 | if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) { | 6240 | if (isatty(STDIN_FILENO) && isatty(STDOUT_FILENO)) { |
6238 | G.saved_tty_pgrp = tcgetpgrp(STDIN_FILENO); | 6241 | G_saved_tty_pgrp = tcgetpgrp(STDIN_FILENO); |
6239 | debug_printf("saved_tty_pgrp:%d\n", G.saved_tty_pgrp); | 6242 | debug_printf("saved_tty_pgrp:%d\n", G_saved_tty_pgrp); |
6240 | if (G.saved_tty_pgrp < 0) | 6243 | if (G_saved_tty_pgrp < 0) |
6241 | G.saved_tty_pgrp = 0; | 6244 | G_saved_tty_pgrp = 0; |
6242 | 6245 | ||
6243 | /* try to dup stdin to high fd#, >= 255 */ | 6246 | /* try to dup stdin to high fd#, >= 255 */ |
6244 | G_interactive_fd = fcntl(STDIN_FILENO, F_DUPFD, 255); | 6247 | G_interactive_fd = fcntl(STDIN_FILENO, F_DUPFD, 255); |
@@ -6248,7 +6251,7 @@ int hush_main(int argc, char **argv) | |||
6248 | if (G_interactive_fd < 0) { | 6251 | if (G_interactive_fd < 0) { |
6249 | /* give up */ | 6252 | /* give up */ |
6250 | G_interactive_fd = 0; | 6253 | G_interactive_fd = 0; |
6251 | G.saved_tty_pgrp = 0; | 6254 | G_saved_tty_pgrp = 0; |
6252 | } | 6255 | } |
6253 | } | 6256 | } |
6254 | // TODO: track & disallow any attempts of user | 6257 | // TODO: track & disallow any attempts of user |
@@ -6258,7 +6261,7 @@ int hush_main(int argc, char **argv) | |||
6258 | if (G_interactive_fd) { | 6261 | if (G_interactive_fd) { |
6259 | close_on_exec_on(G_interactive_fd); | 6262 | close_on_exec_on(G_interactive_fd); |
6260 | 6263 | ||
6261 | if (G.saved_tty_pgrp) { | 6264 | if (G_saved_tty_pgrp) { |
6262 | /* If we were run as 'hush &', sleep until we are | 6265 | /* If we were run as 'hush &', sleep until we are |
6263 | * in the foreground (tty pgrp == our pgrp). | 6266 | * in the foreground (tty pgrp == our pgrp). |
6264 | * If we get started under a job aware app (like bash), | 6267 | * If we get started under a job aware app (like bash), |
@@ -6266,8 +6269,8 @@ int hush_main(int argc, char **argv) | |||
6266 | * who gets the foreground */ | 6269 | * who gets the foreground */ |
6267 | while (1) { | 6270 | while (1) { |
6268 | pid_t shell_pgrp = getpgrp(); | 6271 | pid_t shell_pgrp = getpgrp(); |
6269 | G.saved_tty_pgrp = tcgetpgrp(G_interactive_fd); | 6272 | G_saved_tty_pgrp = tcgetpgrp(G_interactive_fd); |
6270 | if (G.saved_tty_pgrp == shell_pgrp) | 6273 | if (G_saved_tty_pgrp == shell_pgrp) |
6271 | break; | 6274 | break; |
6272 | /* send TTIN to ourself (should stop us) */ | 6275 | /* send TTIN to ourself (should stop us) */ |
6273 | kill(- shell_pgrp, SIGTTIN); | 6276 | kill(- shell_pgrp, SIGTTIN); |
@@ -6277,7 +6280,7 @@ int hush_main(int argc, char **argv) | |||
6277 | /* Block some signals */ | 6280 | /* Block some signals */ |
6278 | block_signals(signal_mask_is_inited); | 6281 | block_signals(signal_mask_is_inited); |
6279 | 6282 | ||
6280 | if (G.saved_tty_pgrp) { | 6283 | if (G_saved_tty_pgrp) { |
6281 | /* Set other signals to restore saved_tty_pgrp */ | 6284 | /* Set other signals to restore saved_tty_pgrp */ |
6282 | set_fatal_handlers(); | 6285 | set_fatal_handlers(); |
6283 | /* Put ourselves in our own process group | 6286 | /* Put ourselves in our own process group |
@@ -6690,7 +6693,7 @@ static int builtin_fg_bg(char **argv) | |||
6690 | found: | 6693 | found: |
6691 | /* TODO: bash prints a string representation | 6694 | /* TODO: bash prints a string representation |
6692 | * of job being foregrounded (like "sleep 1 | cat") */ | 6695 | * of job being foregrounded (like "sleep 1 | cat") */ |
6693 | if (argv[0][0] == 'f' && G.saved_tty_pgrp) { | 6696 | if (argv[0][0] == 'f' && G_saved_tty_pgrp) { |
6694 | /* Put the job into the foreground. */ | 6697 | /* Put the job into the foreground. */ |
6695 | tcsetpgrp(G_interactive_fd, pi->pgrp); | 6698 | tcsetpgrp(G_interactive_fd, pi->pgrp); |
6696 | } | 6699 | } |
diff --git a/util-linux/Config.in b/util-linux/Config.in index e5c053fcf..024550172 100644 --- a/util-linux/Config.in +++ b/util-linux/Config.in | |||
@@ -764,6 +764,13 @@ config SCRIPT | |||
764 | help | 764 | help |
765 | The script makes typescript of terminal session. | 765 | The script makes typescript of terminal session. |
766 | 766 | ||
767 | config SCRIPTREPLAY | ||
768 | bool "scriptreplay" | ||
769 | default n | ||
770 | help | ||
771 | This program replays a typescript, using timing information | ||
772 | given by script -t. | ||
773 | |||
767 | config SETARCH | 774 | config SETARCH |
768 | bool "setarch" | 775 | bool "setarch" |
769 | default n | 776 | default n |
diff --git a/util-linux/Kbuild b/util-linux/Kbuild index ac071c620..eaad3319d 100644 --- a/util-linux/Kbuild +++ b/util-linux/Kbuild | |||
@@ -33,6 +33,7 @@ lib-$(CONFIG_RDEV) += rdev.o | |||
33 | lib-$(CONFIG_READPROFILE) += readprofile.o | 33 | lib-$(CONFIG_READPROFILE) += readprofile.o |
34 | lib-$(CONFIG_RTCWAKE) += rtcwake.o | 34 | lib-$(CONFIG_RTCWAKE) += rtcwake.o |
35 | lib-$(CONFIG_SCRIPT) += script.o | 35 | lib-$(CONFIG_SCRIPT) += script.o |
36 | lib-$(CONFIG_SCRIPTREPLAY) += scriptreplay.o | ||
36 | lib-$(CONFIG_SETARCH) += setarch.o | 37 | lib-$(CONFIG_SETARCH) += setarch.o |
37 | lib-$(CONFIG_SWAPONOFF) += swaponoff.o | 38 | lib-$(CONFIG_SWAPONOFF) += swaponoff.o |
38 | lib-$(CONFIG_SWITCH_ROOT) += switch_root.o | 39 | lib-$(CONFIG_SWITCH_ROOT) += switch_root.o |
diff --git a/util-linux/script.c b/util-linux/script.c index a9f24b10e..d16a2914a 100644 --- a/util-linux/script.c +++ b/util-linux/script.c | |||
@@ -10,16 +10,8 @@ | |||
10 | * | 10 | * |
11 | * Licensed under GPLv2 or later, see file License in this tarball for details. | 11 | * Licensed under GPLv2 or later, see file License in this tarball for details. |
12 | */ | 12 | */ |
13 | |||
14 | #include "libbb.h" | 13 | #include "libbb.h" |
15 | 14 | ||
16 | static smallint fd_count = 2; | ||
17 | |||
18 | static void handle_sigchld(int sig UNUSED_PARAM) | ||
19 | { | ||
20 | fd_count = 0; | ||
21 | } | ||
22 | |||
23 | int script_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 15 | int script_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
24 | int script_main(int argc UNUSED_PARAM, char **argv) | 16 | int script_main(int argc UNUSED_PARAM, char **argv) |
25 | { | 17 | { |
@@ -36,6 +28,15 @@ int script_main(int argc UNUSED_PARAM, char **argv) | |||
36 | const char *shell; | 28 | const char *shell; |
37 | char shell_opt[] = "-i"; | 29 | char shell_opt[] = "-i"; |
38 | char *shell_arg = NULL; | 30 | char *shell_arg = NULL; |
31 | enum { | ||
32 | OPT_a = (1 << 0), | ||
33 | OPT_c = (1 << 1), | ||
34 | OPT_f = (1 << 2), | ||
35 | OPT_q = (1 << 3), | ||
36 | #if ENABLE_SCRIPTREPLAY | ||
37 | OPT_t = (1 << 4), | ||
38 | #endif | ||
39 | }; | ||
39 | 40 | ||
40 | #if ENABLE_GETOPT_LONG | 41 | #if ENABLE_GETOPT_LONG |
41 | static const char getopt_longopts[] ALIGN1 = | 42 | static const char getopt_longopts[] ALIGN1 = |
@@ -43,25 +44,28 @@ int script_main(int argc UNUSED_PARAM, char **argv) | |||
43 | "command\0" Required_argument "c" | 44 | "command\0" Required_argument "c" |
44 | "flush\0" No_argument "f" | 45 | "flush\0" No_argument "f" |
45 | "quiet\0" No_argument "q" | 46 | "quiet\0" No_argument "q" |
47 | # if ENABLE_SCRIPTREPLAY | ||
48 | "timing\0" No_argument "t" | ||
49 | # endif | ||
46 | ; | 50 | ; |
47 | 51 | ||
48 | applet_long_options = getopt_longopts; | 52 | applet_long_options = getopt_longopts; |
49 | #endif | 53 | #endif |
50 | opt_complementary = "?1"; /* max one arg */ | 54 | opt_complementary = "?1"; /* max one arg */ |
51 | opt = getopt32(argv, "ac:fq", &shell_arg); | 55 | opt = getopt32(argv, "ac:fq" IF_SCRIPTREPLAY("t") , &shell_arg); |
52 | //argc -= optind; | 56 | //argc -= optind; |
53 | argv += optind; | 57 | argv += optind; |
54 | if (argv[0]) { | 58 | if (argv[0]) { |
55 | fname = argv[0]; | 59 | fname = argv[0]; |
56 | } | 60 | } |
57 | mode = O_CREAT|O_TRUNC|O_WRONLY; | 61 | mode = O_CREAT|O_TRUNC|O_WRONLY; |
58 | if (opt & 1) { | 62 | if (opt & OPT_a) { |
59 | mode = O_CREAT|O_APPEND|O_WRONLY; | 63 | mode = O_CREAT|O_APPEND|O_WRONLY; |
60 | } | 64 | } |
61 | if (opt & 2) { | 65 | if (opt & OPT_c) { |
62 | shell_opt[1] = 'c'; | 66 | shell_opt[1] = 'c'; |
63 | } | 67 | } |
64 | if (!(opt & 8)) { /* not -q */ | 68 | if (!(opt & OPT_q)) { |
65 | printf("Script started, file is %s\n", fname); | 69 | printf("Script started, file is %s\n", fname); |
66 | } | 70 | } |
67 | shell = getenv("SHELL"); | 71 | shell = getenv("SHELL"); |
@@ -83,7 +87,7 @@ int script_main(int argc UNUSED_PARAM, char **argv) | |||
83 | /* "script" from util-linux exits when child exits, | 87 | /* "script" from util-linux exits when child exits, |
84 | * we wouldn't wait for EOF from slave pty | 88 | * we wouldn't wait for EOF from slave pty |
85 | * (output may be produced by grandchildren of child) */ | 89 | * (output may be produced by grandchildren of child) */ |
86 | signal(SIGCHLD, handle_sigchld); | 90 | signal(SIGCHLD, record_signo); |
87 | 91 | ||
88 | /* TODO: SIGWINCH? pass window size changes down to slave? */ | 92 | /* TODO: SIGWINCH? pass window size changes down to slave? */ |
89 | 93 | ||
@@ -97,19 +101,23 @@ int script_main(int argc UNUSED_PARAM, char **argv) | |||
97 | #define buf bb_common_bufsiz1 | 101 | #define buf bb_common_bufsiz1 |
98 | struct pollfd pfd[2]; | 102 | struct pollfd pfd[2]; |
99 | int outfd, count, loop; | 103 | int outfd, count, loop; |
104 | #if ENABLE_SCRIPTREPLAY | ||
105 | double oldtime = time(NULL); | ||
106 | #endif | ||
107 | smallint fd_count = 2; | ||
100 | 108 | ||
101 | outfd = xopen(fname, mode); | 109 | outfd = xopen(fname, mode); |
102 | pfd[0].fd = pty; | 110 | pfd[0].fd = pty; |
103 | pfd[0].events = POLLIN; | 111 | pfd[0].events = POLLIN; |
104 | pfd[1].fd = 0; | 112 | pfd[1].fd = STDIN_FILENO; |
105 | pfd[1].events = POLLIN; | 113 | pfd[1].events = POLLIN; |
106 | ndelay_on(pty); /* this descriptor is not shared, can do this */ | 114 | ndelay_on(pty); /* this descriptor is not shared, can do this */ |
107 | /* ndelay_on(0); - NO, stdin can be shared! Pity :( */ | 115 | /* ndelay_on(STDIN_FILENO); - NO, stdin can be shared! Pity :( */ |
108 | 116 | ||
109 | /* copy stdin to pty master input, | 117 | /* copy stdin to pty master input, |
110 | * copy pty master output to stdout and file */ | 118 | * copy pty master output to stdout and file */ |
111 | /* TODO: don't use full_write's, use proper write buffering */ | 119 | /* TODO: don't use full_write's, use proper write buffering */ |
112 | while (fd_count) { | 120 | while (fd_count && !bb_got_signal) { |
113 | /* not safe_poll! we want SIGCHLD to EINTR poll */ | 121 | /* not safe_poll! we want SIGCHLD to EINTR poll */ |
114 | if (poll(pfd, fd_count, -1) < 0 && errno != EINTR) { | 122 | if (poll(pfd, fd_count, -1) < 0 && errno != EINTR) { |
115 | /* If child exits too quickly, we may get EIO: | 123 | /* If child exits too quickly, we may get EIO: |
@@ -124,9 +132,20 @@ int script_main(int argc UNUSED_PARAM, char **argv) | |||
124 | goto restore; | 132 | goto restore; |
125 | } | 133 | } |
126 | if (count > 0) { | 134 | if (count > 0) { |
135 | #if ENABLE_SCRIPTREPLAY | ||
136 | if (opt & OPT_t) { | ||
137 | struct timeval tv; | ||
138 | double newtime; | ||
139 | |||
140 | gettimeofday(&tv, NULL); | ||
141 | newtime = tv.tv_sec + (double) tv.tv_usec / 1000000; | ||
142 | fprintf(stderr, "%f %u\n", newtime - oldtime, count); | ||
143 | oldtime = newtime; | ||
144 | } | ||
145 | #endif | ||
127 | full_write(STDOUT_FILENO, buf, count); | 146 | full_write(STDOUT_FILENO, buf, count); |
128 | full_write(outfd, buf, count); | 147 | full_write(outfd, buf, count); |
129 | if (opt & 4) { /* -f */ | 148 | if (opt & OPT_f) { |
130 | fsync(outfd); | 149 | fsync(outfd); |
131 | } | 150 | } |
132 | } | 151 | } |
@@ -142,8 +161,8 @@ int script_main(int argc UNUSED_PARAM, char **argv) | |||
142 | } | 161 | } |
143 | } | 162 | } |
144 | } | 163 | } |
145 | /* If loop was exited because SIGCHLD handler set fd_count to 0, | 164 | /* If loop was exited because SIGCHLD handler set bb_got_signal, |
146 | * there still can be some buffered output. But not loop forever: | 165 | * there still can be some buffered output. But dont loop forever: |
147 | * we won't pump orphaned grandchildren's output indefinitely. | 166 | * we won't pump orphaned grandchildren's output indefinitely. |
148 | * Testcase: running this in script: | 167 | * Testcase: running this in script: |
149 | * exec dd if=/dev/zero bs=1M count=1 | 168 | * exec dd if=/dev/zero bs=1M count=1 |
@@ -158,7 +177,7 @@ int script_main(int argc UNUSED_PARAM, char **argv) | |||
158 | restore: | 177 | restore: |
159 | if (attr_ok == 0) | 178 | if (attr_ok == 0) |
160 | tcsetattr(0, TCSAFLUSH, &tt); | 179 | tcsetattr(0, TCSAFLUSH, &tt); |
161 | if (!(opt & 8)) /* not -q */ | 180 | if (!(opt & OPT_q)) |
162 | printf("Script done, file is %s\n", fname); | 181 | printf("Script done, file is %s\n", fname); |
163 | return EXIT_SUCCESS; | 182 | return EXIT_SUCCESS; |
164 | } | 183 | } |
diff --git a/util-linux/scriptreplay.c b/util-linux/scriptreplay.c new file mode 100644 index 000000000..038dbdfe1 --- /dev/null +++ b/util-linux/scriptreplay.c | |||
@@ -0,0 +1,38 @@ | |||
1 | /* vi: set sw=4 ts=4: */ | ||
2 | /* | ||
3 | * scriptreplay - play back typescripts, using timing information | ||
4 | * | ||
5 | * pascal.bellard@ads-lu.com | ||
6 | * | ||
7 | * Licensed under GPLv2 or later, see file License in this tarball for details. | ||
8 | * | ||
9 | */ | ||
10 | #include "libbb.h" | ||
11 | |||
12 | int scriptreplay_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | ||
13 | int scriptreplay_main(int argc UNUSED_PARAM, char **argv) | ||
14 | { | ||
15 | const char *script = "typescript"; | ||
16 | double delay, factor = 1000000.0; | ||
17 | int fd; | ||
18 | unsigned long count; | ||
19 | FILE *tfp; | ||
20 | |||
21 | if (argv[2]) { | ||
22 | script = argv[2]; | ||
23 | if (argv[3]) | ||
24 | factor /= atof(argv[3]); | ||
25 | } | ||
26 | |||
27 | tfp = xfopen_for_read(argv[1]); | ||
28 | fd = xopen(script, O_RDONLY); | ||
29 | while (fscanf(tfp, "%lf %lu\n", &delay, &count) == 2) { | ||
30 | usleep(delay * factor); | ||
31 | bb_copyfd_exact_size(fd, STDOUT_FILENO, count); | ||
32 | } | ||
33 | #if ENABLE_FEATURE_CLEAN_UP | ||
34 | close(fd); | ||
35 | fclose(tfp); | ||
36 | #endif | ||
37 | return EXIT_SUCCESS; | ||
38 | } | ||