RPM Package Manager, CVS Repository
  http://rpm5.org/cvs/
  ____________________________________________________________________________

  Server: rpm5.org                         Name:   Jeff Johnson
  Root:   /v/rpm/cvs                       Email:  j...@rpm5.org
  Module: rpm                              Date:   19-Apr-2017 22:42:15
  Branch: rpm-5_4                          Handle: 2017041920421401

  Modified files:           (Branch: rpm-5_4)
    rpm                     CHANGES configure.ac
    rpm/lib                 fsm.c psm.c
    rpm/rpmio               iosm.c librpmio.vers rpmio.c rpmio.h
                            rpmio_internal.h

  Log:
    - rpmio: add fgetxattr+flistxattr+fremovexattr+fsetxattr
    - rpmio: add getrandom+getentropy
    - rpmio: add syncfs+ftruncate+futimens

  Summary:
    Revision    Changes     Path
    1.3501.2.534+3  -0      rpm/CHANGES
    2.472.2.161 +12 -5      rpm/configure.ac
    2.193.4.15  +1  -1      rpm/lib/fsm.c
    2.399.2.23  +2  -2      rpm/lib/psm.c
    1.43.2.12   +2  -2      rpm/rpmio/iosm.c
    2.199.2.68  +6  -0      rpm/rpmio/librpmio.vers
    1.230.2.42  +277 -83    rpm/rpmio/rpmio.c
    1.97.2.12   +33 -1      rpm/rpmio/rpmio.h
    2.127.2.11  +115 -48    rpm/rpmio/rpmio_internal.h
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/CHANGES
  ============================================================================
  $ cvs diff -u -r1.3501.2.533 -r1.3501.2.534 CHANGES
  --- rpm/CHANGES       18 Apr 2017 11:14:41 -0000      1.3501.2.533
  +++ rpm/CHANGES       19 Apr 2017 20:42:14 -0000      1.3501.2.534
  @@ -1,4 +1,7 @@
   5.4.17 -> 5.4.18:
  +    - jbj: rpmio: add fgetxattr+flistxattr+fremovexattr+fsetxattr
  +    - jbj: rpmio: add getrandom+getentropy
  +    - jbj: rpmio: add syncfs+ftruncate+futimens
       - jbj: rpmio: add fchdir+fchmod+fchown+fincore+flock+futimes.
       - jbj: rpmio: add fallocate+fdatasync+fadvise+fsync.
       - jbj: install: use clock_gettime/gettimeofday/time for *.rpm timestamps.
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/configure.ac
  ============================================================================
  $ cvs diff -u -r2.472.2.160 -r2.472.2.161 configure.ac
  --- rpm/configure.ac  17 Apr 2017 18:19:07 -0000      2.472.2.160
  +++ rpm/configure.ac  19 Apr 2017 20:42:14 -0000      2.472.2.161
  @@ -1367,6 +1367,11 @@
   AC_CHECK_HEADERS(error.h)
   AC_CHECK_FUNCS(error)
   
  +dnl # linux getrandom(2) and OpenBSD getentropy(2) syscalls
  +AC_CHECK_HEADERS(sys/syscall.h linux/random.h)
  +AC_CHECK_FUNCS(getrandom)
  +AC_CHECK_FUNCS(getentropy)
  +
   dnl # POSIX search(3) API
   AC_CHECK_HEADERS(search.h)
   AC_CHECK_FUNC(insque, [], [ AC_CHECK_LIB(compat, insque) ])
  @@ -1413,7 +1418,7 @@
   dnl # platform-hack: The Mac OS X (aka Darwin) ld(1) uses a strange
   dnl # non-standard Unix library search path order. This causes great
   dnl # problems when linking against the third-party libraries.
  -dnl # Force ld(1) to stick standard Unix search path order.
  +dnl # Force ld(1) to stick to standard Unix search path order.
   case "$host" in
       *-*-darwin* ) LDFLAGS="$LDFLAGS -Wl,-search_paths_first" ;;
   esac
  @@ -1574,23 +1579,25 @@
   AC_CHECK_FUNCS([dnl
       asprintf atexit basename chflags clearenv clock_gettime clone dnl
       confstr dup2 endgrent endpwent fallocate fchdir fchflags dnl
  -    fchmod fdatasync floor ftok fsync ftruncate getaddrinfo dnl
  +    fchmod fdatasync fgetxattr flistxattr floor fremovexattr dnl
  +    fsetxattr fsync ftok ftruncate getaddrinfo dnl
       getattrlist getcwd getdelim gethostbyaddr gethostbyname dnl
       gethostname getline getmode getmntent getmntinfo dnl
       getnameinfo getpass getpassphrase gettimeofday getwd dnl
       getxattr hasmntopt iconv inet_aton inet_ntoa isascii dnl
       lchflags lchmod lchown lgetxattr localtime_r lsetxattr dnl
       lutimes madvise mbrlen memchr mempcpy memset mincore mkdir dnl
  -    mkdtemp mkfifo mkstemp msync mtrace munmap nl_langinfo dnl
  +    mkdtemp mkfifo mkstemp mremap msync mtrace munmap nl_langinfo dnl
       pathconf posix_fadvise posix_fallocate posix_madvise posix_memalign dnl
       posix_memalign posix_mem_offset posix_typed_mem_open dnl
  -    pow prctl putenv realpath regcomp rmdir rpmatch __secure_getenv 
secure_getenv dnl
  +    pow prctl putenv realpath regcomp rmdir rpmatch dnl
  +    __secure_getenv secure_getenv dnl
       select sendfile setattrlist setenv setmode setns setxattr dnl
       sigaction sigaddset sigdelset sigemptyset sighold sigpause dnl
       sigprocmask sigrelse sigsuspend setlocale socket splice sqrt dnl
       stpcpy stpncpy strcspn strdup strerror strmode dnl
       strncasecmp strndup strpbrk strspn strstr strtol strtoul strtoull dnl
  -    tee tzset uname unshare vmsplice dnl
  +    syncfs tee tzset uname unshare vmsplice dnl
   ])
   
   dnl # specific additional tests needed to replace Berkeley-DB db_config.h 
