[BusyBox] Does anyone need 'tac' command?
Yang Xiaopeng
yxp at hanwang.com.cn
Wed Jul 30 18:51:24 MDT 2003
hi,
I write a ugly 'tac' applet for busybox, it's very simple, just print
input file lines in reverse, hope it could be helpful.
-------------- next part --------------
diff -urN busybox-1.00-pre1/coreutils/Config.in busybox-1.00/coreutils/Config.in
--- busybox-1.00-pre1/coreutils/Config.in 2003-07-15 03:37:08.000000000 +0800
+++ busybox-1.00/coreutils/Config.in 2003-07-30 17:33:04.000000000 +0800
@@ -421,6 +421,12 @@
help
sync is used to flush filesystem buffers.
+config CONFIG_TAC
+ bool "tac"
+ default n
+ help
+ tac is used to concatenate and print files in reverse.
+
config CONFIG_TAIL
bool "tail"
default n
diff -urN busybox-1.00-pre1/coreutils/Makefile.in busybox-1.00/coreutils/Makefile.in
--- busybox-1.00-pre1/coreutils/Makefile.in 2003-07-15 05:20:43.000000000 +0800
+++ busybox-1.00/coreutils/Makefile.in 2003-07-30 17:33:05.000000000 +0800
@@ -67,6 +67,7 @@
COREUTILS-$(CONFIG_SORT) += sort.o
COREUTILS-$(CONFIG_STTY) += stty.o
COREUTILS-$(CONFIG_SYNC) += sync.o
+COREUTILS-$(CONFIG_TAC) += tac.o
COREUTILS-$(CONFIG_TAIL) += tail.o
COREUTILS-$(CONFIG_TEE) += tee.o
COREUTILS-$(CONFIG_TEST) += test.o
diff -urN busybox-1.00-pre1/coreutils/tac.c busybox-1.00/coreutils/tac.c
--- busybox-1.00-pre1/coreutils/tac.c 1970-01-01 08:00:00.000000000 +0800
+++ busybox-1.00/coreutils/tac.c 2003-07-30 17:33:05.000000000 +0800
@@ -0,0 +1,140 @@
+/* vi: set sw=4 ts=4: */
+/*
+ * tac implementation for busybox
+ *
+ * Copyright (C) 2003 Yang Xiaopeng <yxp at hanwang.com.cn>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/* tac - concatenate and print files in reverse */
+
+/* Writen by Yang Xiaopeng (yxp at hanwang.com.cn), refer to the tac
+ * source code Written by Jay Lepreau (lepreau at cs.utah.edu). */
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/mman.h>
+#include "busybox.h"
+
+#ifndef DEFAULT_TMPDIR
+#define DEFAULT_TMPDIR "/tmp"
+#endif
+
+/* Print file to stdout in reverse */
+static int tac_file(int fd)
+{
+ struct stat stats;
+ char *map, *ptr, *end;
+
+ if (fstat(fd, &stats)) {
+ return -1;
+ }
+
+ map = mmap(0, stats.st_size, PROT_READ, MAP_SHARED, fd, 0);
+ if (map == MAP_FAILED) {
+ return -1;
+ }
+
+ ptr = end = map + stats.st_size - 1;
+ while (ptr >= map) {
+ if (*ptr == '\n') ptr--;
+ while (ptr >= map && *ptr != '\n') ptr--;
+ bb_full_write(STDOUT_FILENO, ptr+1, end-ptr);
+ end = ptr;
+ }
+ munmap(map, stats.st_size);
+
+ return 0;
+}
+
+/* Make a copy of the standard input. */
+static int save_stdin(int fdin)
+{
+ static char *template = NULL;
+ static char *tempdir;
+ int fd;
+
+ tempdir = getenv("TMPDIR");
+ if (!tempdir)
+ tempdir = DEFAULT_TMPDIR;
+ template = xmalloc(strlen(tempdir) + 11);
+ sprintf(template, "%s/tacXXXXXX", tempdir);
+
+ fd = mkstemp(template);
+ if (fd == -1) {
+ bb_error_msg("Can't creat temp file\n");
+ return -1;
+ }
+
+ if (bb_copyfd(fdin, fd, 0) < 0) {
+ bb_error_msg("Copy file error\n");
+ return -1;
+ }
+
+ unlink(template);
+ free(template);
+
+ return fd;
+}
+
+extern int tac_main(int argc, char **argv)
+{
+ FILE *f;
+ int retval = EXIT_SUCCESS;
+ struct stat stats;
+ int fd;
+ int error;
+
+ argv++;
+ if (!*argv)
+ *--argv = "-";
+
+ do {
+ if ((f = bb_wfopen_input(*argv)) != NULL) {
+ fd = fileno(f);
+ if (fstat(fd, &stats)) {
+ bb_error_msg("Can't stat input file\n");
+ retval = EXIT_FAILURE;
+ break;
+ }
+
+ if (S_ISREG(stats.st_mode)) {
+ error = tac_file(fd);
+ } else {
+ fd = save_stdin(fd);
+ if (fd == -1) {
+ retval = EXIT_FAILURE;
+ break;
+ }
+
+ error = tac_file(fd);
+ close(fd);
+ }
+
+ bb_fclose_nonstdin(f);
+
+ if (!error) {
+ continue;
+ }
+ }
+ retval = EXIT_FAILURE;
+ } while (*++argv);
+
+ return retval;
+}
diff -urN busybox-1.00-pre1/include/applets.h busybox-1.00/include/applets.h
--- busybox-1.00-pre1/include/applets.h 2003-07-05 15:51:31.000000000 +0800
+++ busybox-1.00/include/applets.h 2003-07-30 17:33:20.000000000 +0800
@@ -544,6 +544,9 @@
#ifdef CONFIG_SYSLOGD
APPLET(syslogd, syslogd_main, _BB_DIR_SBIN, _BB_SUID_NEVER)
#endif
+#ifdef CONFIG_TAC
+ APPLET(tac, tac_main, _BB_DIR_BIN, _BB_SUID_NEVER)
+#endif
#ifdef CONFIG_TAIL
APPLET(tail, tail_main, _BB_DIR_USR_BIN, _BB_SUID_NEVER)
#endif
diff -urN busybox-1.00-pre1/include/usage.h busybox-1.00/include/usage.h
--- busybox-1.00-pre1/include/usage.h 2003-07-15 06:14:49.000000000 +0800
+++ busybox-1.00/include/usage.h 2003-07-30 17:33:20.000000000 +0800
@@ -2112,6 +2112,10 @@
"$ syslogd -R masterlog:514\n" \
"$ syslogd -R 192.168.1.1:601\n"
+#define tac_trivial_usage \
+ "[FILE]..."
+#define tac_full_usage \
+ "Concatenates FILE(s) and prints them to stdout in reverse.\n\n"
#ifndef CONFIG_FEATURE_FANCY_TAIL
#define USAGE_UNSIMPLE_TAIL(a)
More information about the busybox
mailing list