mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-12-19 14:31:48 +01:00
sh: Add printf builtin.
This was removed in 2001 but I think it is appropriate to add it back: * I do not want to encourage people to write fragile and non-portable echo commands by making printf much slower than echo. * Recent versions of Autoconf use it a lot. * Almost no software still wants to support systems that do not have printf(1) at all. * In many other shells printf is already a builtin. Side effect: printf is now always the builtin version (which behaves identically to /usr/bin/printf) and cannot be overridden via PATH (except via the undocumented %builtin mechanism). Code size increases about 5K on i386. Embedded folks might want to replace /usr/bin/printf with a hard link to /usr/bin/alias.
This commit is contained in:
parent
b00f982843
commit
9897c45f31
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=215520
@ -5,7 +5,7 @@ PROG= sh
|
||||
INSTALLFLAGS= -S
|
||||
SHSRCS= alias.c arith.y arith_lex.l cd.c echo.c error.c eval.c exec.c expand.c \
|
||||
histedit.c input.c jobs.c mail.c main.c memalloc.c miscbltin.c \
|
||||
mystring.c options.c output.c parser.c redir.c show.c \
|
||||
mystring.c options.c output.c parser.c printf.c redir.c show.c \
|
||||
test.c trap.c var.c
|
||||
GENSRCS= builtins.c init.c nodes.c syntax.c
|
||||
GENHDRS= builtins.h nodes.h syntax.h token.h
|
||||
@ -26,7 +26,8 @@ WARNS?= 2
|
||||
WFORMAT=0
|
||||
|
||||
.PATH: ${.CURDIR}/bltin \
|
||||
${.CURDIR}/../test
|
||||
${.CURDIR}/../test \
|
||||
${.CURDIR}/../../usr.bin/printf
|
||||
|
||||
CLEANFILES+= mkinit mkinit.o mknodes mknodes.o \
|
||||
mksyntax mksyntax.o
|
||||
|
@ -71,7 +71,7 @@ histcmd -h fc
|
||||
jobidcmd jobid
|
||||
jobscmd jobs
|
||||
localcmd local
|
||||
#printfcmd printf
|
||||
printfcmd printf
|
||||
pwdcmd pwd
|
||||
readcmd read
|
||||
returncmd -s return
|
||||
|
@ -32,7 +32,7 @@
|
||||
.\" from: @(#)sh.1 8.6 (Berkeley) 5/4/95
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd November 12, 2010
|
||||
.Dd November 19, 2010
|
||||
.Dt SH 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -2049,6 +2049,9 @@ line.
|
||||
See the
|
||||
.Sx Functions
|
||||
subsection.
|
||||
.It Ic printf
|
||||
A built-in equivalent of
|
||||
.Xr printf 1 .
|
||||
.It Ic pwd Op Fl L | P
|
||||
Print the path of the current directory.
|
||||
The built-in command may
|
||||
@ -2470,6 +2473,7 @@ will return the argument.
|
||||
.Xr echo 1 ,
|
||||
.Xr ed 1 ,
|
||||
.Xr emacs 1 ,
|
||||
.Xr printf 1 ,
|
||||
.Xr pwd 1 ,
|
||||
.Xr test 1 ,
|
||||
.Xr vi 1 ,
|
||||
|
@ -26,7 +26,7 @@
|
||||
.\"
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd May 9, 2010
|
||||
.Dd November 19, 2010
|
||||
.Dt BUILTIN 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -99,6 +99,7 @@
|
||||
.Nm onintr ,
|
||||
.Nm popd ,
|
||||
.Nm printenv ,
|
||||
.Nm printf ,
|
||||
.Nm pushd ,
|
||||
.Nm pwd ,
|
||||
.Nm read ,
|
||||
@ -263,6 +264,7 @@ but are implemented as scripts using a builtin command of the same name.
|
||||
.It Ic onintr Ta \&No Ta Yes Ta \&No
|
||||
.It Ic popd Ta \&No Ta Yes Ta \&No
|
||||
.It Ic printenv Ta Yes Ta Yes Ta \&No
|
||||
.It Ic printf Ta Yes Ta \&No Ta Yes
|
||||
.It Ic pushd Ta \&No Ta Yes Ta \&No
|
||||
.It Ic pwd Ta Yes Ta \&No Ta Yes
|
||||
.It Ic read Ta No** Ta \&No Ta Yes
|
||||
@ -313,6 +315,7 @@ but are implemented as scripts using a builtin command of the same name.
|
||||
.Xr nice 1 ,
|
||||
.Xr nohup 1 ,
|
||||
.Xr printenv 1 ,
|
||||
.Xr printf 1 ,
|
||||
.Xr pwd 1 ,
|
||||
.Xr sh 1 ,
|
||||
.Xr test 1 ,
|
||||
|
@ -35,7 +35,7 @@
|
||||
.\" @(#)printf.1 8.1 (Berkeley) 6/6/93
|
||||
.\" $FreeBSD$
|
||||
.\"
|
||||
.Dd September 5, 2010
|
||||
.Dd November 19, 2010
|
||||
.Dt PRINTF 1
|
||||
.Os
|
||||
.Sh NAME
|
||||
@ -306,6 +306,13 @@ character is defined in the program's locale (category
|
||||
In no case does a non-existent or small field width cause truncation of
|
||||
a field; padding takes place only if the specified field width exceeds
|
||||
the actual width.
|
||||
.Pp
|
||||
Some shells may provide a builtin
|
||||
.Nm
|
||||
command which is similar or identical to this utility.
|
||||
Consult the
|
||||
.Xr builtin 1
|
||||
manual page.
|
||||
.Sh EXIT STATUS
|
||||
.Ex -std
|
||||
.Sh COMPATIBILITY
|
||||
@ -316,7 +323,9 @@ with a digit to the
|
||||
.Tn ASCII
|
||||
code of the first character is not supported.
|
||||
.Sh SEE ALSO
|
||||
.Xr builtin 1 ,
|
||||
.Xr echo 1 ,
|
||||
.Xr sh 1 ,
|
||||
.Xr printf 3
|
||||
.Sh STANDARDS
|
||||
The
|
||||
|
@ -62,6 +62,7 @@ static const char rcsid[] =
|
||||
#define main printfcmd
|
||||
#include "bltin/bltin.h"
|
||||
#include "memalloc.h"
|
||||
#include "error.h"
|
||||
#else
|
||||
#define warnx1(a, b, c) warnx(a)
|
||||
#define warnx2(a, b, c) warnx(a, b)
|
||||
@ -90,7 +91,7 @@ static const char rcsid[] =
|
||||
} while (0)
|
||||
|
||||
static int asciicode(void);
|
||||
static char *doformat(char *, int *);
|
||||
static char *printf_doformat(char *, int *);
|
||||
static int escape(char *, int, size_t *);
|
||||
static int getchr(void);
|
||||
static int getfloating(long double *, int);
|
||||
@ -114,8 +115,11 @@ main(int argc, char *argv[])
|
||||
int ch, chopped, end, rval;
|
||||
char *format, *fmt, *start;
|
||||
|
||||
#ifndef BUILTIN
|
||||
#if !defined(BUILTIN) && !defined(SHELL)
|
||||
(void) setlocale(LC_NUMERIC, "");
|
||||
#endif
|
||||
#ifdef SHELL
|
||||
optreset = 1; optind = 1; opterr = 0; /* initialize getopt */
|
||||
#endif
|
||||
while ((ch = getopt(argc, argv, "")) != -1)
|
||||
switch (ch) {
|
||||
@ -132,6 +136,9 @@ main(int argc, char *argv[])
|
||||
return (1);
|
||||
}
|
||||
|
||||
#ifdef SHELL
|
||||
INTOFF;
|
||||
#endif
|
||||
/*
|
||||
* Basic algorithm is to scan the format string for conversion
|
||||
* specifications -- once one is found, find out if the field
|
||||
@ -154,9 +161,13 @@ main(int argc, char *argv[])
|
||||
putchar('%');
|
||||
fmt += 2;
|
||||
} else {
|
||||
fmt = doformat(fmt, &rval);
|
||||
if (fmt == NULL)
|
||||
fmt = printf_doformat(fmt, &rval);
|
||||
if (fmt == NULL) {
|
||||
#ifdef SHELL
|
||||
INTON;
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
end = 0;
|
||||
}
|
||||
start = fmt;
|
||||
@ -166,11 +177,18 @@ main(int argc, char *argv[])
|
||||
|
||||
if (end == 1) {
|
||||
warnx1("missing format character", NULL, NULL);
|
||||
#ifdef SHELL
|
||||
INTON;
|
||||
#endif
|
||||
return (1);
|
||||
}
|
||||
fwrite(start, 1, fmt - start, stdout);
|
||||
if (chopped || !*gargv)
|
||||
if (chopped || !*gargv) {
|
||||
#ifdef SHELL
|
||||
INTON;
|
||||
#endif
|
||||
return (rval);
|
||||
}
|
||||
/* Restart at the beginning of the format string. */
|
||||
fmt = format;
|
||||
end = 1;
|
||||
@ -180,7 +198,7 @@ main(int argc, char *argv[])
|
||||
|
||||
|
||||
static char *
|
||||
doformat(char *start, int *rval)
|
||||
printf_doformat(char *start, int *rval)
|
||||
{
|
||||
static const char skip1[] = "#'-+ 0";
|
||||
static const char skip2[] = "0123456789";
|
||||
|
Loading…
Reference in New Issue
Block a user