VirtualBox

Changeset 3192 in kBuild for trunk/src/kmk/kmkbuiltin/echo.c


Ignore:
Timestamp:
Mar 26, 2018 8:25:56 PM (7 years ago)
Author:
bird
Message:

kmkbuiltin: funnel output thru output.c (usually via err.c).

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
    284 */
    295
    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 */
    3625
    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>
    4240#endif
    4341
    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
     46int 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
     119int main(int argc, char **argv, char **envp)
     120{
     121    KMKBUILTINCTX Ctx = { "kmk_echo", NULL };
     122    return kmk_builtin_echo(argc, argv, envp, &Ctx);
     123}
    48124#endif
    49125
    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_VER
    57 #include <unistd.h>
    58 #else
    59 #include "mscfakes.h"
    60 #endif
    61 
    62 #ifndef IOV_MAX
    63 #define IOV_MAX 1024
    64 #endif
    65 
    66 
    67 /*
    68  * Report an error and exit.
    69  * Use it instead of err(3) to avoid linking-in stdio.
    70  */
    71 static void
    72 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_VER
    77         int doserrno = _doserrno;
    78         char szDosErr[48];
    79         sprintf(szDosErr, " (doserrno=%d)", doserrno);
    80 #endif
    81         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_VER
    87         cchIgn += write(STDERR_FILENO, szDosErr, strlen(szDosErr));
    88 #endif
    89         cchIgn += write(STDERR_FILENO, "\n", 1);
    90         (void)cchIgn;
    91 }
    92 
    93 int
    94 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         } else
    109                 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 this
    125                  * the last argument, therefore we need to check
    126                  * 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.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette