diff options
author | Diomidis Spinellis <dds@FreeBSD.org> | 2003-10-11 20:34:43 +0000 |
---|---|---|
committer | Diomidis Spinellis <dds@FreeBSD.org> | 2003-10-11 20:34:43 +0000 |
commit | 91b7d6dc5871f532b1a86ee76389a9bc348bdf58 (patch) | |
tree | 533e6e21a58986c2d4f90e619a507734341bf87d /bin/echo/echo.c | |
parent | 84b11cd80a5a5b46ea59420b8290ce6113fb889f (diff) | |
download | src-test2-91b7d6dc5871f532b1a86ee76389a9bc348bdf58.tar.gz src-test2-91b7d6dc5871f532b1a86ee76389a9bc348bdf58.zip |
Notes
Diffstat (limited to 'bin/echo/echo.c')
-rw-r--r-- | bin/echo/echo.c | 69 |
1 files changed, 59 insertions, 10 deletions
diff --git a/bin/echo/echo.c b/bin/echo/echo.c index 85a9efaafd7f..cb0c7899e975 100644 --- a/bin/echo/echo.c +++ b/bin/echo/echo.c @@ -45,23 +45,56 @@ static char sccsid[] = "@(#)echo.c 8.1 (Berkeley) 5/31/93"; #include <sys/cdefs.h> __FBSDID("$FreeBSD$"); -#include <unistd.h> +#include <sys/types.h> +#include <sys/uio.h> + +#include <assert.h> +#include <errno.h> +#include <limits.h> +#include <stdlib.h> #include <string.h> +#include <unistd.h> -/* ARGSUSED */ +/* + * Report an error and exit. + * Use it instead of err(3) to avoid linking-in stdio. + */ +static void +errexit(const char *prog, const char *reason) +{ + char *errstr = strerror(errno); + write(STDERR_FILENO, prog, strlen(prog)); + write(STDERR_FILENO, ": ", 2); + write(STDERR_FILENO, reason, strlen(reason)); + write(STDERR_FILENO, ": ", 2); + write(STDERR_FILENO, errstr, strlen(errstr)); + write(STDERR_FILENO, "\n", 1); + exit(1); +} + int -main(int argc __unused, char *argv[]) +main(int argc, char *argv[]) { int nflag; /* if not set, output a trailing newline. */ + int veclen; /* number of writev arguments. */ + struct iovec *iov, *vp; /* Elements to write, current element. */ + char space[] = " "; + char newline[] = "\n"; + char *progname = argv[0]; /* This utility may NOT do getopt(3) option parsing. */ if (*++argv && !strcmp(*argv, "-n")) { ++argv; + --argc; nflag = 1; - } - else + } else nflag = 0; + veclen = (argc >= 2) ? (argc - 2) * 2 + 1 : 0; + + if ((vp = iov = malloc((veclen + 1) * sizeof(struct iovec))) == NULL) + errexit(progname, "malloc"); + while (argv[0] != NULL) { size_t len; @@ -82,11 +115,27 @@ main(int argc __unused, char *argv[]) nflag = 1; } } - write(STDOUT_FILENO, argv[0], len); - if (*++argv) - write(STDOUT_FILENO, " ", 1); + vp->iov_base = *argv; + vp++->iov_len = len; + if (*++argv) { + vp->iov_base = space; + vp++->iov_len = 1; + } + } + if (!nflag) { + veclen++; + vp->iov_base = newline; + vp++->iov_len = 1; + } + /* assert(veclen == (vp - iov)); */ + while (veclen) { + int nwrite; + + nwrite = (veclen > IOV_MAX) ? IOV_MAX : veclen; + if (writev(STDOUT_FILENO, iov, nwrite) == -1) + errexit(progname, "write"); + iov += nwrite; + veclen -= nwrite; } - if (!nflag) - write(STDOUT_FILENO, "\n", 1); return 0; } |