rpm 5.2.1

- Main Page
- Related Pages
- Modules
- Data Structures
- Files

- File List
- Globals

rpmiob.c
Go to the documentation of this file.
1
4 #include "system.h"
5 #define _RPMIOB_INTERNAL
6 #include <rpmiotypes.h>
7 #include <rpmio.h>
8 #include "debug.h"
9
10 /*@unchecked@*/
11 size_t _rpmiob_chunk = 1024;
12
13 /*@unchecked@*/
14 int _rpmiob_debug;
15
16 static void rpmiobFini(void * _iob)
17 {
18 rpmiob iob = _iob;
19
20 iob->b = _free(iob->b);
21 iob->blen = 0;
22 iob->allocated = 0;
23 }
24
25 /*@unchecked@*/ /*@only@*/ /*@null@*/
26 rpmioPool _rpmiobPool;
27
28 static rpmiob rpmiobGetPool(/*@null@*/ rpmioPool pool)
29 /*@globals _rpmiobPool, fileSystem @*/
30 /*@modifies pool, _rpmiobPool, fileSystem @*/
31 {
32 rpmiob iob;
33
34 if (_rpmiobPool == NULL) {
35 _rpmiobPool = rpmioNewPool("iob", sizeof(*iob), -1, _rpmiob_debug,
36 NULL, NULL, rpmiobFini);
37 pool = _rpmiobPool;
38 }
39 return (rpmiob) rpmioGetPool(pool, sizeof(*iob));
40 }
41
42 rpmiob rpmiobNew(size_t len)
43 {
44 rpmiob iob = rpmiobGetPool(_rpmiobPool);
45 if (len == 0)
46 len = _rpmiob_chunk;
47 iob->allocated = len;
48 iob->blen = 0;
49 iob->b = xcalloc(iob->allocated+1, sizeof(*iob->b));
50 return rpmiobLink(iob);
51 }
52
53 rpmiob rpmiobEmpty(rpmiob iob)
54 {
55 assert(iob != NULL);
56 iob->b[0] = '\0';
57 iob->blen = 0;
58 return iob;
59 }
60
61 rpmiob rpmiobRTrim(rpmiob iob)
62 {
63
64 assert(iob != NULL);
65 while (iob->blen > 0 && xisspace((int)iob->b[iob->blen-1]))
66 iob->b[--iob->blen] = (rpmuint8_t) '\0';
67 return iob;
68 }
69
70 rpmiob rpmiobAppend(rpmiob iob, const char * s, size_t nl)
71 {
72 size_t ns = strlen(s);
73 rpmuint8_t * tail;
74
75 if (nl > 0) ns++;
76
77 assert(iob != NULL);
78 if ((iob->blen + ns) > iob->allocated) {
79 iob->allocated += ((ns+_rpmiob_chunk-1)/_rpmiob_chunk) * _rpmiob_chunk;
80 iob->b = xrealloc(iob->b, iob->allocated+1);
81 }
82
83 tail = iob->b + iob->blen;
84 tail = (rpmuint8_t *) stpcpy((char *)tail, s);
85 if (nl > 0) {
86 *tail++ = (rpmuint8_t) '\n';
87 *tail = (rpmuint8_t) '\0';
88 }
89 iob->blen += ns;
90 return iob;
91 }
92
93 rpmuint8_t * rpmiobBuf(rpmiob iob)
94 {
95 assert(iob != NULL);
96 /*@-retalias -retexpose -usereleased @*/
97 return iob->b;
98 /*@=retalias =retexpose =usereleased @*/
99 }
100
101 char * rpmiobStr(rpmiob iob)
102 {
103 assert(iob != NULL);
104 /*@-retalias -retexpose -usereleased @*/
105 return (char *) iob->b;
106 /*@=retalias =retexpose =usereleased @*/
107 }
108
109 size_t rpmiobLen(rpmiob iob)
110 {
111 return (iob != NULL ? iob->blen : 0);
112 }
113
114 int rpmiobSlurp(const char * fn, rpmiob * iobp)
115 {
116 static size_t blenmax = (32 * BUFSIZ);
117 rpmuint8_t * b = NULL;
118 size_t blen;
119 struct stat sb;
120 FD_t fd;
121 int rc = 0;
122 int xx;
123
124 fd = Fopen(fn, "r%{?_rpmgio}");
125 if (fd == NULL || Ferror(fd)) {
126 rc = 2;
127 goto exit;
128 }
129 sb.st_size = 0;
130 if ((xx = Fstat(fd, &sb)) < 0 || sb.st_size == 0)
131 sb.st_size = blenmax;
132 #if defined(__linux__)
133 /* XXX st->st_size = 0 for /proc files on linux, see stat(2). */
134 /* XXX glibc mmap'd libio no workie for /proc files on linux?!? */
135 if (sb.st_size == 0 && !strncmp(fn, "/proc/", sizeof("/proc/")-1)) {
136 blen = blenmax;
137 b = xmalloc(blen+1);
138 b[0] = (rpmuint8_t) '\0';
139
140 xx = read(Fileno(fd), b, blen);
141 blen = (size_t) (xx >= 0 ? xx : 0);
142 } else
143 #endif
144 {
145 blen = sb.st_size;
146 b = xmalloc(blen+1);
147 b[0] = (rpmuint8_t) '\0';
148
149 blen = Fread(b, sizeof(*b), blen, fd);
150 if (Ferror(fd)) {
151 rc = 1;
152 goto exit;
153 }
154 }
155 if (blen < (size_t)sb.st_size)
156 b = xrealloc(b, blen+1);
157 b[blen] = (rpmuint8_t) '\0';
158
159 exit:
160 if (fd != NULL) (void) Fclose(fd);
161
162 if (rc == 0) {
163 if (iobp != NULL) {
164 /* XXX use rpmiobNew() if/when lazy iop->b alloc is implemented. */
165 rpmiob iob = rpmiobGetPool(_rpmiobPool);
166 iob->b = b;
167 iob->blen = blen;
168 iob->allocated = blen;
169 *iobp = iob;
170 }
171 } else {
172 if (iobp)
173 *iobp = NULL;
174 b = _free(b);
175 }
176
177 return rc;
178 }