rpm 5.3.7

rpmio/rpmiob.c

Go to the documentation of this file.
00001 
00004 #include "system.h"
00005 #define _RPMIOB_INTERNAL
00006 #include <rpmiotypes.h>
00007 #include <rpmio.h>
00008 #include "debug.h"
00009 
00010 /*@unchecked@*/
00011 size_t _rpmiob_chunk = 1024;
00012 
00013 /*@unchecked@*/
00014 int _rpmiob_debug;
00015 
00016 static void rpmiobFini(void * _iob)
00017 {
00018     rpmiob iob = _iob;
00019 
00020 if (_rpmiob_debug)
00021 fprintf(stderr, "--> %s(%p) %p[%u:%u]\n", __FUNCTION__, iob, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated);
00022     iob->b = _free(iob->b);
00023     iob->blen = 0;
00024     iob->allocated = 0;
00025 }
00026 
00027 /*@unchecked@*/ /*@only@*/ /*@null@*/
00028 rpmioPool _rpmiobPool;
00029 
00030 static rpmiob rpmiobGetPool(/*@null@*/ rpmioPool pool)
00031         /*@globals _rpmiobPool, fileSystem @*/
00032         /*@modifies pool, _rpmiobPool, fileSystem @*/
00033 {
00034     rpmiob iob;
00035 
00036     if (_rpmiobPool == NULL) {
00037         _rpmiobPool = rpmioNewPool("iob", sizeof(*iob), -1, _rpmiob_debug,
00038                         NULL, NULL, rpmiobFini);
00039         pool = _rpmiobPool;
00040     }
00041     return (rpmiob) rpmioGetPool(pool, sizeof(*iob));
00042 }
00043 
00044 rpmiob rpmiobNew(size_t len)
00045 {
00046     rpmiob iob = rpmiobGetPool(_rpmiobPool);
00047 if (_rpmiob_debug)
00048 fprintf(stderr, "--> %s(%p) %p[%u:%u]\n", __FUNCTION__, iob, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated);
00049     if (len == 0)
00050         len = _rpmiob_chunk;
00051     iob->allocated = len;
00052     iob->blen = 0;
00053     iob->b = xcalloc(iob->allocated+1, sizeof(*iob->b));
00054     return rpmiobLink(iob);
00055 }
00056 
00057 rpmiob rpmiobEmpty(rpmiob iob)
00058 {
00059 assert(iob != NULL);
00060     iob->b[0] = '\0';
00061     iob->blen = 0;
00062 if (_rpmiob_debug)
00063 fprintf(stderr, "<-- %s(%p) %p[%u:%u]\n", __FUNCTION__, iob, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated);
00064     return iob;
00065 }
00066 
00067 rpmiob rpmiobRTrim(rpmiob iob)
00068 {
00069     
00070 assert(iob != NULL);
00071     while (iob->blen > 0 && xisspace((int)iob->b[iob->blen-1]))
00072         iob->b[--iob->blen] = (rpmuint8_t) '\0';
00073 if (_rpmiob_debug)
00074 fprintf(stderr, "<-- %s(%p) %p[%u:%u]\n", __FUNCTION__, iob, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated);
00075     return iob;
00076 }
00077 
00078 rpmiob rpmiobAppend(rpmiob iob, const char * s, size_t nl)
00079 {
00080     size_t ns = strlen(s);
00081     rpmuint8_t * tail;
00082 
00083     if (nl > 0) ns++;
00084 
00085 assert(iob != NULL);
00086     if ((iob->blen + ns) > iob->allocated) {
00087         iob->allocated += ((ns+_rpmiob_chunk-1)/_rpmiob_chunk) * _rpmiob_chunk;
00088         iob->b = xrealloc(iob->b, iob->allocated+1);
00089     }
00090 
00091     tail = iob->b + iob->blen;
00092     tail = (rpmuint8_t *) stpcpy((char *)tail, s);
00093     if (nl > 0) {
00094         *tail++ = (rpmuint8_t) '\n';
00095         *tail = (rpmuint8_t) '\0';
00096     }
00097     iob->blen += ns;
00098 if (_rpmiob_debug)
00099 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);
00100     return iob;
00101 }
00102 
00103 rpmuint8_t * rpmiobBuf(rpmiob iob)
00104 {
00105 assert(iob != NULL);
00106 if (_rpmiob_debug)
00107 fprintf(stderr, "<-- %s(%p) %p[%u:%u]\n", __FUNCTION__, iob, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated);
00108 /*@-retalias -retexpose -usereleased @*/
00109     return iob->b;
00110 /*@=retalias =retexpose =usereleased @*/
00111 }
00112 
00113 char * rpmiobStr(rpmiob iob)
00114 {
00115 assert(iob != NULL);
00116 if (_rpmiob_debug)
00117 fprintf(stderr, "<-- %s(%p) %p[%u:%u]\n===============\n%s\n===============\n", __FUNCTION__, iob, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated, iob->b);
00118 /*@-retalias -retexpose -usereleased @*/
00119     return (char *) iob->b;
00120 /*@=retalias =retexpose =usereleased @*/
00121 }
00122 
00123 size_t rpmiobLen(rpmiob iob)
00124 {
00125 if (_rpmiob_debug)
00126 fprintf(stderr, "<-- %s(%p) %p[%u:%u]\n", __FUNCTION__, iob, iob->b, (unsigned)iob->blen, (unsigned)iob->allocated);
00127     return (iob != NULL ? iob->blen : 0);
00128 }
00129 
00130 int rpmiobSlurp(const char * fn, rpmiob * iobp)
00131 {
00132     static size_t blenmax = (128 * BUFSIZ);     /* XXX 1Mb with glibc */
00133     rpmuint8_t * b = NULL;
00134     size_t blen = 0;
00135     struct stat sb;
00136     FD_t fd;
00137     int rc = 0;
00138     int xx;
00139 
00140     fd = Fopen(fn, "r.ufdio");
00141     if (fd == NULL || Ferror(fd)) {
00142         rc = 2;
00143         goto exit;
00144     }
00145     sb.st_size = 0;
00146     if ((xx = Fstat(fd, &sb)) < 0 || sb.st_size == 0)
00147         sb.st_size = blenmax;
00148 #if defined(__linux__)
00149     /* XXX st->st_size = 0 for /proc files on linux, see stat(2). */
00150     /* XXX glibc mmap'd libio no workie for /proc files on linux?!? */
00151     if (sb.st_size == 0 && !strncmp(fn, "/proc/", sizeof("/proc/")-1)) {
00152         blen = blenmax;
00153         b = xmalloc(blen+1);
00154         b[0] = (rpmuint8_t) '\0';
00155 
00156         xx = read(Fileno(fd), b, blen);
00157         blen = (size_t) (xx >= 0 ? xx : 0); 
00158     } else
00159 #endif
00160     {
00161         blen = sb.st_size;
00162         b = xmalloc(blen+1);
00163         b[0] = (rpmuint8_t) '\0';
00164 
00165         blen = Fread(b, sizeof(*b), blen, fd);
00166         if (Ferror(fd)) {
00167             rc = 1;
00168             goto exit;
00169         }
00170     }
00171     if (blen < (size_t)sb.st_size)
00172         b = xrealloc(b, blen+1);
00173     b[blen] = (rpmuint8_t) '\0';
00174 
00175 exit:
00176     if (fd != NULL) (void) Fclose(fd);
00177 
00178     if (rc == 0) {
00179         if (iobp != NULL) {
00180             /* XXX use rpmiobNew() if/when lazy iop->b alloc is implemented. */
00181             rpmiob iob = rpmiobGetPool(_rpmiobPool);
00182             iob->b = b;
00183             iob->blen = blen;
00184             iob->allocated = blen;
00185             *iobp = iob;
00186         }
00187     } else {
00188         if (iobp)
00189             *iobp = NULL;
00190         b = _free(b);
00191     }
00192 
00193     return rc;
00194 }