Changeset 3192 in kBuild for trunk/src/kmk/kmkbuiltin/echo.c
- Timestamp:
- Mar 26, 2018 8:25:56 PM (7 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kmkbuiltin/echo.c
r3065 r3192 1 /* 2 * Copyright (c) 1989, 1993 3 * The Regents of the University of California. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 4. Neither the name of the University nor the names of its contributors 14 * may be used to endorse or promote products derived from this software 15 * without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 1 /* $Id$ */ 2 /** @file 3 * kMk Builtin command - echo 28 4 */ 29 5 30 #if 0 31 #ifndef lint 32 static char const copyright[] = 33 "@(#) Copyright (c) 1989, 1993\n\ 34 The Regents of the University of California. All rights reserved.\n"; 35 #endif /* not lint */ 6 /* 7 * Copyright (c) 2018 knut st. osmundsen <bird-kBuild-spamx@anduin.net> 8 * 9 * This file is part of kBuild. 10 * 11 * kBuild is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 3 of the License, or 14 * (at your option) any later version. 15 * 16 * kBuild is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with kBuild. If not, see <http://www.gnu.org/licenses/> 23 * 24 */ 36 25 37 #ifndef lint 38 static char sccsid[] = "@(#)echo.c 8.1 (Berkeley) 5/31/93"; 39 #endif /* not lint */ 40 #include <sys/cdefs.h> 41 /*__FBSDID("$FreeBSD: src/bin/echo/echo.c,v 1.17 2004/04/06 20:06:46 markm Exp $");*/ 26 27 /********************************************************************************************************************************* 28 * Header Files * 29 *********************************************************************************************************************************/ 30 #include "config.h" 31 32 #include <string.h> 33 #include <stdlib.h> 34 #include <stdio.h> 35 #ifdef HAVE_UNISTD_H 36 # include <unistd.h> 37 #endif 38 #ifdef _MSC_VER 39 # include <io.h> 42 40 #endif 43 41 44 #include "config.h" 45 #include <sys/types.h> 46 #ifndef _MSC_VER 47 #include <sys/uio.h> 42 #include "kmkbuiltin.h" 43 #include "err.h" 44 45 46 int kmk_builtin_echo(int argc, char **argv, char **envp, PKMKBUILTINCTX pCtx) 47 { 48 int rcExit = 0; 49 int iFirst = 1; 50 int i; 51 char *pszBuf; 52 size_t cbBuf; 53 54 /* 55 * Check for the -n option. 56 */ 57 int fNoNewLine = 0; 58 if ( argc > iFirst 59 && strcmp(argv[iFirst], "-n") == 0) 60 { 61 iFirst++; 62 fNoNewLine = 1; 63 } 64 65 /* 66 * Calc buffer size and allocate it. 67 */ 68 cbBuf = 1 + 1; 69 for (i = 1; i < argc; i++) 70 cbBuf += (i > iFirst) + strlen(argv[i]); 71 pszBuf = (char *)malloc(cbBuf); 72 if (pszBuf) 73 { 74 /* 75 * Assembler the output into the buffer. 76 */ 77 char *pszDst = pszBuf; 78 for (i = iFirst; i < argc; i++) 79 { 80 const char *pszArg = argv[i]; 81 size_t cchArg = strlen(pszArg); 82 83 /* Check for "\c" in final argument (same as -n). */ 84 if (i + 1 >= argc 85 && cchArg >= 2 86 && pszArg[cchArg - 2] == '\\' 87 && pszArg[cchArg - 1] == 'c') 88 { 89 fNoNewLine = 1; 90 cchArg -= 2; 91 } 92 if (i > iFirst) 93 *pszDst++ = ' '; 94 memcpy(pszDst, pszArg, cchArg); 95 pszDst += cchArg; 96 } 97 if (!fNoNewLine) 98 *pszDst++ = '\n'; 99 *pszDst = '\0'; 100 101 /* 102 * Push it out. 103 */ 104 #ifndef KMK_BUILTIN_STANDALONE 105 if (output_write_text(pCtx->pOut, 0, pszBuf, pszDst - pszBuf) == -1) 106 rcExit = err(pCtx, 1, "output_write_text"); 107 #else 108 if (write(STDOUT_FILENO, pszBuf, pszDst - pszBuf) == -1) 109 rcExit = err(pCtx, 1, "write"); 110 #endif 111 free(pszBuf); 112 } 113 else 114 rcExit = err(pCtx, 1, "malloc(%lu)", (unsigned long)cbBuf); 115 return rcExit; 116 } 117 118 #ifdef KMK_BUILTIN_STANDALONE 119 int main(int argc, char **argv, char **envp) 120 { 121 KMKBUILTINCTX Ctx = { "kmk_echo", NULL }; 122 return kmk_builtin_echo(argc, argv, envp, &Ctx); 123 } 48 124 #endif 49 125 50 #include <stdio.h>51 #include <assert.h>52 #include <errno.h>53 #include <limits.h>54 #include <stdlib.h>55 #include <string.h>56 #ifndef _MSC_VER57 #include <unistd.h>58 #else59 #include "mscfakes.h"60 #endif61 62 #ifndef IOV_MAX63 #define IOV_MAX 102464 #endif65 66 67 /*68 * Report an error and exit.69 * Use it instead of err(3) to avoid linking-in stdio.70 */71 static void72 errexit(const char *prog, const char *reason)73 {74 char *errstr = strerror(errno);75 ssize_t cchIgn = 0; /* this is to shut up irrelevant warnings on linux. */76 #ifdef _MSC_VER77 int doserrno = _doserrno;78 char szDosErr[48];79 sprintf(szDosErr, " (doserrno=%d)", doserrno);80 #endif81 cchIgn += write(STDERR_FILENO, prog, strlen(prog));82 cchIgn += write(STDERR_FILENO, ": ", 2);83 cchIgn += write(STDERR_FILENO, reason, strlen(reason));84 cchIgn += write(STDERR_FILENO, ": ", 2);85 cchIgn += write(STDERR_FILENO, errstr, strlen(errstr));86 #ifdef _MSC_VER87 cchIgn += write(STDERR_FILENO, szDosErr, strlen(szDosErr));88 #endif89 cchIgn += write(STDERR_FILENO, "\n", 1);90 (void)cchIgn;91 }92 93 int94 kmk_builtin_echo(int argc, char *argv[])95 {96 int nflag; /* if not set, output a trailing newline. */97 int veclen; /* number of writev arguments. */98 struct iovec *iov, *vp, *iovfree; /* Elements to write, current element. */99 char space[] = " ";100 char newline[] = "\n";101 char *progname = argv[0];102 103 /* This utility may NOT do getopt(3) option parsing. */104 if (*++argv && !strcmp(*argv, "-n")) {105 ++argv;106 --argc;107 nflag = 1;108 } else109 nflag = 0;110 111 veclen = (argc >= 2) ? (argc - 2) * 2 + 1 : 0;112 113 if ((iovfree = vp = iov = malloc((veclen + 1) * sizeof(struct iovec))) == NULL) {114 errexit(progname, "malloc");115 exit(1);116 }117 118 while (argv[0] != NULL) {119 size_t len;120 121 len = strlen(argv[0]);122 123 /*124 * If the next argument is NULL then this is this125 * the last argument, therefore we need to check126 * for a trailing \c.127 */128 if (argv[1] == NULL) {129 /* is there room for a '\c' and is there one? */130 if (len >= 2 &&131 argv[0][len - 2] == '\\' &&132 argv[0][len - 1] == 'c') {133 /* chop it and set the no-newline flag. */134 len -= 2;135 nflag = 1;136 }137 }138 vp->iov_base = *argv;139 vp++->iov_len = len;140 if (*++argv) {141 vp->iov_base = space;142 vp++->iov_len = 1;143 }144 }145 if (!nflag) {146 veclen++;147 vp->iov_base = newline;148 vp++->iov_len = 1;149 }150 /* assert(veclen == (vp - iov)); */151 while (veclen) {152 int nwrite;153 154 nwrite = (veclen > IOV_MAX) ? IOV_MAX : veclen;155 if (writev(STDOUT_FILENO, iov, nwrite) == -1) {156 errexit(progname, "write");157 free(iovfree);158 return 1;159 }160 iov += nwrite;161 veclen -= nwrite;162 }163 free(iovfree);164 return 0;165 }
Note:
See TracChangeset
for help on using the changeset viewer.