rpm 5.2.1

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

- File List
- Globals

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