19ddb49cbSWarner Losh /*- 28a16b7a1SPedro F. Giffuni * SPDX-License-Identifier: BSD-3-Clause 38a16b7a1SPedro F. Giffuni * 44b88c807SRodney W. Grimes * Copyright (c) 1989, 1993 54b88c807SRodney W. Grimes * The Regents of the University of California. All rights reserved. 64b88c807SRodney W. Grimes * 74b88c807SRodney W. Grimes * Redistribution and use in source and binary forms, with or without 84b88c807SRodney W. Grimes * modification, are permitted provided that the following conditions 94b88c807SRodney W. Grimes * are met: 104b88c807SRodney W. Grimes * 1. Redistributions of source code must retain the above copyright 114b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer. 124b88c807SRodney W. Grimes * 2. Redistributions in binary form must reproduce the above copyright 134b88c807SRodney W. Grimes * notice, this list of conditions and the following disclaimer in the 144b88c807SRodney W. Grimes * documentation and/or other materials provided with the distribution. 15fbbd9655SWarner Losh * 3. Neither the name of the University nor the names of its contributors 164b88c807SRodney W. Grimes * may be used to endorse or promote products derived from this software 174b88c807SRodney W. Grimes * without specific prior written permission. 184b88c807SRodney W. Grimes * 194b88c807SRodney W. Grimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 204b88c807SRodney W. Grimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 214b88c807SRodney W. Grimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 224b88c807SRodney W. Grimes * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 234b88c807SRodney W. Grimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 244b88c807SRodney W. Grimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 254b88c807SRodney W. Grimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 264b88c807SRodney W. Grimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 274b88c807SRodney W. Grimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 284b88c807SRodney W. Grimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 294b88c807SRodney W. Grimes * SUCH DAMAGE. 304b88c807SRodney W. Grimes */ 314b88c807SRodney W. Grimes 3209a80d48SDavid E. O'Brien #if 0 334b88c807SRodney W. Grimes #ifndef lint 3478b09ffeSSteve Price static char const copyright[] = 354b88c807SRodney W. Grimes "@(#) Copyright (c) 1989, 1993\n\ 364b88c807SRodney W. Grimes The Regents of the University of California. All rights reserved.\n"; 374b88c807SRodney W. Grimes #endif /* not lint */ 384b88c807SRodney W. Grimes 394b88c807SRodney W. Grimes #ifndef lint 4095d0bf65SPhilippe Charnier static char sccsid[] = "@(#)echo.c 8.1 (Berkeley) 5/31/93"; 414b88c807SRodney W. Grimes #endif /* not lint */ 4209a80d48SDavid E. O'Brien #endif 435eb43ac2SDavid E. O'Brien #include <sys/cdefs.h> 445eb43ac2SDavid E. O'Brien __FBSDID("$FreeBSD$"); 454b88c807SRodney W. Grimes 4691b7d6dcSDiomidis Spinellis #include <sys/types.h> 4791b7d6dcSDiomidis Spinellis #include <sys/uio.h> 484b88c807SRodney W. Grimes 4991b7d6dcSDiomidis Spinellis #include <assert.h> 50cd1693d3SConrad Meyer #include <capsicum_helpers.h> 51cd1693d3SConrad Meyer #include <err.h> 5291b7d6dcSDiomidis Spinellis #include <errno.h> 5391b7d6dcSDiomidis Spinellis #include <limits.h> 5491b7d6dcSDiomidis Spinellis #include <stdlib.h> 5591b7d6dcSDiomidis Spinellis #include <string.h> 5691b7d6dcSDiomidis Spinellis #include <unistd.h> 5791b7d6dcSDiomidis Spinellis 584b88c807SRodney W. Grimes int 5991b7d6dcSDiomidis Spinellis main(int argc, char *argv[]) 604b88c807SRodney W. Grimes { 616188858aSAlfred Perlstein int nflag; /* if not set, output a trailing newline. */ 6291b7d6dcSDiomidis Spinellis int veclen; /* number of writev arguments. */ 6391b7d6dcSDiomidis Spinellis struct iovec *iov, *vp; /* Elements to write, current element. */ 6491b7d6dcSDiomidis Spinellis char space[] = " "; 6591b7d6dcSDiomidis Spinellis char newline[] = "\n"; 664b88c807SRodney W. Grimes 677672a014SMariusz Zaborski if (caph_limit_stdio() < 0 || caph_enter() < 0) 68cd1693d3SConrad Meyer err(1, "capsicum"); 69cd1693d3SConrad Meyer 704b88c807SRodney W. Grimes /* This utility may NOT do getopt(3) option parsing. */ 714b88c807SRodney W. Grimes if (*++argv && !strcmp(*argv, "-n")) { 724b88c807SRodney W. Grimes ++argv; 7391b7d6dcSDiomidis Spinellis --argc; 744b88c807SRodney W. Grimes nflag = 1; 7591b7d6dcSDiomidis Spinellis } else 764b88c807SRodney W. Grimes nflag = 0; 774b88c807SRodney W. Grimes 7891b7d6dcSDiomidis Spinellis veclen = (argc >= 2) ? (argc - 2) * 2 + 1 : 0; 7991b7d6dcSDiomidis Spinellis 8091b7d6dcSDiomidis Spinellis if ((vp = iov = malloc((veclen + 1) * sizeof(struct iovec))) == NULL) 81*4c537df5SHans Petter Selasky err(1, "malloc"); 8291b7d6dcSDiomidis Spinellis 836188858aSAlfred Perlstein while (argv[0] != NULL) { 84ef3e71daSNate Lawson size_t len; 85ef3e71daSNate Lawson 86ef3e71daSNate Lawson len = strlen(argv[0]); 876cef43a7SJordan K. Hubbard 886188858aSAlfred Perlstein /* 89a249b285SLi-Wen Hsu * If the next argument is NULL then this is the last argument, 90a249b285SLi-Wen Hsu * therefore we need to check for a trailing \c. 916188858aSAlfred Perlstein */ 926188858aSAlfred Perlstein if (argv[1] == NULL) { 936188858aSAlfred Perlstein /* is there room for a '\c' and is there one? */ 946188858aSAlfred Perlstein if (len >= 2 && 956188858aSAlfred Perlstein argv[0][len - 2] == '\\' && 966188858aSAlfred Perlstein argv[0][len - 1] == 'c') { 976188858aSAlfred Perlstein /* chop it and set the no-newline flag. */ 98ef3e71daSNate Lawson len -= 2; 996cef43a7SJordan K. Hubbard nflag = 1; 1006cef43a7SJordan K. Hubbard } 1016188858aSAlfred Perlstein } 10291b7d6dcSDiomidis Spinellis vp->iov_base = *argv; 10391b7d6dcSDiomidis Spinellis vp++->iov_len = len; 10491b7d6dcSDiomidis Spinellis if (*++argv) { 10591b7d6dcSDiomidis Spinellis vp->iov_base = space; 10691b7d6dcSDiomidis Spinellis vp++->iov_len = 1; 1074b88c807SRodney W. Grimes } 10891b7d6dcSDiomidis Spinellis } 10991b7d6dcSDiomidis Spinellis if (!nflag) { 11091b7d6dcSDiomidis Spinellis veclen++; 11191b7d6dcSDiomidis Spinellis vp->iov_base = newline; 11291b7d6dcSDiomidis Spinellis vp++->iov_len = 1; 11391b7d6dcSDiomidis Spinellis } 11491b7d6dcSDiomidis Spinellis /* assert(veclen == (vp - iov)); */ 11591b7d6dcSDiomidis Spinellis while (veclen) { 11691b7d6dcSDiomidis Spinellis int nwrite; 11791b7d6dcSDiomidis Spinellis 11891b7d6dcSDiomidis Spinellis nwrite = (veclen > IOV_MAX) ? IOV_MAX : veclen; 11991b7d6dcSDiomidis Spinellis if (writev(STDOUT_FILENO, iov, nwrite) == -1) 120*4c537df5SHans Petter Selasky err(1, "write"); 12191b7d6dcSDiomidis Spinellis iov += nwrite; 12291b7d6dcSDiomidis Spinellis veclen -= nwrite; 12391b7d6dcSDiomidis Spinellis } 1249b2010a2SMark Murray return 0; 1254b88c807SRodney W. Grimes } 126