Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libcmd/head.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1992-2012 AT&T Intellectual Property *
5
* and is licensed under the *
6
* Eclipse Public License, Version 1.0 *
7
* by AT&T Intellectual Property *
8
* *
9
* A copy of the License is available at *
10
* http://www.eclipse.org/org/documents/epl-v10.html *
11
* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
12
* *
13
* Information and Software Systems Research *
14
* AT&T Research *
15
* Florham Park NJ *
16
* *
17
* Glenn Fowler <[email protected]> *
18
* David Korn <[email protected]> *
19
* *
20
***********************************************************************/
21
#pragma prototyped
22
/*
23
* David Korn
24
* AT&T Bell Laboratories
25
*
26
* output the beginning portion of one or more files
27
*/
28
29
static const char usage[] =
30
"[-n?\n@(#)$Id: head (AT&T Research) 2012-05-31 $\n]"
31
USAGE_LICENSE
32
"[+NAME?head - output beginning portion of one or more files ]"
33
"[+DESCRIPTION?\bhead\b copies one or more input files to standard "
34
"output stopping at a designated point for each file or to the end of "
35
"the file whichever comes first. Copying ends at the point indicated by "
36
"the options. By default a header of the form \b==> \b\afilename\a\b "
37
"<==\b is output before all but the first file but this can be changed "
38
"with the \b-q\b and \b-v\b options.]"
39
"[+?If no \afile\a is given, or if the \afile\a is \b-\b, \bhead\b "
40
"copies from standard input starting at the current location.]"
41
"[+?The option argument for \b-c\b, and \b-s\b can optionally be "
42
"followed by one of the following characters to specify a different unit "
43
"other than a single byte:]"
44
"{"
45
"[+b?512 bytes.]"
46
"[+k?1-killobyte.]"
47
"[+m?1-megabyte.]"
48
"}"
49
"[+?For backwards compatibility, \b-\b\anumber\a is equivalent to \b-n\b "
50
"\anumber\a.]"
51
"[n:lines?Copy \alines\a lines from each file.]#[lines:=10]"
52
"[c:bytes?Copy \achars\a bytes from each file.]#[chars]"
53
"[q:quiet|silent?Never ouput filename headers.]"
54
"[s:skip?Skip \askip\a characters or lines from each file before "
55
"copying.]#[skip]"
56
"[v:verbose?Always ouput filename headers.]"
57
"\n\n"
58
"[ file ... ]"
59
"\n\n"
60
"[+EXIT STATUS?]"
61
"{"
62
"[+0?All files copied successfully.]"
63
"[+>0?One or more files did not copy.]"
64
"}"
65
"[+SEE ALSO?\bcat\b(1), \btail\b(1)]"
66
;
67
68
#include <cmd.h>
69
70
int
71
b_head(int argc, register char** argv, Shbltin_t* context)
72
{
73
static const char header_fmt[] = "\n==> %s <==\n";
74
75
register Sfio_t* fp;
76
register char* cp;
77
register off_t keep = 10;
78
register off_t skip = 0;
79
register int delim = '\n';
80
int header = 1;
81
char* format = (char*)header_fmt+1;
82
83
cmdinit(argc, argv, context, ERROR_CATALOG, 0);
84
for (;;)
85
{
86
switch (optget(argv, usage))
87
{
88
case 'c':
89
delim = -1;
90
/*FALLTHROUGH*/
91
case 'n':
92
if (opt_info.offset && argv[opt_info.index][opt_info.offset] == 'c')
93
{
94
delim = -1;
95
opt_info.offset++;
96
}
97
if ((keep = opt_info.number) <=0)
98
error(2, "%s: %I*d: positive numeric option argument expected", opt_info.name, sizeof(keep), keep);
99
continue;
100
case 'q':
101
header = argc;
102
continue;
103
case 'v':
104
header = 0;
105
continue;
106
case 's':
107
skip = opt_info.number;
108
continue;
109
case '?':
110
error(ERROR_usage(2), "%s", opt_info.arg);
111
continue;
112
case ':':
113
error(2, "%s", opt_info.arg);
114
continue;
115
}
116
break;
117
}
118
argv += opt_info.index;
119
argc -= opt_info.index;
120
if (error_info.errors)
121
error(ERROR_usage(2), "%s", optusage(NiL));
122
if (cp = *argv)
123
argv++;
124
do
125
{
126
if (!cp || streq(cp, "-"))
127
{
128
cp = "/dev/stdin";
129
fp = sfstdin;
130
sfset(fp, SF_SHARE, 1);
131
}
132
else if (!(fp = sfopen(NiL, cp, "r")))
133
{
134
error(ERROR_system(0), "%s: cannot open", cp);
135
continue;
136
}
137
if (argc > header)
138
sfprintf(sfstdout, format, cp);
139
format = (char*)header_fmt;
140
if (skip > 0)
141
sfmove(fp, NiL, skip, delim);
142
if (sfmove(fp, sfstdout, keep, delim) < 0 && !ERROR_PIPE(errno) && errno != EINTR)
143
error(ERROR_system(0), "%s: read error", cp);
144
if (fp != sfstdin)
145
sfclose(fp);
146
} while (cp = *argv++);
147
if (sfsync(sfstdout))
148
error(ERROR_system(0), "write error");
149
return error_info.errors != 0;
150
}
151
152