with RPM config.h
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/lib/fsm.c
  ============================================================================
  $ cvs diff -u -r2.193.4.14 -r2.193.4.15 fsm.c
  --- rpm/lib/fsm.c     17 Apr 2017 20:10:37 -0000      2.193.4.14
  +++ rpm/lib/fsm.c     19 Apr 2017 20:42:15 -0000      2.193.4.15
  @@ -685,7 +685,7 @@
        rc = fsmUNSAFE(fsm, IOSM_DESTROY);
   
       /* XXX eliminate when ts->stats is printed. */
  -    (void) rpmswAdd(rpmtsOp(fsmGetTs(fsm), RPMTS_OP_DIGEST), 
&fsm->stats->ops[FDSTAT_DIGEST]);
  +    (void) rpmswAdd(rpmtsOp(fsmGetTs(fsm), RPMTS_OP_DIGEST), 
&fsm->stats->ops[FDSTAT_FDIGEST]);
       FDSTAT_t stats = (FDSTAT_t) rpmtsStats(fsmGetTs(fsm));
       if (stats)
       for (int opx = 0; opx < FDSTAT_MAX; opx++)
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/lib/psm.c
  ============================================================================
  $ cvs diff -u -r2.399.2.22 -r2.399.2.23 psm.c
  --- rpm/lib/psm.c     6 Jul 2016 13:19:58 -0000       2.399.2.22
  +++ rpm/lib/psm.c     19 Apr 2017 20:42:15 -0000      2.399.2.23
  @@ -2667,7 +2667,7 @@
            (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_UNCOMPRESS),
                        fdstat_op(psm->cfd, FDSTAT_READ));
            (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DIGEST),
  -                     fdstat_op(psm->cfd, FDSTAT_DIGEST));
  +                     fdstat_op(psm->cfd, FDSTAT_FDIGEST));
            xx = fsmTeardown(fi->fsm);
   
            saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */
  @@ -2766,7 +2766,7 @@
            (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_COMPRESS),
                        fdstat_op(psm->cfd, FDSTAT_WRITE));
            (void) rpmswAdd(rpmtsOp(ts, RPMTS_OP_DIGEST),
  -                     fdstat_op(psm->cfd, FDSTAT_DIGEST));
  +                     fdstat_op(psm->cfd, FDSTAT_FDIGEST));
            xx = fsmTeardown(fi->fsm);
   
            saveerrno = errno; /* XXX FIXME: Fclose with libio destroys errno */
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/iosm.c
  ============================================================================
  $ cvs diff -u -r1.43.2.11 -r1.43.2.12 iosm.c
  --- rpm/rpmio/iosm.c  17 Apr 2017 19:25:27 -0000      1.43.2.11
  +++ rpm/rpmio/iosm.c  19 Apr 2017 20:42:15 -0000      1.43.2.12
  @@ -760,7 +760,7 @@
   #if defined(_USE_RPMTS)
        /* XXX eliminate when ts->stats is printed. */
        (void) rpmswAdd(rpmtsOp(iosmGetTs(iosm), RPMTS_OP_DIGEST),
  -                     &iosm->stats->ops[FDSTAT_DIGEST]);
  +                     &iosm->stats->ops[FDSTAT_FDIGEST]);
        FDSTAT_t stats = (FDSTAT_t) rpmtsStats(iosmGetTs(iosm));
        if (stats)
        for (int opx = 0; opx < FDSTAT_MAX; opx++)
  @@ -2552,7 +2552,7 @@
        iosm->rfdno = -1;                       /* XXX */
        break;
       case IOSM_WOPEN:
  -     iosm->wfd = Fopen(iosm->path, "wb+e.fdio");
  +     iosm->wfd = Fopen(iosm->path, "wb+eIONFP?.fdio");
        if (iosm->wfd == NULL || Ferror(iosm->wfd)) {
            (void) iosmNext(iosm, IOSM_WCLOSE);
            rc = IOSMERR_OPEN_FAILED;
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/librpmio.vers
  ============================================================================
  $ cvs diff -u -r2.199.2.67 -r2.199.2.68 librpmio.vers
  --- rpm/rpmio/librpmio.vers   18 Apr 2017 11:14:42 -0000      2.199.2.67
  +++ rpm/rpmio/librpmio.vers   19 Apr 2017 20:42:15 -0000      2.199.2.68
  @@ -121,25 +121,30 @@
       Fflush;
       _Fflush;
       Fgetpos;
  +    Fgetxattr;
       Fileno;
       _Fileno;
       _fini;
       Fincore;
  +    Flistxattr;
       Flock;
       Fopen;
       _Fopen;
       fpio;
       Fread;
       _Fread;
  +    Fremovexattr;
       Fseek;
       _Fseek;
       Fsetpos;
  +    Fsetxattr;
       Fstat;
       _Fstat;
       Fstrerror;
       _Fstrerror;
       Fsync;
       Ftell;
  +    Ftruncate;
       ftpCmd;
       _ftp_debug;
       ftpOpen;
  @@ -153,6 +158,7 @@
       Fts_read;
       Fts_set;
       Futimes;
  +    Futimens;
       Fwrite;
       _Fwrite;
       get_date;
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmio.c
  ============================================================================
  $ cvs diff -u -r1.230.2.41 -r1.230.2.42 rpmio.c
  --- rpm/rpmio/rpmio.c 18 Apr 2017 11:14:42 -0000      1.230.2.41
  +++ rpm/rpmio/rpmio.c 19 Apr 2017 20:42:15 -0000      1.230.2.42
  @@ -391,13 +391,14 @@
   
   static ssize_t fdRead(void * cookie, char * buf, size_t count)
   {
  +    static const int opx = FDSTAT_READ;
       FD_t fd = c2f(cookie);
       ssize_t rc;
   
       /* XXX handle fd->req similar to ufdRead() */
       if (fd->bytesRemain == 0) return 0;      /* XXX simulate EOF */
   
  -    fdstat_enter(fd, FDSTAT_READ);
  +    fdstat_enter(fd, opx);
       /* HACK: flimsy wiring for davRead */
       if (fd->req != NULL) {
   #ifdef WITH_NEON
  @@ -420,7 +421,7 @@
   #endif
       } else
        rc = read(fdFileno(fd), buf, (count > (size_t)fd->bytesRemain ? 
(size_t)fd->bytesRemain : count));
  -    fdstat_exit(fd, FDSTAT_READ, rc);
  +    fdstat_exit(fd, opx, rc);
   
       if (fd->ndigests > 0 && rc > 0) fdUpdateDigests(fd, (const unsigned char 
*)buf, rc);
   
  @@ -431,6 +432,7 @@
   
   static ssize_t fdWrite(void * cookie, const char * buf, size_t count)
   {
  +    static const int opx = FDSTAT_WRITE;
       FD_t fd = c2f(cookie);
       int fdno = fdFileno(fd);
       ssize_t rc;
  @@ -441,7 +443,7 @@
   
       if (count == 0) return 0;
   
  -    fdstat_enter(fd, FDSTAT_WRITE);
  +    fdstat_enter(fd, opx);
       /* HACK: flimsy wiring for davWrite */
       if (fd->req != NULL)
   #ifdef WITH_NEON
  @@ -454,7 +456,7 @@
   #endif
       else
        rc = write(fdno, buf, (count > (size_t)fd->bytesRemain ? 
(size_t)fd->bytesRemain : count));
  -    fdstat_exit(fd, FDSTAT_WRITE, rc);
  +    fdstat_exit(fd, opx, rc);
   
   DBGIO(fd, (stderr, "<--\tfdWrite(%p,%p,%ld) rc %ld %s\n", cookie, buf, 
(long)count, (long)rc, fdbg(fd)));
   
  @@ -463,6 +465,7 @@
   
   static int fdSeek(void * cookie, _libio_pos_t pos, int whence)
   {
  +    static const int opx = FDSTAT_SEEK;
   #ifdef USE_COOKIE_SEEK_POINTER
       _IO_off64_t p = *pos;
   #else
  @@ -472,9 +475,9 @@
       off_t rc;
   
       assert(fd->bytesRemain == -1);   /* XXX FIXME fadio only for now */
  -    fdstat_enter(fd, FDSTAT_SEEK);
  +    fdstat_enter(fd, opx);
       rc = lseek(fdFileno(fd), p, whence);
  -    fdstat_exit(fd, FDSTAT_SEEK, rc);
  +    fdstat_exit(fd, opx, rc);
   
   DBGIO(fd, (stderr, "<--\tfdSeek(%p,%ld,%d) rc %lx %s\n", cookie, (long)p, 
whence, (unsigned long)rc, fdbg(fd)));
   
  @@ -485,28 +488,39 @@
   {
       int rc = -2;
       int fdno = fdFileno(fd);
  +    int nincore = 0;
   
  -    if (fdno >= 0 && RPMFD_ISSET(fd, FSYNC)) {
  -     if (RPMFD_ISSET(fd, DEBUGIO))
  -         (void) Fincore(fd);
  -     if (RPMFD_ISSET(fd, FDATASYNC)) {
  -         rc = Fdatasync(fd);
  -         if (rc < 0 && errno != ENOSYS)      /* XXX best effort */
  -             goto exit;
  -     }
  -     if (RPMFD_ISSET(fd, FADVISE)) {
  +    if (fdno < 0) {                          /* XXX needed? */
  +     errno = EBADF;
  +     goto exit;
  +    }
  +
  +    if (RPMFD_ISSET(fd, DEBUGIO))
  +     nincore = Fincore(fd, nincore);
  +    if (RPMFD_ISSET(fd, FDATASYNC)) {
  +     rc = Fdatasync(fd);
  +     if (rc < 0 && errno != ENOSYS)          /* XXX best effort */
  +         goto exit;
  +    }
  +    if (RPMFD_ISSET(fd, FADVISE)) {
   #if defined(POSIX_FADV_DONTNEED)
  -         rc = Fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
  +     rc = Fadvise(fd, 0, 0, POSIX_FADV_DONTNEED);
   #endif  
  -         if (rc < 0 && errno != ENOSYS)      /* XXX best effort */
  -             goto exit;
  -     }
  +     if (rc < 0 && errno != ENOSYS)          /* XXX best effort */
  +         goto exit;
  +    }
  +    if (RPMFD_ISSET(fd, FSYNC)) {
        rc = Fsync(fd);
        if (rc < 0 && errno != ENOSYS)          /* XXX best effort */
            goto exit;
  -     if (RPMFD_ISSET(fd, DEBUGIO))
  -         (void) Fincore(fd);
       }
  +    if (RPMFD_ISSET(fd, SYNCFS)) {
  +     rc = Syncfs(fd);
  +     if (rc < 0 && errno != ENOSYS)          /* XXX best effort */
  +         goto exit;
  +    }
  +    if (RPMFD_ISSET(fd, DEBUGIO))
  +     nincore -= Fincore(fd, nincore);
       rc = 0;
   
   exit:
  @@ -515,6 +529,7 @@
   
   static int fdClose(void * cookie)
   {
  +    static const int opx = FDSTAT_CLOSE;
       FD_t fd;
       int fdno;
       int rc;
  @@ -523,12 +538,13 @@
       fd = c2f(cookie);
   
       /* Perform sync-on-close (if requested). */
  -    if (RPMFD_ISSET(fd, FSYNC))
  +    if (RPMFD_ISSET(fd, FSYNC)
  +     || RPMFD_ISSET(fd, SYNCFS))
        rc = fdSync(fd);
   
       fdno = fdSetFdno(fd, -1);
   
  -    fdstat_enter(fd, FDSTAT_CLOSE);
  +    fdstat_enter(fd, opx);
       /* HACK: flimsy wiring for davClose */
       if (fd->req != NULL) {
   #ifdef WITH_NEON
  @@ -538,7 +554,7 @@
   #endif
       } else
        rc = ((fdno >= 0) ? close(fdno) : -2);
  -    fdstat_exit(fd, FDSTAT_CLOSE, rc);
  +    fdstat_exit(fd, opx, rc);
   
   DBGIO(fd, (stderr, "<--\tfdClose(%p) rc %lx %s\n", (fd ? fd : NULL), 
(unsigned long)rc, fdbg(fd)));
       if (!rc && (_rpmio_debug || rpmIsDebug())) fdstat_print(fd, " FDIO", 
stderr);
  @@ -2567,10 +2583,10 @@
    *
    * @todo glibc also supports ",ccs="
    *
  - * - glibc:  c no cancel
  - * - glibc:  e close on exec (FD_CLOEXEC)
  - * - glibc:  m use mmap'd input
  - * - glibc:  x don't clobber (O_EXCL)
  + * - glibc:  'c' no cancel
  + * - glibc:  'e' close on exec (FD_CLOEXEC)
  + * - glibc:  'm' use mmap'd input
  + * - glibc:  'x' don't clobber (O_EXCL)
    * - gzopen: [0-9] is compression level
    * - gzopen: 'f' is filtered (Z_FILTERED)
    * - gzopen: 'h' is Huffman encoding (Z_HUFFMAN_ONLY)
  @@ -2581,7 +2597,13 @@
    * - HACK:   '.' terminates, rest is type of I/O
    * - HACK:   'D' sync (O_DSYNC)
    * - HACK:   'S' sync (O_SYNC)
  - * - HACK:   'J' fallocate+fdatasync+fadvise+fsync
  + * - HACK:   'I' fallocate(2)
  + * - HACK:   'O' fdatasync(2)
  + * - HACK:   'N' fadvise(2)
  + * - HACK:   'F' fsync(2)
  + * - HACK:   'P' syncfs(2)
  + * - HACK:   't' truncate (O_TRUNC)
  + * - HACK:   'T' tempfile (O_TMPFILE)
    * - HACK:   '?' debug I/O + refcnt
    */
   static inline void cvtfmode (const char *m,
  @@ -2605,6 +2627,16 @@
        flags |= O_RDONLY;
        if (--nstdio > 0) *stdio++ = *m;
        break;
  +    case 'T':
  +#if defined(O_TMPFILE)
  +     flags |= O_TMPFILE;
  +     if (--nstdio > 0) *stdio++ = *m;
  +#endif
  +     break;
  +    case 't':
  +     flags |= O_TRUNC;
  +     if (--nstdio > 0) *stdio++ = *m;
  +     break;
       default:
        *stdio = '\0';
        return;
  @@ -2643,12 +2675,21 @@
        case 'S':
            flags |= O_SYNC;
            goto other;
  -     case 'J':
  +     case 'I':
            RPMFD_SET(flags, FALLOCATE);
  +         goto other;
  +     case 'O':
            RPMFD_SET(flags, FDATASYNC);
  +         goto other;
  +     case 'N':
            RPMFD_SET(flags, FADVISE);
  +         goto other;
  +     case 'F':
            RPMFD_SET(flags, FSYNC);
            goto other;
  +     case 'P':
  +         RPMFD_SET(flags, SYNCFS);
  +         goto other;
        case '?':
            RPMFD_SET(flags, DEBUGIO);
            RPMFD_SET(flags, DEBUGREFS);
  @@ -2968,7 +3009,8 @@
   
   int Fcntl(FD_t fd, int cmd, ...)
   {
  -    int fdno = fdSyscallPre(__FUNCTION__, fd, 1, NULL);
  +    static const int opx = FDSTAT_FCNTL;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
       va_list ap;
       void * arg = NULL;
       int rc = -2;
  @@ -2977,76 +3019,202 @@
       arg = va_arg(ap, void *);
       va_end(ap);
   
  -    fdstat_enter(fd, FDSTAT_FCNTL);
  +    fdstat_enter(fd, opx);
       rc = fdSyscall( fcntl(fdno, cmd, arg) );
  -    fdstat_exit(fd, FDSTAT_FCNTL, 0);
  +    fdstat_exit(fd, opx, 0);
   
  -    return fdSyscallPost(__FUNCTION__, fd, fdno, rc);
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
   }
   
   int Flock(FD_t fd, int op)
   {
  -    int fdno = fdSyscallPre(__FUNCTION__, fd, 1, NULL);
  -    fdstat_enter(fd, FDSTAT_FLOCK);
  +    static const int opx = FDSTAT_FLOCK;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
  +    fdstat_enter(fd, opx);
       int rc = fdSyscall( flock(fdno, op) );
  -    fdstat_exit(fd, FDSTAT_FLOCK, 0);
  -    return fdSyscallPost(__FUNCTION__, fd, fdno, rc);
  +    fdstat_exit(fd, opx, 0);
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
   }
   
   int Fchdir(FD_t fd)
   {
  -    int fdno = fdSyscallPre(__FUNCTION__, fd, 1, NULL);
  -    fdstat_enter(fd, FDSTAT_FCHDIR);
  +    static const int opx = FDSTAT_FCHDIR;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
  +    fdstat_enter(fd, opx);
       int rc = fdSyscall( fchdir(fdno) );
  -    fdstat_exit(fd, FDSTAT_FCHDIR, 0);
  -    return fdSyscallPost(__FUNCTION__, fd, fdno, rc);
  +    fdstat_exit(fd, opx, 0);
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
   }
   
   int Fchmod(FD_t fd, mode_t mode)
   {
  -    int fdno = fdSyscallPre(__FUNCTION__, fd, 1, NULL);
  -    fdstat_enter(fd, FDSTAT_FCHMOD);
  +    static const int opx = FDSTAT_FCHMOD;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
  +    fdstat_enter(fd, opx);
       int rc = fdSyscall( fchdir(fdno) );
  -    fdstat_exit(fd, FDSTAT_FCHMOD, 0);
  -    return fdSyscallPost(__FUNCTION__, fd, fdno, rc);
  +    fdstat_exit(fd, opx, 0);
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
   }
   
   int Fchown(FD_t fd, uid_t uid, gid_t gid)
   {
  -    int fdno = fdSyscallPre(__FUNCTION__, fd, 1, NULL);
  -    fdstat_enter(fd, FDSTAT_FCHOWN);
  +    static const int opx = FDSTAT_FCHOWN;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
  +    fdstat_enter(fd, opx);
       int rc = fdSyscall( fchown(fdno, uid, gid) );
  -    fdstat_exit(fd, FDSTAT_FCHOWN, 0);
  -    return fdSyscallPost(__FUNCTION__, fd, fdno, rc);
  +    fdstat_exit(fd, opx, 0);
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
   }
   
   int Futimes(FD_t fd, const struct timeval tv[2])
   {
  -    int fdno = fdSyscallPre(__FUNCTION__, fd, 1, NULL);
  -    fdstat_enter(fd, FDSTAT_FUTIMES);
  +    static const int opx = FDSTAT_FUTIMES;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
  +    fdstat_enter(fd, opx);
  +#if defined(HAVE_FUTIMENS)
  +    struct timespec times[2];
  +    times[0].tv_sec = tv[0].tv_sec;
  +    times[0].tv_nsec = tv[0].tv_usec * 1000;
  +    times[1].tv_sec = tv[1].tv_sec;
  +    times[1].tv_nsec = tv[1].tv_usec * 1000;
  +    int rc = fdSyscall( futimens(fdno, times) );
  +#elif defined(HAVE_FUTIMES)
       int rc = fdSyscall( futimes(fdno, tv) );
  -    fdstat_exit(fd, FDSTAT_FUTIMES, 0);
  -    return fdSyscallPost(__FUNCTION__, fd, fdno, rc);
  +#else
  +    errno = ENOSYS;
  +#endif
  +    fdstat_exit(fd, opx, 0);
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
  +}
  +
  +int Futimens(FD_t fd, const struct timespec times[2])
  +{
  +    static const int opx = FDSTAT_FUTIMENS;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
  +    fdstat_enter(fd, opx);
  +#if defined(HAVE_FUTIMENS)
  +    int rc = fdSyscall( futimens(fdno, times) );
  +#elif defined(HAVE_FUTIMES)
  +    struct timeval tv[2];
  +    tv[0].tv_sec = times[0].tv_sec;
  +    tv[0].tv_usec = times[0].tv_nsec / 1000;
  +    tv[1].tv_sec = times[1].tv_sec;
  +    tv[1].tv_usec = times[1].tv_nsec / 1000;
  +    int rc = fdSyscall( futimes(fdno, tv) );
  +#else
  +    errno = ENOSYS;
  +#endif
  +    fdstat_exit(fd, opx, 0);
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
  +}
  +
  +ssize_t Fgetxattr(FD_t fd, const char *name, void *value, size_t size)
  +{
  +    static const int opx = FDSTAT_FGETXATTR;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
  +    ssize_t rc = -2;
  +
  +    fdstat_enter(fd, opx);
  +#if defined(HAVE_FGETXATTR)
  +#if defined(linux)
  +    rc = fdSyscall( fgetxattr(fdno, name, value, size) );
  +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
  +    uint32_t _position = 0;
  +    int _options = 0;        /* XXX XATTR_{NOFOLLOW,SHOWCOMPRESSION} */
  +    rc = fdSyscall( fgetxattr(fdno, name, value, size, _position, _options) 
);
  +#else
  +    errno = ENOSYS;
  +#endif
  +#endif
  +    fdstat_exit(fd, opx, (rc >= 0 ? rc : 0));
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
  +}
  +
  +int Fsetxattr(FD_t fd, const char *name, const void *value, size_t size,
  +             int flags)
  +{
  +    static const int opx = FDSTAT_FSETXATTR;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
  +    ssize_t rc = -2;
  +
  +    fdstat_enter(fd, opx);
  +#if defined(HAVE_FSETXATTR)
  +#if defined(linux)
  +    rc = fdSyscall( fsetxattr(fdno, name, value, size, flags) );
  +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
  +    uint32_t _position = 0;
  +    int _options = 0;        /* XXX XATTR_{NOFOLLOW,CREATE,REPLACE} */
  +    rc = fdSyscall( fsetxattr(fdno, name, value, size, _position, _options) 
);
  +#else
  +    errno = ENOSYS;
  +#endif
  +#endif
  +    fdstat_exit(fd, opx, (rc >= 0 ? size : 0));
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
  +}
  +
  +ssize_t Flistxattr(FD_t fd, char *list, size_t size)
  +{
  +    static const int opx = FDSTAT_FLISTXATTR;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
  +    ssize_t rc = -2;
  +
  +    fdstat_enter(fd, opx);
  +#if defined(HAVE_FGETXATTR)
  +#if defined(linux)
  +    rc = fdSyscall( flistxattr(fdno, list, size) );
  +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
  +    int _options = 0;        /* XXX XATTR_{NOFOLLOW,SHOWCOMPRESSION} */
  +    rc = fdSyscall( flistxattr(fdno, list, size, _options) );
  +#else
  +    errno = ENOSYS;
  +#endif
  +#endif
  +    fdstat_exit(fd, opx, (rc >= 0 ? rc : 0));
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
  +}
  +
  +int Fremovexattr(FD_t fd, char *name)
  +{
  +    static const int opx = FDSTAT_FREMOVEXATTR;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
  +    ssize_t rc = -2;
  +
  +    fdstat_enter(fd, opx);
  +#if defined(HAVE_FGETXATTR)
  +#if defined(linux)
  +    rc = fdSyscall( fremovexattr(fdno, name) );
  +#elif defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__)
  +    int _options = 0;        /* XXX XATTR_{NOFOLLOW,SHOWCOMPRESSION} */
  +    rc = fdSyscall( fremovexattr(fdno, name, _options) );
  +#else
  +    errno = ENOSYS;
  +#endif
  +#endif
  +    fdstat_exit(fd, opx, (rc >= 0 ? rc : 0));
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
   }
   
   int Fchflags(FD_t fd, unsigned int flags)
   {
  -    int fdno = fdSyscallPre(__FUNCTION__, fd, 1, NULL);
  +    static const int opx = FDSTAT_FCHFLAGS;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
       int rc = -2;
   
  -    fdstat_enter(fd, FDSTAT_FCHFLAGS);
  +    fdstat_enter(fd, opx);
   #if defined(HAVE_FCHFLAGS)
       rc = fdSyscall( fchflags(fdno, flags) );
   #else
       errno = ENOSYS;
   #endif
  -    fdstat_exit(fd, FDSTAT_FCHFLAGS, 0);
  -    return fdSyscallPost(__FUNCTION__, fd, fdno, rc);
  +    fdstat_exit(fd, opx, 0);
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
   }
   
   int Fadvise(FD_t fd, off_t offset, off_t len, int advice)
   {
  -    int fdno = fdSyscallPre(__FUNCTION__, fd, 1, NULL);
  +    static const int opx = FDSTAT_FADVISE;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
       int rc = -2;
   
       if (fdno < 0) {
  @@ -3054,7 +3222,7 @@
        if (errno == EINVAL)
            errno = ESPIPE;
       }
  -    fdstat_enter(fd, FDSTAT_FADVISE);
  +    fdstat_enter(fd, opx);
       switch (advice) {
   #if defined(HAVE_POSIX_FADVISE)
       case POSIX_FADV_NORMAL:
  @@ -3073,19 +3241,20 @@
        goto exit;
        break;
       }
  -    fdstat_exit(fd, FDSTAT_FADVISE, len);
  +    fdstat_exit(fd, opx, len);
   
   exit:
  -    return fdSyscallPost(__FUNCTION__, fd, fdno, rc);
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
   }
   
   #undef HAVE_FALLOCATE  /* XXX hmmm, fallocate64 is AWOL in F11. */
   int Fallocate(FD_t fd, off_t offset, off_t len)
   {
  -    int fdno = fdSyscallPre(__FUNCTION__, fd, 1, NULL);
  +    static const int opx = FDSTAT_FALLOCATE;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
       int rc = -2;
   
  -    fdstat_enter(fd, FDSTAT_FALLOCATE);
  +    fdstat_enter(fd, opx);
   #if defined(HAVE_POSIX_FALLOCATE)
       rc = fdSyscall( posix_fallocate(fdno, offset, len) );
   #elif defined(HAVE_FALLOCATE)
  @@ -3094,60 +3263,83 @@
   #else
       errno = ENOSYS;
   #endif
  -    fdstat_exit(fd, FDSTAT_FALLOCATE, len);
  +    fdstat_exit(fd, opx, len);
   
  -    return fdSyscallPost(__FUNCTION__, fd, fdno, rc);
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
   }
   
   int Ftruncate(FD_t fd, off_t len)
   {
  -    int fdno = fdSyscallPre(__FUNCTION__, fd, 1, NULL);
  +    static const int opx = FDSTAT_FTRUNCATE;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
       int rc = -2;
   
  +    fdstat_enter(fd, opx);
   #if defined(HAVE_FTRUNCATE)
       rc = fdSyscall( ftruncate(fdno, len) );
   #else
       errno = ENOSYS;
   #endif
  +    fdstat_exit(fd, opx, len);
   
  -    return fdSyscallPost(__FUNCTION__, fd, fdno, rc);
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
   }
   
   int Fdatasync(FD_t fd)
   {
  -    int fdno = fdSyscallPre(__FUNCTION__, fd, 1, NULL);
  +    static const int opx = FDSTAT_FDATASYNC;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
       int rc = -2;
   
  -    fdstat_enter(fd, FDSTAT_FDATASYNC);
  +    fdstat_enter(fd, opx);
   #if defined(HAVE_FDATASYNC)
       rc = fdSyscall( fdatasync(fdno) );
   #else
       errno = ENOSYS;
   #endif
  -    fdstat_exit(fd, FDSTAT_FDATASYNC, 0);    /* XXX #bytes? */
  +    fdstat_exit(fd, opx, 0); /* XXX #bytes? */
   
  -    return fdSyscallPost(__FUNCTION__, fd, fdno, rc);
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
   }
   
   int Fsync(FD_t fd)
   {
  -    int fdno = fdSyscallPre(__FUNCTION__, fd, 1, NULL);
  +    static const int opx = FDSTAT_FSYNC;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
       int rc = -2;
   
  -    fdstat_enter(fd, FDSTAT_FSYNC);
  -#if defined(HAVE_FDATASYNC)
  -    rc = fdSyscall( fdatasync(fdno) );
  +    fdstat_enter(fd, opx);
  +#if defined(HAVE_FSYNC)
  +    rc = fdSyscall( fsync(fdno) );
  +#else
  +    errno = ENOSYS;
  +#endif
  +    fdstat_exit(fd, opx, 0);         /* XXX #bytes? */
  +
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
  +}
  +
  +int Syncfs(FD_t fd)
  +{
  +    static const int opx = FDSTAT_SYNCFS;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
  +    int rc = -2;
  +
  +    fdstat_enter(fd, opx);
  +#if defined(HAVE_SYNCFS)
  +    rc = fdSyscall( syncfs(fdno) );
   #else
       errno = ENOSYS;
   #endif
  -    fdstat_exit(fd, FDSTAT_FSYNC, 0);                /* XXX #bytes? */
  +    fdstat_exit(fd, opx, 0);         /* XXX #bytes? */
   
  -    return fdSyscallPost(__FUNCTION__, fd, fdno, rc);
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
   }
   
  -int Fincore(FD_t fd)
  +int Fincore(FD_t fd, int nincore)
   {
  -    int fdno = fdSyscallPre(__FUNCTION__, fd, 1, NULL);
  +    static const int opx = FDSTAT_FINCORE;
  +    int fdno = fdSyscallPreFdno(__FUNCTION__, fd, 1, NULL);
       void * mapped = MAP_FAILED;
       size_t nmapped = 0;
       size_t pagesize = sysconf(_SC_PAGESIZE);
  @@ -3156,7 +3348,7 @@
       unsigned char * vec;
       int rc = -2;
     
  -    fdstat_enter(fd, FDSTAT_FINCORE);
  +    fdstat_enter(fd, opx);
       if (fdno < 0)
        goto exit;
   
  @@ -3189,8 +3381,10 @@
   exit:
       if (mapped != MAP_FAILED)
        (void) Munmap(mapped, nmapped);
  -    fdstat_exit(fd, FDSTAT_FINCORE, (rc >= 0 ? rc : 0) * pagesize);
  -    return fdSyscallPost(__FUNCTION__, fd, fdno, rc);
  +    if (nincore > 0 && rc >= 0)
  +     nincore -= rc;
  +    fdstat_exit(fd, opx, nincore * pagesize);
  +    return fdSyscallPostFdno(__FUNCTION__, fd, fdno, rc);
   }
   
   #undef       fdSyscall
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmio.h
  ============================================================================
  $ cvs diff -u -r1.97.2.11 -r1.97.2.12 rpmio.h
  --- rpm/rpmio/rpmio.h 18 Apr 2017 11:14:42 -0000      1.97.2.11
  +++ rpm/rpmio/rpmio.h 19 Apr 2017 20:42:15 -0000      1.97.2.12
  @@ -188,6 +188,32 @@
   int Futimes(FD_t fd, const struct timeval tv[2]);
   
   /**
  + * futimens(2) clone.
  + */
  +int Futimens(FD_t fd, const struct timespec times[2]);
  +
  +/**
  + * fgetxattr(2) clone.
  + */
  +ssize_t Fgetxattr(FD_t fd, const char *name, void *value, size_t size);
  +
  +/**
  + * fsetxattr(2) clone.
  + */
  +int Fsetxattr(FD_t fd, const char *name,
  +             const void *value, size_t size, int flags);
  +
  +/**
  + * flistxattr(2) clone.
  + */
  +ssize_t Flistxattr(FD_t fd, char *list, size_t size);
  +
  +/**
  + * fremovexattr(2) clone.
  + */
  +int Fremovexattr(FD_t fd, char *name);
  +
  +/**
    * fchflags(2) clone.
    */
   int Fchflags(FD_t fd, unsigned int flags);
  @@ -218,10 +244,16 @@
   int Fsync(FD_t fd);
   
   /**
  + * syncfs(2) clone.
  + */
  +int Syncfs(FD_t fd);
  +
  +/**
    * Return no. of pages in cache (using mmap(2) and mincore(2)).
  + * @param nincore    expected no. pages in core
    * @return           no. of pages in core, -1 on error
    */
  -int Fincore(FD_t fd);
  +int Fincore(FD_t fd, int nincore);
   
   /*@}*/
   
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmio/rpmio_internal.h
  ============================================================================
  $ cvs diff -u -r2.127.2.10 -r2.127.2.11 rpmio_internal.h
  --- rpm/rpmio/rpmio_internal.h        18 Apr 2017 11:14:42 -0000      
2.127.2.10
  +++ rpm/rpmio/rpmio_internal.h        19 Apr 2017 20:42:15 -0000      
2.127.2.11
  @@ -31,20 +31,28 @@
       FDSTAT_WRITE     =  1,   /*!< write statistics index. */
       FDSTAT_SEEK              =  2,   /*!< seek statistics index. */
       FDSTAT_CLOSE     =  3,   /*!< close statistics index */
  -    FDSTAT_DIGEST    =  4,   /*!< digest statistics index. */
  -    FDSTAT_OPEN              =  5,   /*!< open statistics index. */
  +    FDSTAT_FDIGEST   =  4,   /*!< digest statistics index. */
  +    FDSTAT_FOPEN     =  5,   /*!< open statistics index. */
       FDSTAT_FCNTL     =  6,   /*!< fcntl statistics index. */
       FDSTAT_FLOCK     =  7,   /*!< flock statistics index. */
       FDSTAT_FCHDIR    =  8,   /*!< fchdir statistics index. */
       FDSTAT_FCHMOD    =  9,   /*!< fchmod statistics index. */
       FDSTAT_FCHOWN    = 10,   /*!< fchown statistics index. */
       FDSTAT_FUTIMES   = 11,   /*!< futimes statistics index. */
  -    FDSTAT_FCHFLAGS  = 12,   /*!< fchflags statistics index. */
  -    FDSTAT_FALLOCATE = 13,   /*!< fallocate statistics index. */
  -    FDSTAT_FDATASYNC = 14,   /*!< fdatasync statistics index. */
  -    FDSTAT_FADVISE   = 15,   /*!< fadvise statistics index. */
  -    FDSTAT_FSYNC     = 16,   /*!< fsync statistics index. */
  -    FDSTAT_FINCORE   = 17,   /*!< fincore statistics index. */
  +    FDSTAT_FUTIMENS  = 12,   /*!< futimens statistics index. */
  +    FDSTAT_FGETXATTR = 13,   /*!< fgetxattr statistics index. */
  +    FDSTAT_FSETXATTR = 14,   /*!< fsetxattr statistics index. */
  +    FDSTAT_FLISTXATTR        = 15,   /*!< flistxattr statistics index. */
  +    FDSTAT_FREMOVEXATTR      = 16,   /*!< fremovexattr statistics index. */
  +    FDSTAT_FCHFLAGS  = 17,   /*!< fchflags statistics index. */
  +    FDSTAT_FALLOCATE = 18,   /*!< fallocate statistics index. */
  +    FDSTAT_FTRUNCATE = 19,   /*!< ftruncate statistics index. */
  +    FDSTAT_FDATASYNC = 20,   /*!< fdatasync statistics index. */
  +    FDSTAT_FADVISE   = 21,   /*!< fadvise statistics index. */
  +    FDSTAT_FSYNC     = 22,   /*!< fsync statistics index. */
  +    FDSTAT_SYNCFS    = 23,   /*!< syncfs statistics index. */
  +    FDSTAT_FINCORE   = 24,   /*!< fincore statistics index. */
  +
       FDSTAT_MAX
   } fdOpX;
   
  @@ -53,11 +61,12 @@
    */
   typedef enum fdFlags_e {
       RPMFD_FLAG_NONE          = 0,
  -     /* 0 - 24 unused */
  -    RPMFD_FLAG_FALLOCATE     = (1 << 25),
  -    RPMFD_FLAG_FADVISE               = (1 << 26),
  -    RPMFD_FLAG_FDATASYNC     = (1 << 27),
  -    RPMFD_FLAG_FSYNC         = (1 << 28),
  +     /* 0 - 23 unused */
  +    RPMFD_FLAG_SYNCFS                = (1 << 24),
  +    RPMFD_FLAG_FSYNC         = (1 << 25),
  +    RPMFD_FLAG_FDATASYNC     = (1 << 26),
  +    RPMFD_FLAG_FADVISE               = (1 << 27),
  +    RPMFD_FLAG_FALLOCATE     = (1 << 28),
       RPMFD_FLAG_DEBUGREFS     = (1 << 29),
       RPMFD_FLAG_DEBUGIO               = (1 << 30),
   } fdFlags;
  @@ -425,28 +434,36 @@
       if (fd == NULL || fd->stats == NULL) return;
       for (int opx = 0; opx < FDSTAT_MAX; opx++) {
        static const char *const names[] = {
  -         [FDSTAT_READ]       = "    read",
  -         [FDSTAT_WRITE]      = "   write",
  -         [FDSTAT_SEEK]       = "    seek",
  +         [FDSTAT_READ]               = "        read",
  +         [FDSTAT_WRITE]              = "       write",
  +         [FDSTAT_SEEK]               = "        seek",
   #ifdef       NOISY
  -         [FDSTAT_CLOSE]      = "   close",
  +         [FDSTAT_CLOSE]              = "       close",
   #endif
  -         [FDSTAT_DIGEST]     = "  digest",
  -         [FDSTAT_OPEN]       = "    open",
  -         [FDSTAT_FCNTL]      = "    cntl",
  -         [FDSTAT_FLOCK]      = "    lock",
  -         [FDSTAT_FCHDIR]     = "   chdir",
  -         [FDSTAT_FCHMOD]     = "   chmod",
  -         [FDSTAT_FCHOWN]     = "   chown",
  -         [FDSTAT_FUTIMES]    = "  utimes",
  -         [FDSTAT_FCHFLAGS]   = " chflags",
  -         [FDSTAT_FALLOCATE]  = "   alloc",
  +         [FDSTAT_FDIGEST]            = "     fdigest",
  +         [FDSTAT_FOPEN]              = "       fopen",
  +         [FDSTAT_FCNTL]              = "       fcntl",
  +         [FDSTAT_FLOCK]              = "       flock",
  +         [FDSTAT_FCHDIR]             = "      fchdir",
  +         [FDSTAT_FCHMOD]             = "      fchmod",
  +         [FDSTAT_FCHOWN]             = "      fchown",
  +         [FDSTAT_FUTIMES]            = "     futimes",
  +         [FDSTAT_FUTIMENS]           = "    futimens",
  +         [FDSTAT_FGETXATTR]          = "   fgetxattr",
  +         [FDSTAT_FSETXATTR]          = "   fsetxattr",
  +         [FDSTAT_FLISTXATTR]         = "  flistxattr",
  +         [FDSTAT_FREMOVEXATTR]       = "fremovexattr",
  +         [FDSTAT_FCHFLAGS]           = "    fchflags",
  +         [FDSTAT_FALLOCATE]          = "   fallocate",
  +         [FDSTAT_FTRUNCATE]          = "   ftruncate",
   #ifdef       NOISY
  -         [FDSTAT_FADVISE]    = "  advise",
  +         [FDSTAT_FADVISE]            = "     fadvise",
   #endif
  -         [FDSTAT_FDATASYNC]  = "datasync",
  -         [FDSTAT_FSYNC]      = "    sync",
  -         [FDSTAT_FINCORE]    = "  incore",
  +         [FDSTAT_FDATASYNC]          = "   fdatasync",
  +         [FDSTAT_FSYNC]              = "       fsync",
  +         [FDSTAT_SYNCFS]             = "      syncfs",
  +
  +         [FDSTAT_FINCORE]            = "     fincore",
        };
        rpmop op = &fd->stats->ops[opx];
   
  @@ -516,12 +533,13 @@
   static inline
   void fdInitDigest(FD_t fd, pgpHashAlgo hashalgo, int _flags)
   {
  +    static const int opx = FDSTAT_FDIGEST;
       rpmDigestFlags flags = (rpmDigestFlags) _flags;
       fd->digests = (DIGEST_CTX *) realloc(fd->digests,
                        (fd->ndigests + 1) * sizeof(*fd->digests));
  -    fdstat_enter(fd, FDSTAT_DIGEST);
  +    fdstat_enter(fd, opx);
       fd->digests[fd->ndigests++] = rpmDigestInit(hashalgo, flags);
  -    fdstat_exit(fd, FDSTAT_DIGEST, 0);
  +    fdstat_exit(fd, opx, 0);
   }
   
   /** \ingroup rpmio
  @@ -530,8 +548,11 @@
   static inline
   void fdInitHmac(FD_t fd, const void * key, size_t keylen)
   {
  +    static const int opx = FDSTAT_FDIGEST;
  +    fdstat_enter(fd, opx);
       if (fd->digests != NULL && fd->ndigests > 0 && key != NULL)
        (void) rpmHmacInit(fd->digests[fd->ndigests-1], key, keylen);
  +    fdstat_exit(fd, opx, 0);
   }
   
   /** \ingroup rpmio
  @@ -540,21 +561,20 @@
   static inline
   void fdUpdateDigests(FD_t fd, const unsigned char * buf, ssize_t buflen)
   {
  -    int i;
  +    static const int opx = FDSTAT_FDIGEST;
   
  -  if (fd->ndigests > 0 && buf != NULL && buflen > 0) {
  -    fdstat_enter(fd, FDSTAT_DIGEST);
  +    fdstat_enter(fd, opx);
  +    if (fd->ndigests > 0 && buf != NULL && buflen > 0)
   #if defined(_OPENMP)
   #pragma omp parallel for if (fd->ndigests > 1)
   #endif
  -    for (i = fd->ndigests - 1; i >= 0; i--) {
  +    for (int i = fd->ndigests - 1; i >= 0; i--) {
        DIGEST_CTX ctx = fd->digests[i];
        if (ctx == NULL)
            continue;
        (void) rpmDigestUpdate(ctx, buf, buflen);
       }
  -    fdstat_exit(fd, FDSTAT_DIGEST, buflen);
  -  }
  +    fdstat_exit(fd, opx, buflen);
   }
   
   /** \ingroup rpmio
  @@ -563,10 +583,11 @@
   void fdFiniDigest(FD_t fd, pgpHashAlgo hashalgo,
                void * datap, size_t * lenp, int asAscii)
   {
  +    static const int opx = FDSTAT_FDIGEST;
       int i = -1;
   
  -  if (fd->ndigests > 0) {
  -    fdstat_enter(fd, FDSTAT_DIGEST);
  +    fdstat_enter(fd, opx);
  +    if (fd->ndigests > 0)
       for (i = fd->ndigests - 1; i >= 0; i--) {
        DIGEST_CTX ctx = fd->digests[i];
        if (ctx == NULL)
  @@ -577,12 +598,11 @@
        (void) rpmDigestFinal(ctx, datap, lenp, asAscii);
        break;
       }
  -    fdstat_exit(fd, FDSTAT_DIGEST, 0);
  -  }
       if (i < 0) {
        if (datap != NULL) *(void **)datap = NULL;
        if (lenp != NULL) *lenp = 0;
       }
  +    fdstat_exit(fd, opx, 0);
   }
   
   /** \ingroup rpmio
  @@ -590,9 +610,11 @@
   static inline
   void fdStealDigest(FD_t fd, pgpDig dig)
   {
  -    int i;
  +    static const int opx = FDSTAT_FDIGEST;
  +
  +    fdstat_enter(fd, opx);
       if (fd->ndigests > 0)
  -    for (i = fd->ndigests - 1; i >= 0; i--) {
  +    for (int i = fd->ndigests - 1; i >= 0; i--) {
        DIGEST_CTX ctx = fd->digests[i];
        if (ctx != NULL)
        switch (rpmDigestAlgo(ctx)) {
  @@ -614,6 +636,7 @@
            break;
        }
       }
  +    fdstat_exit(fd, opx, 0);
   }
   
   /** \ingroup rpmio
  @@ -629,11 +652,11 @@
   }
   
   /** \ingroup rpmio
  - * Common prologue for checking wrapped system functions.
  + * Common prologue(s) for checking wrapped system functions.
    * @return           file descriptor
    */
   static inline
  -int fdSyscallPre(const char * sysname, FD_t fd, int local, const char ** 
lpathp)
  +int fdSyscallPreFdno(const char * sysname, FD_t fd, int local, const char ** 
lpathp)
   {
       int fdno = Fileno(fd);
       const char * path = fdGetOPath(fd);
  @@ -666,12 +689,45 @@
       return fdno;
   }
   
  +static inline
  +const char * fdSyscallPrePath(const char * sysname, const char *path, int 
local)
  +{
  +    const char * lpath = NULL;
  +    int ut = urlPath(path, &lpath);
  +    
  +if (_rpmio_debug)
  +fprintf(stderr, "--> %s(%s)\n", sysname, path);
  +
  +    if (path == NULL) {
  +     path = NULL;
  +     errno = EFAULT;
  +     goto exit;
  +    }
  +
  +    if (local)                       /* XXX Restrict to local file paths? */
  +    switch (ut) {
  +    case URL_IS_PATH:                /* XXX Drop file:/// prefix. */
  +     path = lpath;
  +     /*@fallthrough@*/
  +    case URL_IS_UNKNOWN:
  +     break;
  +    default:
  +     path = NULL;
  +     errno = EINVAL;
  +     goto exit;
  +     break;
  +    }
  +
  +exit:
  +    return path;
  +}
  +
   /** \ingroup rpmio
    * Common epilogue for checking wrapped system functions.
    * @return           exit code
    */
   static inline
  -int fdSyscallPost(const char * sysname, FD_t fd, int fdno, int rc)
  +int fdSyscallPostFdno(const char * sysname, FD_t fd, int fdno, int rc)
   {
       if (rc < 0)
        rpmlog(RPMLOG_DEBUG, _("%s(%d) failed: rc %d %m\n"),
  @@ -680,6 +736,17 @@
       return rc;
   }
   
  +static inline
  +int fdSyscallPostPath(const char * sysname, const char *lpath, int rc)
  +{
  +    if (rc < 0)
  +     rpmlog(RPMLOG_DEBUG, _("%s(%s) failed: rc %d %m\n"),
  +             __FUNCTION__, lpath, rc);
  +if (_rpmio_debug)
  +fprintf(stderr, "<-- %s(%s) rc %d\n", sysname, lpath, rc);
  +    return rc;
  +}
  +
   #ifdef __cplusplus
   }
   #endif
  @@ .
______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
CVS Sources Repository                                rpm-cvs@rpm5.org

Reply via email to