aboutsummaryrefslogtreecommitdiff
path: root/coreutils
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-06-01 22:36:39 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-06-01 22:36:39 +0000
commitcd2663f15e74274619dd97dc382bb858ac255872 (patch)
treef86565e574c3488794383b910b9f3fa3ae27df48 /coreutils
parentd78920675f31d6ec87dc883c4edc0f3862b22f6a (diff)
downloadbusybox-cd2663f15e74274619dd97dc382bb858ac255872.tar.gz
ash: optional printf builtin. +25 bytes if off, +35 if on.
by Cristian Ionescu-Idbohrn.
Diffstat (limited to 'coreutils')
-rw-r--r--coreutils/Kbuild1
-rw-r--r--coreutils/chown.c1
-rw-r--r--coreutils/printf.c18
3 files changed, 16 insertions, 4 deletions
diff --git a/coreutils/Kbuild b/coreutils/Kbuild
index cb4543912..a5a2d4c26 100644
--- a/coreutils/Kbuild
+++ b/coreutils/Kbuild
@@ -54,6 +54,7 @@ lib-$(CONFIG_NOHUP) += nohup.o
lib-$(CONFIG_OD) += od.o
lib-$(CONFIG_PRINTENV) += printenv.o
lib-$(CONFIG_PRINTF) += printf.o
+lib-$(CONFIG_ASH_BUILTIN_PRINTF) += printf.o
lib-$(CONFIG_PWD) += pwd.o
lib-$(CONFIG_READLINK) += readlink.o
lib-$(CONFIG_REALPATH) += realpath.o
diff --git a/coreutils/chown.c b/coreutils/chown.c
index eaaefaf29..78377e6a0 100644
--- a/coreutils/chown.c
+++ b/coreutils/chown.c
@@ -61,7 +61,6 @@ static int fileAction(const char *fileName, struct stat *statbuf,
return FALSE;
}
-int chown_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int chown_main(int argc ATTRIBUTE_UNUSED, char **argv)
{
int retval = EXIT_SUCCESS;
diff --git a/coreutils/printf.c b/coreutils/printf.c
index ebe961564..b7752369c 100644
--- a/coreutils/printf.c
+++ b/coreutils/printf.c
@@ -193,6 +193,7 @@ static char **print_formatted(char *f, char **argv)
unsigned direc_length; /* Length of % directive. */
int field_width; /* Arg to first '*', or -1 if none. */
int precision; /* Arg to second '*', or -1 if none. */
+ char **saved_argv = argv;
for (; *f; ++f) {
switch (*f) {
@@ -264,8 +265,9 @@ static char **print_formatted(char *f, char **argv)
precision, "");
break;
case '\\':
- if (*++f == 'c')
- exit(EXIT_SUCCESS);
+ if (*++f == 'c') {
+ return saved_argv; /* causes main() to exit */
+ }
bb_putchar(bb_process_escape_sequence((const char **)&f));
f--;
break;
@@ -277,12 +279,22 @@ static char **print_formatted(char *f, char **argv)
return argv;
}
-int printf_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
int printf_main(int argc ATTRIBUTE_UNUSED, char **argv)
{
char *format;
char **argv2;
+ /* We must check that stdout is not closed.
+ * The reason for this is highly non-obvious. printf_main is used from shell.
+ * Shell must correctly handle 'printf "%s" foo'
+ * if stdout is closed. With stdio, output gets shoveled into
+ * stdout buffer, and even fflush cannot clear it out. It seems that
+ * even if libc receives EBADF on write attempts, it feels determined
+ * to output data no matter what. So it will try later,
+ * and possibly will clobber future output. Not good. */
+ if (dup2(1, 1) != 1)
+ return -1;
+
/* bash builtin errors out on "printf '-%s-\n' foo",
* coreutils-6.9 works. Both work with "printf -- '-%s-\n' foo".
* We will mimic coreutils. */