source: MondoRescue/branches/3.2/mindi-busybox/coreutils/tac.c@ 3232

Last change on this file since 3232 was 3232, checked in by Bruno Cornec, 10 years ago
  • Update mindi-busybox to 1.21.1
  • Property svn:eol-style set to native
File size: 2.5 KB
Line 
1/* vi: set sw=4 ts=4: */
2/*
3 * tac implementation for busybox
4 *
5 * Copyright (C) 2003 Yang Xiaopeng <yxp at hanwang.com.cn>
6 * Copyright (C) 2007 Natanael Copa <natanael.copa@gmail.com>
7 * Copyright (C) 2007 Tito Ragusa <farmatito@tiscali.it>
8 *
9 * Licensed under GPLv2, see file LICENSE in this source tree.
10 *
11 */
12
13/* tac - concatenate and print files in reverse */
14
15/* Based on Yang Xiaopeng's (yxp at hanwang.com.cn) patch
16 * http://www.uclibc.org/lists/busybox/2003-July/008813.html
17 */
18
19//usage:#define tac_trivial_usage
20//usage: "[FILE]..."
21//usage:#define tac_full_usage "\n\n"
22//usage: "Concatenate FILEs and print them in reverse"
23
24#include "libbb.h"
25
26/* This is a NOEXEC applet. Be very careful! */
27
28struct lstring {
29 int size;
30 char buf[1];
31};
32
33int tac_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
34int tac_main(int argc UNUSED_PARAM, char **argv)
35{
36 char **name;
37 FILE *f;
38 struct lstring *line = NULL;
39 llist_t *list = NULL;
40 int retval = EXIT_SUCCESS;
41
42#if ENABLE_DESKTOP
43/* tac from coreutils 6.9 supports:
44 -b, --before
45 attach the separator before instead of after
46 -r, --regex
47 interpret the separator as a regular expression
48 -s, --separator=STRING
49 use STRING as the separator instead of newline
50We support none, but at least we will complain or handle "--":
51*/
52 getopt32(argv, "");
53 argv += optind;
54#else
55 argv++;
56#endif
57 if (!*argv)
58 *--argv = (char *)"-";
59 /* We will read from last file to first */
60 name = argv;
61 while (*name)
62 name++;
63
64 do {
65 int ch, i;
66
67 name--;
68 f = fopen_or_warn_stdin(*name);
69 if (f == NULL) {
70 /* error message is printed by fopen_or_warn_stdin */
71 retval = EXIT_FAILURE;
72 continue;
73 }
74
75 errno = i = 0;
76 do {
77 ch = fgetc(f);
78 if (ch != EOF) {
79 if (!(i & 0x7f))
80 /* Grow on every 128th char */
81 line = xrealloc(line, i + 0x7f + sizeof(int) + 1);
82 line->buf[i++] = ch;
83 }
84 if (ch == '\n' || (ch == EOF && i != 0)) {
85 line = xrealloc(line, i + sizeof(int));
86 line->size = i;
87 llist_add_to(&list, line);
88 line = NULL;
89 i = 0;
90 }
91 } while (ch != EOF);
92 /* fgetc sets errno to ENOENT on EOF, we don't want
93 * to warn on this non-error! */
94 if (errno && errno != ENOENT) {
95 bb_simple_perror_msg(*name);
96 retval = EXIT_FAILURE;
97 }
98 } while (name != argv);
99
100 while (list) {
101 line = (struct lstring *)list->data;
102 xwrite(STDOUT_FILENO, line->buf, line->size);
103 if (ENABLE_FEATURE_CLEAN_UP) {
104 free(llist_pop(&list));
105 } else {
106 list = list->link;
107 }
108 }
109
110 return retval;
111}
Note: See TracBrowser for help on using the repository browser.