aboutsummaryrefslogtreecommitdiff
path: root/coreutils/echo.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-04-09 13:04:50 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-04-09 13:04:50 +0000
commit7e754f12d304704d44e10fd4d2fdb8710526656e (patch)
tree9aa16703d48b9a7a38ccaec3759a19e95e976383 /coreutils/echo.c
parent2dfdd44d9d6c3984501683bbac2e78b18eeae1e7 (diff)
downloadbusybox-w32-7e754f12d304704d44e10fd4d2fdb8710526656e.tar.gz
busybox-w32-7e754f12d304704d44e10fd4d2fdb8710526656e.tar.bz2
busybox-w32-7e754f12d304704d44e10fd4d2fdb8710526656e.zip
Implement first instance of NOFORK applet - echo
find: use NOFORK/NOEXEC; small -exec buglet also eliminated vfork_daemon_rexec: honor PREFER_APPLETS echo: small size improvements find -exec echo {} \; with PREFER_APPLETS=y runs 4 times faster
Diffstat (limited to 'coreutils/echo.c')
-rw-r--r--coreutils/echo.c75
1 files changed, 38 insertions, 37 deletions
diff --git a/coreutils/echo.c b/coreutils/echo.c
index 8270fc006..486245508 100644
--- a/coreutils/echo.c
+++ b/coreutils/echo.c
@@ -20,86 +20,85 @@
20 * 1) In handling '\c' escape, the previous version only suppressed the 20 * 1) In handling '\c' escape, the previous version only suppressed the
21 * trailing newline. SUSv3 specifies _no_ output after '\c'. 21 * trailing newline. SUSv3 specifies _no_ output after '\c'.
22 * 2) SUSv3 specifies that octal escapes are of the form \0{#{#{#}}}. 22 * 2) SUSv3 specifies that octal escapes are of the form \0{#{#{#}}}.
23 * The previous version version did not allow 4-digit octals. 23 * The previous version did not allow 4-digit octals.
24 */ 24 */
25 25
26
27#include <stdio.h>
28#include <string.h>
29#include <stdlib.h>
30#include "busybox.h" 26#include "busybox.h"
31 27
32int bb_echo(char **argv) 28int bb_echo(char **argv)
33{ 29{
34#ifndef CONFIG_FEATURE_FANCY_ECHO 30 const char *arg;
31#if !ENABLE_FEATURE_FANCY_ECHO
35#define eflag '\\' 32#define eflag '\\'
36 ++argv; 33 ++argv;
37#else 34#else
38 const char *p; 35 const char *p;
39 int nflag = 1; 36 char nflag = 1;
40 int eflag = 0; 37 char eflag = 0;
38
39 while (1) {
40 arg = *++argv;
41 if (!arg)
42 goto ret;
43 if (*arg != '-')
44 break;
41 45
42 while (*++argv && (**argv == '-')) {
43 /* If it appears that we are handling options, then make sure 46 /* If it appears that we are handling options, then make sure
44 * that all of the options specified are actually valid. 47 * that all of the options specified are actually valid.
45 * Otherwise, the string should just be echoed. 48 * Otherwise, the string should just be echoed.
46 */ 49 */
47 50 p = arg + 1;
48 if (!*(p = *argv + 1)) { /* A single '-', so echo it. */ 51 if (!*p) /* A single '-', so echo it. */
49 goto just_echo; 52 goto just_echo;
50 }
51 53
52 do { 54 do {
53 if (strrchr("neE", *p) == 0) { 55 if (!strrchr("neE", *p))
54 goto just_echo; 56 goto just_echo;
55 }
56 } while (*++p); 57 } while (*++p);
57 58
58 /* All of the options in this arg are valid, so handle them. */ 59 /* All of the options in this arg are valid, so handle them. */
59 p = *argv + 1; 60 p = arg + 1;
60 do { 61 do {
61 if (*p == 'n') { 62 if (*p == 'n')
62 nflag = 0; 63 nflag = 0;
63 } else if (*p == 'e') { 64 if (*p == 'e')
64 eflag = '\\'; 65 eflag = '\\';
65 } else {
66 eflag = 0;
67 }
68 } while (*++p); 66 } while (*++p);
69 } 67 }
70 68 just_echo:
71just_echo:
72#endif 69#endif
73 while (*argv) { 70 while (1) {
71 /* arg is already = *argv and isn't NULL */
74 int c; 72 int c;
75 73
76 while ((c = *(*argv)++)) { 74 while ((c = *arg++)) {
77 if (c == eflag) { /* Check for escape seq. */ 75 if (c == eflag) { /* Check for escape seq. */
78 if (**argv == 'c') { 76 if (*arg == 'c') {
79 /* '\c' means cancel newline and 77 /* '\c' means cancel newline and
80 * ignore all subsequent chars. */ 78 * ignore all subsequent chars. */
81 return 0; 79 goto ret;
82 } 80 }
83#ifndef CONFIG_FEATURE_FANCY_ECHO 81#if !ENABLE_FEATURE_FANCY_ECHO
84 /* SUSv3 specifies that octal escapes must begin with '0'. */ 82 /* SUSv3 specifies that octal escapes must begin with '0'. */
85 if (((unsigned int)(**argv - '1')) >= 7) 83 if ( (((unsigned char)*arg) - '1') >= 7)
86#endif 84#endif
87 { 85 {
88 /* Since SUSv3 mandates a first digit of 0, 4-digit octals 86 /* Since SUSv3 mandates a first digit of 0, 4-digit octals
89 * of the form \0### are accepted. */ 87 * of the form \0### are accepted. */
90 if ((**argv == '0') && (((unsigned int)(argv[0][1] - '0')) < 8)) { 88 if (*arg == '0' && ((unsigned char)(arg[1]) - '0') < 8) {
91 (*argv)++; 89 arg++;
92 } 90 }
93 /* bb_process_escape_sequence can handle nul correctly */ 91 /* bb_process_escape_sequence can handle nul correctly */
94 c = bb_process_escape_sequence((const char **) argv); 92 c = bb_process_escape_sequence(&arg);
95 } 93 }
96 } 94 }
97 putchar(c); 95 putchar(c);
98 } 96 }
99 97
100 if (*++argv) { 98 arg = *++argv;
101 putchar(' '); 99 if (!arg)
102 } 100 break;
101 putchar(' ');
103 } 102 }
104 103
105#ifdef CONFIG_FEATURE_FANCY_ECHO 104#ifdef CONFIG_FEATURE_FANCY_ECHO
@@ -109,14 +108,16 @@ just_echo:
109#else 108#else
110 putchar('\n'); 109 putchar('\n');
111#endif 110#endif
112 return 0; 111 ret:
112 return fflush(stdout);
113} 113}
114 114
115/* This is a NOFORK applet. Be very careful! */
116
115int echo_main(int argc, char** argv); 117int echo_main(int argc, char** argv);
116int echo_main(int argc, char** argv) 118int echo_main(int argc, char** argv)
117{ 119{
118 (void)bb_echo(argv); 120 return bb_echo(argv);
119 fflush_stdout_and_exit(EXIT_SUCCESS);
120} 121}
121 122
122/*- 123/*-