apps/system/tee: Port tee command from NetBSD
This commit is contained in:
parent
d8c7a8fff8
commit
35c32d4ba0
11
system/tee/.gitignore
vendored
Normal file
11
system/tee/.gitignore
vendored
Normal file
@ -0,0 +1,11 @@
|
||||
/Make.dep
|
||||
/.depend
|
||||
/.built
|
||||
/*.asm
|
||||
/*.rel
|
||||
/*.lst
|
||||
/*.sym
|
||||
/*.adb
|
||||
/*.lib
|
||||
/*.src
|
||||
/*.obj
|
26
system/tee/Kconfig
Normal file
26
system/tee/Kconfig
Normal file
@ -0,0 +1,26 @@
|
||||
#
|
||||
# For a description of the syntax of this configuration file,
|
||||
# see the file kconfig-language.txt in the NuttX tools repository.
|
||||
#
|
||||
|
||||
config SYSTEM_TEE
|
||||
bool "Tee Command"
|
||||
default n
|
||||
---help---
|
||||
Enable support for the tee command.
|
||||
|
||||
if SYSTEM_TEE
|
||||
|
||||
config SYSTEM_TEE_STACKSIZE
|
||||
int "tee stack size"
|
||||
default 1536
|
||||
---help---
|
||||
The size of stack allocated for the tee task.
|
||||
|
||||
config SYSTEM_TEE_PRIORITY
|
||||
int "tee priority"
|
||||
default 100
|
||||
---help---
|
||||
The priority of the tee task.
|
||||
|
||||
endif
|
39
system/tee/Make.defs
Normal file
39
system/tee/Make.defs
Normal file
@ -0,0 +1,39 @@
|
||||
############################################################################
|
||||
# apps/system/tee/Make.defs
|
||||
# Adds selected applications to apps/ build
|
||||
#
|
||||
# Copyright (C) 2016 Gregory Nutt. All rights reserved.
|
||||
# Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# 3. Neither the name NuttX nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
ifeq ($(CONFIG_SYSTEM_TEE),y)
|
||||
CONFIGURED_APPS += system/tee
|
||||
endif
|
146
system/tee/Makefile
Normal file
146
system/tee/Makefile
Normal file
@ -0,0 +1,146 @@
|
||||
############################################################################
|
||||
# apps/system/tee/Makefile
|
||||
#
|
||||
# Copyright (C) 2011-2012 Uros Platise. All rights reserved.
|
||||
# Copyright (C) 2012, 2016 Gregory Nutt. All rights reserved.
|
||||
# Author: Uros Platise <uros.platise@isotel.eu>
|
||||
# Gregory Nutt <gnutt@nuttx.org>
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without
|
||||
# modification, are permitted provided that the following conditions
|
||||
# are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright
|
||||
# notice, this list of conditions and the following disclaimer.
|
||||
# 2. Redistributions in binary form must reproduce the above copyright
|
||||
# notice, this list of conditions and the following disclaimer in
|
||||
# the documentation and/or other materials provided with the
|
||||
# distribution.
|
||||
# 3. Neither the name NuttX nor the names of its contributors may be
|
||||
# used to endorse or promote products derived from this software
|
||||
# without specific prior written permission.
|
||||
#
|
||||
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
|
||||
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
|
||||
# OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
|
||||
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
# POSSIBILITY OF SUCH DAMAGE.
|
||||
#
|
||||
############################################################################
|
||||
|
||||
-include $(TOPDIR)/.config
|
||||
-include $(TOPDIR)/Make.defs
|
||||
include $(APPDIR)/Make.defs
|
||||
|
||||
# tee command
|
||||
|
||||
CONFIG_SYSTEM_TEE_STACKSIZE ?= 1536
|
||||
CONFIG_SYSTEM_TEE_PRIORITY ?= 100
|
||||
|
||||
APPNAME = tee
|
||||
PRIORITY = $(CONFIG_SYSTEM_TEE_PRIORITY)
|
||||
STACKSIZE = $(CONFIG_SYSTEM_TEE_PRIORITY)
|
||||
|
||||
ASRCS =
|
||||
CSRCS =
|
||||
MAINSRC = tee.c
|
||||
|
||||
AOBJS = $(ASRCS:.S=$(OBJEXT))
|
||||
COBJS = $(CSRCS:.c=$(OBJEXT))
|
||||
MAINOBJ = $(MAINSRC:.c=$(OBJEXT))
|
||||
|
||||
SRCS = $(ASRCS) $(CSRCS) $(MAINSRC)
|
||||
OBJS = $(AOBJS) $(COBJS)
|
||||
|
||||
ifneq ($(CONFIG_BUILD_KERNEL),y)
|
||||
OBJS += $(MAINOBJ)
|
||||
endif
|
||||
|
||||
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
|
||||
BIN = ..\..\libapps$(LIBEXT)
|
||||
else
|
||||
ifeq ($(WINTOOL),y)
|
||||
BIN = ..\\..\\libapps$(LIBEXT)
|
||||
else
|
||||
BIN = ../../libapps$(LIBEXT)
|
||||
endif
|
||||
endif
|
||||
|
||||
ifeq ($(WINTOOL),y)
|
||||
INSTALL_DIR = "${shell cygpath -w $(BIN_DIR)}"
|
||||
else
|
||||
INSTALL_DIR = $(BIN_DIR)
|
||||
endif
|
||||
|
||||
CONFIG_XYZ_PROGNAME ?= tee$(EXEEXT)
|
||||
PROGNAME = $(CONFIG_XYZ_PROGNAME)
|
||||
|
||||
ROOTDEPPATH = --dep-path .
|
||||
|
||||
# Common build
|
||||
|
||||
VPATH =
|
||||
|
||||
all: .built
|
||||
.PHONY: context depend clean distclean
|
||||
|
||||
$(AOBJS): %$(OBJEXT): %.S
|
||||
$(call ASSEMBLE, $<, $@)
|
||||
|
||||
$(COBJS) $(MAINOBJ): %$(OBJEXT): %.c
|
||||
$(call COMPILE, $<, $@)
|
||||
|
||||
.built: $(OBJS)
|
||||
$(call ARCHIVE, $(BIN), $(OBJS))
|
||||
$(Q) touch .built
|
||||
|
||||
ifeq ($(CONFIG_BUILD_KERNEL),y)
|
||||
$(BIN_DIR)$(DELIM)$(PROGNAME): $(OBJS) $(MAINOBJ)
|
||||
@echo "LD: $(PROGNAME)"
|
||||
$(Q) $(LD) $(LDELFFLAGS) $(LDLIBPATH) -o $(INSTALL_DIR)$(DELIM)$(PROGNAME) $(ARCHCRT0OBJ) $(MAINOBJ) $(LDLIBS)
|
||||
$(Q) $(NM) -u $(INSTALL_DIR)$(DELIM)$(PROGNAME)
|
||||
|
||||
install: $(BIN_DIR)$(DELIM)$(PROGNAME)
|
||||
|
||||
else
|
||||
install:
|
||||
|
||||
endif
|
||||
|
||||
# Register application
|
||||
|
||||
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
|
||||
$(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat: $(DEPCONFIG) Makefile
|
||||
$(call REGISTER,$(APPNAME),$(PRIORITY),$(STACKSIZE),$(APPNAME)_main)
|
||||
|
||||
context: $(BUILTIN_REGISTRY)$(DELIM)$(APPNAME)_main.bdat
|
||||
else
|
||||
context:
|
||||
endif
|
||||
|
||||
# Create dependencies
|
||||
|
||||
.depend: Makefile $(SRCS)
|
||||
$(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
|
||||
$(Q) touch $@
|
||||
|
||||
depend: .depend
|
||||
|
||||
clean:
|
||||
$(call DELFILE, .built)
|
||||
$(call CLEAN)
|
||||
|
||||
distclean: clean
|
||||
$(call DELFILE, Make.dep)
|
||||
$(call DELFILE, .depend)
|
||||
|
||||
-include Make.dep
|
||||
.PHONY: preconfig
|
||||
preconfig:
|
242
system/tee/tee.c
Normal file
242
system/tee/tee.c
Normal file
@ -0,0 +1,242 @@
|
||||
/****************************************************************************
|
||||
* apps/system/tee/tee.c
|
||||
* $NetBSD: tee.c,v 1.6 1997/10/20 00:37:11 lukem Exp $
|
||||
*
|
||||
* Copyright (c) 2016. Gregory Nutt. All rights reserved.
|
||||
* Author: Gregory Nutt <gnutt@nuttx.org>
|
||||
*
|
||||
* Leveraged from NetBSD:
|
||||
*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
/****************************************************************************
|
||||
* Included Files
|
||||
****************************************************************************/
|
||||
|
||||
#include <nuttx/config.h>
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <debug.h>
|
||||
|
||||
/****************************************************************************
|
||||
* Pre-processor Definitions
|
||||
****************************************************************************/
|
||||
|
||||
#define BSIZE 1024
|
||||
#define STDIN_FILENO 0
|
||||
#define STDOUT_FILENO 1
|
||||
|
||||
/****************************************************************************
|
||||
* Private Types
|
||||
****************************************************************************/
|
||||
|
||||
struct tee_list_s
|
||||
{
|
||||
FAR struct tee_list_s *next;
|
||||
FAR char *name;
|
||||
int fd;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
* Private Functions
|
||||
****************************************************************************/
|
||||
|
||||
static int tee_add(int fd, FAR char *name,
|
||||
FAR struct tee_list_s **head)
|
||||
{
|
||||
FAR struct tee_list_s *curr;
|
||||
|
||||
curr = (FAR struct tee_list_s *)malloc((sizeof(struct tee_list_s)));
|
||||
if (curr == NULL)
|
||||
{
|
||||
_err("ERROR: alloc failed\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
curr->fd = fd;
|
||||
curr->name = name;
|
||||
curr->next = *head;
|
||||
*head = curr;
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
static void show_usage(FAR const char *progrname, int exitcode)
|
||||
{
|
||||
fprintf(stderr, "USAGE: tee [-a] [file ...]\n");
|
||||
fprintf(stderr, " tee -h\n");
|
||||
fprintf(stderr, "Where:\n");
|
||||
fprintf(stderr, "-a:\n");
|
||||
fprintf(stderr, "\tAppend to the file (vs. truncating)\n");
|
||||
fprintf(stderr, "file:\n");
|
||||
fprintf(stderr, "\tArbitrary number of options output files. Output\n");
|
||||
fprintf(stderr, "\twill go to stdout in addition to each of these files.\n");
|
||||
fprintf(stderr, "-h:\n");
|
||||
fprintf(stderr, "\tShows this message and exits\n");
|
||||
exit(exitcode);
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Public Functions
|
||||
****************************************************************************/
|
||||
|
||||
#ifdef CONFIG_BUILD_KERNEL
|
||||
int main(int argc, FAR char *argv[])
|
||||
#else
|
||||
int tee_main(int argc, char *argv[])
|
||||
#endif
|
||||
{
|
||||
FAR struct tee_list_s *head = NULL;
|
||||
FAR struct tee_list_s *curr;
|
||||
FAR struct tee_list_s *next;
|
||||
FAR char *buf;
|
||||
FAR char *bp;
|
||||
bool append = false;
|
||||
int exitcode = EXIT_FAILURE;
|
||||
int rval;
|
||||
int wval;
|
||||
int ret;
|
||||
int fd;
|
||||
int ch;
|
||||
int n;
|
||||
|
||||
while ((ch = getopt(argc, argv, "ah")) != -1)
|
||||
{
|
||||
switch (ch)
|
||||
{
|
||||
case 'a':
|
||||
append = true;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
show_usage(argv[0], EXIT_SUCCESS);
|
||||
|
||||
case '?':
|
||||
default:
|
||||
show_usage(argv[0], EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
argv += optind;
|
||||
argc -= optind;
|
||||
|
||||
buf = (FAR char *)malloc((size_t)BSIZE);
|
||||
if (buf == NULL)
|
||||
{
|
||||
_err("ERROR: malloc failed\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
ret = tee_add(STDOUT_FILENO, "stdout", &head);
|
||||
if (ret < 0)
|
||||
{
|
||||
_err("ERROR: tee_add failed: %d\n", ret);
|
||||
goto errout_with_buf;
|
||||
}
|
||||
|
||||
for (; *argv; ++argv)
|
||||
{
|
||||
fd = open(*argv, append ? O_WRONLY | O_CREAT | O_APPEND :
|
||||
O_WRONLY | O_CREAT | O_TRUNC, 0644);
|
||||
if (fd < 0)
|
||||
{
|
||||
_err("ERROR: tee_add failed: %d\n", errno);
|
||||
goto errout_with_list;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = tee_add(fd, *argv, &head);
|
||||
if (ret < 0)
|
||||
{
|
||||
_err("ERROR: tee_add failed: %d\n", ret);
|
||||
goto errout_with_list;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while ((rval = read(STDIN_FILENO, buf, BSIZE)) > 0)
|
||||
{
|
||||
for (curr = head; curr; curr = curr->next)
|
||||
{
|
||||
n = rval;
|
||||
bp = buf;
|
||||
|
||||
do
|
||||
{
|
||||
wval = write(curr->fd, bp, n);
|
||||
if (wval < 0)
|
||||
{
|
||||
_err("ERROR: write to %s failed: %d\n",
|
||||
curr->name, errno);
|
||||
break;
|
||||
}
|
||||
|
||||
bp += wval;
|
||||
n -= wval;
|
||||
}
|
||||
while (n > 0);
|
||||
}
|
||||
}
|
||||
|
||||
if (rval >= 0)
|
||||
{
|
||||
exitcode = EXIT_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
_err("ERROR: read failed: %d\n", errno);
|
||||
}
|
||||
|
||||
errout_with_list:
|
||||
for (curr = head; curr; curr = next)
|
||||
{
|
||||
next = curr->next;
|
||||
(void)close(curr->fd);
|
||||
free(curr);
|
||||
}
|
||||
|
||||
errout_with_buf:
|
||||
free(buf);
|
||||
exit(exitcode);
|
||||
}
|
Loading…
Reference in New Issue
Block a user