rpm  5.4.10
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@*/
15 
16 static void rpmiobFini(void * _iob)
17 {
18  rpmiob iob = (rpmiob) _iob;
19 
20 if (_rpmiob_debug)
21 fprintf(stderr, "--> %s(%p) %p[%u:%u]\n", __FUNCTION__, iob, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated);
22  iob->b = _free(iob->b);
23  iob->blen = 0;
24  iob->allocated = 0;
25 }
26 
27 /*@unchecked@*/ /*@only@*/ /*@null@*/
29 
30 static rpmiob rpmiobGetPool(/*@null@*/ rpmioPool pool)
31  /*@globals _rpmiobPool, fileSystem @*/
32  /*@modifies pool, _rpmiobPool, fileSystem @*/
33 {
34  rpmiob iob;
35 
36  if (_rpmiobPool == NULL) {
37  _rpmiobPool = rpmioNewPool("iob", sizeof(*iob), -1, _rpmiob_debug,
38  NULL, NULL, rpmiobFini);
39  pool = _rpmiobPool;
40  }
41  return (rpmiob) rpmioGetPool(pool, sizeof(*iob));
42 }
43 
44 rpmiob rpmiobNew(size_t len)
45 {
46  rpmiob iob = rpmiobGetPool(_rpmiobPool);
47 if (_rpmiob_debug)
48 fprintf(stderr, "--> %s(%p) %p[%u:%u]\n", __FUNCTION__, iob, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated);
49  if (len == 0)
50  len = _rpmiob_chunk;
51  iob->allocated = len;
52  iob->blen = 0;
53  iob->b = (rpmuint8_t *) xcalloc(iob->allocated+1, sizeof(*iob->b));
54  return rpmiobLink(iob);
55 }
56 
58 {
59 assert(iob != NULL);
60  iob->b[0] = '\0';
61  iob->blen = 0;
62 if (_rpmiob_debug)
63 fprintf(stderr, "<-- %s(%p) %p[%u:%u]\n", __FUNCTION__, iob, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated);
64  return iob;
65 }
66 
68 {
69 
70 assert(iob != NULL);
71  while (iob->blen > 0 && xisspace((int)iob->b[iob->blen-1]))
72  iob->b[--iob->blen] = (rpmuint8_t) '\0';
73 if (_rpmiob_debug)
74 fprintf(stderr, "<-- %s(%p) %p[%u:%u]\n", __FUNCTION__, iob, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated);
75  return iob;
76 }
77 
78 rpmiob rpmiobAppend(rpmiob iob, const char * s, size_t nl)
79 {
80  size_t ns = strlen(s);
81  rpmuint8_t * tail;
82 
83  if (nl > 0) ns++;
84 
85 assert(iob != NULL);
86  if ((iob->blen + ns) > iob->allocated) {
87  iob->allocated += ((ns+_rpmiob_chunk-1)/_rpmiob_chunk) * _rpmiob_chunk;
88  iob->b = (rpmuint8_t *) xrealloc(iob->b, iob->allocated+1);
89  }
90 
91  tail = iob->b + iob->blen;
92  tail = (rpmuint8_t *) stpcpy((char *)tail, s);
93  if (nl > 0) {
94  *tail++ = (rpmuint8_t) '\n';
95  *tail = (rpmuint8_t) '\0';
96  }
97  iob->blen += ns;
98 if (_rpmiob_debug)
99 fprintf(stderr, "<-- %s(%p,%p,%u) %p[%u:%u] \"%s\"\n", __FUNCTION__, iob, s, (unsigned)nl, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated, s);
100  return iob;
101 }
102 
104 {
105 assert(iob != NULL);
106 if (_rpmiob_debug)
107 fprintf(stderr, "<-- %s(%p) %p[%u:%u]\n", __FUNCTION__, iob, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated);
108 /*@-retalias -retexpose -usereleased @*/
109  return iob->b;
110 /*@=retalias =retexpose =usereleased @*/
111 }
112 
113 char * rpmiobStr(rpmiob iob)
114 {
115 assert(iob != NULL);
116 if (_rpmiob_debug)
117 fprintf(stderr, "<-- %s(%p) %p[%u:%u]\n===============\n%s\n===============\n", __FUNCTION__, iob, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated, iob->b);
118 /*@-retalias -retexpose -usereleased @*/
119  return (char *) iob->b;
120 /*@=retalias =retexpose =usereleased @*/
121 }
122 
123 size_t rpmiobLen(rpmiob iob)
124 {
125 if (_rpmiob_debug)
126 fprintf(stderr, "<-- %s(%p) %p[%u:%u]\n", __FUNCTION__, iob, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated);
127  return (iob != NULL ? iob->blen : 0);
128 }
129 
130 int rpmiobSlurp(const char * fn, rpmiob * iobp)
131 {
132  static size_t blenmax = (128 * BUFSIZ); /* XXX 1Mb with glibc */
133  rpmuint8_t * b = NULL;
134  size_t blen = 0;
135  struct stat sb;
136  FD_t fd;
137  int rc = 0;
138  int xx;
139 
140  fd = Fopen(fn, "r.ufdio");
141  if (fd == NULL || Ferror(fd)) {
142  rc = 2;
143  goto exit;
144  }
145  sb.st_size = 0;
146  if ((xx = Fstat(fd, &sb)) < 0 || sb.st_size == 0)
147  sb.st_size = blenmax;
148 #if defined(__linux__)
149  /* XXX st->st_size = 0 for /proc files on linux, see stat(2). */
150  /* XXX glibc mmap'd libio no workie for /proc files on linux?!? */
151  if (sb.st_size == 0 && !strncmp(fn, "/proc/", sizeof("/proc/")-1)) {
152  blen = blenmax;
153  b = (rpmuint8_t *) xmalloc(blen+1);
154  b[0] = (rpmuint8_t) '\0';
155 
156  xx = read(Fileno(fd), b, blen);
157  blen = (size_t) (xx >= 0 ? xx : 0);
158  } else
159 #endif
160  {
161  blen = sb.st_size;
162  b = (rpmuint8_t *) xmalloc(blen+1);
163  b[0] = (rpmuint8_t) '\0';
164 
165  blen = Fread(b, sizeof(*b), blen, fd);
166  if (Ferror(fd)) {
167  rc = 1;
168  goto exit;
169  }
170  }
171  if (blen < (size_t)sb.st_size)
172  b = (rpmuint8_t *) xrealloc(b, blen+1);
173  b[blen] = (rpmuint8_t) '\0';
174 
175 exit:
176  if (fd != NULL) (void) Fclose(fd);
177 
178  if (rc == 0) {
179  if (iobp != NULL) {
180  /* XXX use rpmiobNew() if/when lazy iop->b alloc is implemented. */
181  rpmiob iob = rpmiobGetPool(_rpmiobPool);
182  iob->b = b;
183  iob->blen = blen;
184  iob->allocated = blen;
185  *iobp = iob;
186  }
187  } else {
188  if (iobp)
189  *iobp = NULL;
190  b = _free(b);
191  }
192 
193  return rc;
194 }
rpmiob rpmiobRTrim(rpmiob iob)
Trim trailing white space.
Definition: rpmiob.c:67
int _rpmiob_debug
Definition: rpmiob.c:14
rpmuint8_t * rpmiobBuf(rpmiob iob)
Return I/O buffer.
Definition: rpmiob.c:103
static void rpmiobFini(void *_iob)
Definition: rpmiob.c:16
size_t _rpmiob_chunk
Definition: rpmiob.c:11
size_t rpmiobLen(rpmiob iob)
Return I/O buffer len.
Definition: rpmiob.c:123
FD_t Fopen(const char *path, const char *_fmode)
fopen(3) clone.
Definition: rpmio.c:2833
void * pool
Definition: rpmiotypes.h:43
rpmiob rpmiobAppend(rpmiob iob, const char *s, size_t nl)
Append string to I/O buffer.
Definition: rpmiob.c:78
int rpmiobSlurp(const char *fn, rpmiob *iobp)
Definition: rpmiob.c:130
int Fstat(FD_t fd, struct stat *st)
fstat(2) clone.
Definition: rpmrpc.c:1441
void * xcalloc(size_t nmemb, size_t size)
Definition: rpmmalloc.c:301
rpmioItem rpmioGetPool(rpmioPool pool, size_t size)
Get unused item from pool, or alloc a new item.
Definition: rpmmalloc.c:221
unsigned char rpmuint8_t
Private int typedefs to avoid C99 portability issues.
Definition: rpmiotypes.h:23
static int xisspace(int c)
Definition: rpmiotypes.h:446
The FD_t File Handle data structure.
size_t Fread(void *buf, size_t size, size_t nmemb, FD_t fd)
fread(3) clone.
Definition: rpmio.c:2412
rpmiob rpmiobLink(rpmiob iob)
Reference a I/O buffer instance.
int Fclose(FD_t fd)
fclose(3) clone.
Definition: rpmio.c:2534
rpmiob rpmiobNew(size_t len)
Create an I/O buffer.
Definition: rpmiob.c:44
int Ferror(FD_t fd)
ferror(3) clone.
Definition: rpmio.c:2944
char * rpmiobStr(rpmiob iob)
Return I/O buffer (as string).
Definition: rpmiob.c:113
rpmioPool rpmioNewPool(const char *name, size_t size, int limit, int flags, char *(*dbg)(void *item), void(*init)(void *item), void(*fini)(void *item))
Create a memory pool.
Definition: rpmmalloc.c:110
char * stpcpy(char *dest, const char *src)
static void * _free(const void *p)
Wrapper to free(3), hides const compilation noise, permit NULL, return NULL.
Definition: rpmiotypes.h:647
struct rpmiob_s * rpmiob
Definition: rpmiotypes.h:57
rpmiob rpmiobEmpty(rpmiob iob)
Empty an I/O buffer.
Definition: rpmiob.c:57
int Fileno(FD_t fd)
fileno(3) clone.
Definition: rpmio.c:2991
static rpmiob rpmiobGetPool(rpmioPool pool)
Definition: rpmiob.c:30
#define xmalloc
Definition: system.h:33
rpmioPool _rpmiobPool
Definition: rpmiob.c:28
#define xrealloc
Definition: system.h:36