int Fclose(FD_t fd) { int rc = 0, ec = 0; if (fd == NULL) return -1; fd = fdLink(fd); fdstat_enter(fd, FDSTAT_CLOSE); while (fd->nfps >= 0) { fdio_close_function_t _close = FDIOVEC(fd, close); rc = _close ? _close(fd) : -2; if (fd->nfps == 0) break; if (ec == 0 && rc) ec = rc; fdPop(fd); } fdstat_exit(fd, FDSTAT_CLOSE, rc); DBGIO(fd, (stderr, "==>\tFclose(%p) rc %lx %s\n", (fd ? fd : NULL), (unsigned long)rc, fdbg(fd))); fdFree(fd); return ec; }
static int xzdClose( /*@only@*/ void * cookie) /*@globals fileSystem, internalState @*/ /*@modifies fileSystem, internalState @*/ { FD_t fd = c2f(cookie); XZFILE *xzfile; const char * errcookie; int rc; xzfile = xzdFileno(fd); if (xzfile == NULL) return -2; errcookie = strerror(ferror(xzfile->fp)); fdstat_enter(fd, FDSTAT_CLOSE); /*@-dependenttrans@*/ rc = xzclose(xzfile); /*@=dependenttrans@*/ fdstat_exit(fd, FDSTAT_CLOSE, rc); if (fd && rc == -1) fd->errcookie = errcookie; DBGIO(fd, (stderr, "==>\txzdClose(%p) rc %lx %s\n", cookie, (unsigned long)rc, fdbg(fd))); if (_rpmio_debug || rpmIsDebug()) fdstat_print(fd, "XZDIO", stderr); /*@-branchstate@*/ if (rc == 0) fd = fdFree(fd, "open (xzdClose)"); /*@=branchstate@*/ return rc; }
/*@-mustmod@*/ /* LCL: *buf is modified */ static ssize_t xzdRead(void * cookie, /*@out@*/ char * buf, size_t count) /*@globals fileSystem, internalState @*/ /*@modifies *buf, fileSystem, internalState @*/ { FD_t fd = c2f(cookie); XZFILE *xzfile; ssize_t rc = -1; assert(fd != NULL); if (fd->bytesRemain == 0) return 0; /* XXX simulate EOF */ xzfile = xzdFileno(fd); assert(xzfile != NULL); fdstat_enter(fd, FDSTAT_READ); /*@-compdef@*/ rc = xzread(xzfile, buf, count); /*@=compdef@*/ DBGIO(fd, (stderr, "==>\txzdRead(%p,%p,%u) rc %lx %s\n", cookie, buf, (unsigned)count, (unsigned long)rc, fdbg(fd))); if (rc == -1) { fd->errcookie = "Lzma: decoding error"; } else if (rc >= 0) { fdstat_exit(fd, FDSTAT_READ, rc); /*@-compdef@*/ if (fd->ndigests > 0 && rc > 0) fdUpdateDigests(fd, (void *)buf, rc); /*@=compdef@*/ } return rc; }
int ufdCopy(FD_t sfd, FD_t tfd) { char buf[BUFSIZ]; int itemsRead; int itemsCopied = 0; int rc = 0; while (1) { rc = Fread(buf, sizeof(buf[0]), sizeof(buf), sfd); if (rc < 0) break; else if (rc == 0) { rc = itemsCopied; break; } itemsRead = rc; rc = Fwrite(buf, sizeof(buf[0]), itemsRead, tfd); if (rc < 0) break; if (rc != itemsRead) { rc = -1; break; } itemsCopied += itemsRead; } DBGIO(sfd, (stderr, "++ copied %d bytes\n", itemsCopied)); return rc; }
int Ferror(FD_t fd) { int i, rc = 0; if (fd == NULL) return -1; for (i = fd->nfps; rc == 0 && i >= 0; i--) { FDSTACK_t * fps = &fd->fps[i]; int ec; if (fps->io == gzdio) { ec = (fd->syserrno || fd->errcookie != NULL) ? -1 : 0; i--; /* XXX fdio under gzdio always has fdno == -1 */ #if HAVE_BZLIB_H } else if (fps->io == bzdio) { ec = (fd->syserrno || fd->errcookie != NULL) ? -1 : 0; i--; /* XXX fdio under bzdio always has fdno == -1 */ #endif #if HAVE_LZMA_H } else if (fps->io == xzdio || fps->io == lzdio) { ec = (fd->syserrno || fd->errcookie != NULL) ? -1 : 0; i--; /* XXX fdio under xzdio/lzdio always has fdno == -1 */ #endif } else { /* XXX need to check ufdio/gzdio/bzdio/fdio errors correctly. */ ec = (fdFileno(fd) < 0 ? -1 : 0); } if (rc == 0 && ec) rc = ec; } DBGIO(fd, (stderr, "==> Ferror(%p) rc %d %s\n", fd, rc, fdbg(fd))); return rc; }
FD_t Fdopen(FD_t ofd, const char *fmode) { char stdio[20], other[20], zstdio[20]; const char *end = NULL; FDIO_t iof = NULL; FD_t fd = ofd; if (_rpmio_debug) fprintf(stderr, "*** Fdopen(%p,%s) %s\n", fd, fmode, fdbg(fd)); if (fd == NULL || fmode == NULL) return NULL; cvtfmode(fmode, stdio, sizeof(stdio), other, sizeof(other), &end, NULL); if (stdio[0] == '\0') return NULL; zstdio[0] = '\0'; strncat(zstdio, stdio, sizeof(zstdio) - strlen(zstdio)); strncat(zstdio, other, sizeof(zstdio) - strlen(zstdio)); if (end == NULL && other[0] == '\0') return fd; if (end && *end) { if (rstreq(end, "fdio")) { iof = fdio; } else if (rstreq(end, "gzdio") || rstreq(end, "gzip")) { iof = gzdio; fd = gzdFdopen(fd, zstdio); #if HAVE_BZLIB_H } else if (rstreq(end, "bzdio") || rstreq(end, "bzip2")) { iof = bzdio; fd = bzdFdopen(fd, zstdio); #endif #if HAVE_LZMA_H } else if (rstreq(end, "xzdio") || rstreq(end, "xz")) { iof = xzdio; fd = xzdFdopen(fd, zstdio); } else if (rstreq(end, "lzdio") || rstreq(end, "lzma")) { iof = lzdio; fd = lzdFdopen(fd, zstdio); #endif } else if (rstreq(end, "ufdio")) { iof = ufdio; } } else if (other[0] != '\0') { for (end = other; *end && strchr("0123456789fh", *end); end++) {}; if (*end == '\0') { iof = gzdio; fd = gzdFdopen(fd, zstdio); } } if (iof == NULL) return fd; DBGIO(fd, (stderr, "==> Fdopen(%p,\"%s\") returns fd %p %s\n", ofd, fmode, (fd ? fd : NULL), fdbg(fd))); return fd; }
FD_t Fopen(const char *path, const char *fmode) { char stdio[20], other[20]; const char *end = NULL; mode_t perms = 0666; int flags = 0; FD_t fd; if (path == NULL || fmode == NULL) return NULL; stdio[0] = '\0'; cvtfmode(fmode, stdio, sizeof(stdio), other, sizeof(other), &end, &flags); if (stdio[0] == '\0') return NULL; if (end == NULL || rstreq(end, "fdio")) { if (_rpmio_debug) fprintf(stderr, "*** Fopen fdio path %s fmode %s\n", path, fmode); fd = fdOpen(path, flags, perms); if (fdFileno(fd) < 0) { if (fd) (void) fdClose(fd); return NULL; } } else { /* XXX gzdio and bzdio here too */ switch (urlIsURL(path)) { case URL_IS_HTTPS: case URL_IS_HTTP: case URL_IS_HKP: case URL_IS_PATH: case URL_IS_DASH: case URL_IS_FTP: case URL_IS_UNKNOWN: if (_rpmio_debug) fprintf(stderr, "*** Fopen ufdio path %s fmode %s\n", path, fmode); fd = ufdOpen(path, flags, perms); if (fd == NULL || !(fdFileno(fd) >= 0)) return fd; break; default: if (_rpmio_debug) fprintf(stderr, "*** Fopen WTFO path %s fmode %s\n", path, fmode); return NULL; break; } } if (fd) fd = Fdopen(fd, fmode); DBGIO(fd, (stderr, "==>\tFopen(\"%s\",%x,0%o) %s\n", path, (unsigned)flags, (unsigned)perms, fdbg(fd))); return fd; }
FD_t fdDup(int fdno) { FD_t fd; int nfdno; if ((nfdno = dup(fdno)) < 0) return NULL; fd = fdNew(nfdno, NULL); DBGIO(fd, (stderr, "==> fdDup(%d) fd %p %s\n", fdno, (fd ? fd : NULL), fdbg(fd))); return fd; }
int Fileno(FD_t fd) { int i, rc = -1; if (fd == NULL) return -1; for (i = fd->nfps ; rc == -1 && i >= 0; i--) { rc = fd->fps[i].fdno; } DBGIO(fd, (stderr, "==> Fileno(%p) rc %d %s\n", (fd ? fd : NULL), rc, fdbg(fd))); return rc; }
int Fseek(FD_t fd, off_t offset, int whence) { int rc = -1; if (fd != NULL) { fdio_seek_function_t _seek = FDIOVEC(fd, seek); fdstat_enter(fd, FDSTAT_SEEK); rc = (_seek ? _seek(fd, offset, whence) : -2); fdstat_exit(fd, FDSTAT_SEEK, rc); } DBGIO(fd, (stderr, "==>\tFseek(%p,%ld,%d) rc %lx %s\n", fd, (long)offset, whence, (unsigned long)rc, fdbg(fd))); return rc; }
ssize_t Fwrite(const void *buf, size_t size, size_t nmemb, FD_t fd) { ssize_t rc = -1; if (fd != NULL) { fdio_write_function_t _write = FDIOVEC(fd, write); fdstat_enter(fd, FDSTAT_WRITE); rc = (_write ? _write(fd, buf, size * nmemb) : -2); fdstat_exit(fd, FDSTAT_WRITE, rc); if (fd->digests && rc > 0) fdUpdateDigests(fd, buf, rc); } DBGIO(fd, (stderr, "==>\tFwrite(%p,%p,%ld) rc %ld %s\n", fd, buf, (long)size * nmemb, (long)rc, fdbg(fd))); return rc; }
ssize_t Fread(void *buf, size_t size, size_t nmemb, FD_t fd) { ssize_t rc = -1; if (fd != NULL) { fdio_read_function_t _read = FDIOVEC(fd, read); fdstat_enter(fd, FDSTAT_READ); rc = (_read ? (*_read) (fd, buf, size * nmemb) : -2); fdstat_exit(fd, FDSTAT_READ, rc); if (fd->digests && rc > 0) fdUpdateDigests(fd, buf, rc); } DBGIO(fd, (stderr, "==>\tFread(%p,%p,%ld) rc %ld %s\n", fd, buf, (long)size * nmemb, (long)rc, fdbg(fd))); return rc; }
/*@-globuse@*/ static ssize_t xzdWrite(void * cookie, const char * buf, size_t count) /*@globals fileSystem, internalState @*/ /*@modifies fileSystem, internalState @*/ { FD_t fd = c2f(cookie); XZFILE *xzfile; ssize_t rc = 0; if (fd == NULL || fd->bytesRemain == 0) return 0; /* XXX simulate EOF */ if (fd->ndigests > 0 && count > 0) fdUpdateDigests(fd, (void *)buf, count); xzfile = xzdFileno(fd); fdstat_enter(fd, FDSTAT_WRITE); rc = xzwrite(xzfile, (void *)buf, count); DBGIO(fd, (stderr, "==>\txzdWrite(%p,%p,%u) rc %lx %s\n", cookie, buf, (unsigned)count, (unsigned long)rc, fdbg(fd))); if (rc < 0) { fd->errcookie = "Lzma: encoding error"; } else if (rc > 0) { fdstat_exit(fd, FDSTAT_WRITE, rc); } return rc; }