Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
att
GitHub Repository: att/ast
Path: blob/master/src/lib/libcs/csread.c
1808 views
1
/***********************************************************************
2
* *
3
* This software is part of the ast package *
4
* Copyright (c) 1990-2011 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
* *
19
***********************************************************************/
20
#pragma prototyped
21
/*
22
* Glenn Fowler
23
* AT&T Research
24
*
25
* read at most size chars according to op
26
*
27
* CS_EXACT read exactly size chars
28
* multiple reads possible
29
* CS_LIMIT one read up to size chars
30
* CS_LINE '\n' '\r\n' '\n\r' terminated line up to size
31
* multiple reads possible
32
* CS_RESTART restart on interrupt
33
*
34
* 0 returned on eof
35
*/
36
37
#include "cslib.h"
38
39
ssize_t
40
csread(Cs_t* state, int fd, void* buf, size_t size, int op)
41
{
42
register ssize_t n;
43
register char* p;
44
register char* e;
45
int restart;
46
47
if (restart = !!(op & CS_RESTART))
48
op &= ~CS_RESTART;
49
p = (char*)buf;
50
e = p + size;
51
messagef((state->id, NiL, -9, "read(%d,%d,%s) before", fd, size, op == CS_EXACT ? "EXACT" : op == CS_LIMIT ? "LIMIT" : "LINE"));
52
if (op == CS_LINE && size > 1)
53
{
54
if ((n = cspeek(state, fd, buf, size - 1)) > 0 && (p[n] = 0, e = strchr(p, '\n')))
55
{
56
e++;
57
op = CS_EXACT;
58
}
59
else
60
{
61
while (p < e && (n = read(fd, p, 1)) == 1 && *p++ != '\n');
62
if (n <= 0 || p == (char*)buf || *(p - 1) != '\n')
63
goto bad;
64
n = p - (char*)buf;
65
messagef((state->id, NiL, -9, "read(%d,%d,%s) [%d] `%-.*s'", fd, size, op == CS_EXACT ? "EXACT" : op == CS_LIMIT ? "LIMIT" : "LINE", n, n, buf));
66
return n;
67
}
68
}
69
while (n = read(fd, p, e - p))
70
{
71
if (n < 0)
72
{
73
if (restart && errno == EINTR)
74
continue;
75
break;
76
}
77
messagef((state->id, NiL, -9, "read(%d,%d,%s) [%d] `%-.*s'", fd, size, op == CS_EXACT ? "EXACT" : op == CS_LIMIT ? "LIMIT" : "LINE", n, n, p));
78
p += n;
79
if (op == CS_LIMIT || op == CS_LINE && (*(p - 1) == '\n' || n > 1 && *(p - 1) == '\r' && *(p - 2) == '\n'))
80
return p - (char*)buf;
81
if (p >= e)
82
{
83
if (op == CS_EXACT)
84
return p - (char*)buf;
85
break;
86
}
87
messagef((state->id, NiL, -2, "read(%d,%d,%s) again [%d] `%-.*s'", fd, size, op == CS_EXACT ? "EXACT" : op == CS_LIMIT ? "LIMIT" : "LINE", p - (char*)buf, p - (char*)buf, (char*)buf));
88
}
89
bad:
90
if (p != (char*)buf || n < 0)
91
{
92
errno = EINVAL;
93
messagef((state->id, NiL, -2, "read(%d,%d,%s) invalid record [%d] `%-.*s'", fd, size, op == CS_EXACT ? "EXACT" : op == CS_LIMIT ? "LIMIT" : "LINE", p - (char*)buf, p - (char*)buf, (char*)buf));
94
return -1;
95
}
96
messagef((state->id, NiL, -2, "read(%d,%d,%s) eof", fd, size, op == CS_EXACT ? "EXACT" : op == CS_LIMIT ? "LIMIT" : "LINE"));
97
return 0;
98
}
99
100
ssize_t
101
_cs_read(int fd, void* buf, size_t size, int op)
102
{
103
return csread(&cs, fd, buf, size, op);
104
}
105
106