diff options
Diffstat (limited to 'src/driver/tpax_driver_ctx.c')
-rw-r--r-- | src/driver/tpax_driver_ctx.c | 160 |
1 files changed, 132 insertions, 28 deletions
diff --git a/src/driver/tpax_driver_ctx.c b/src/driver/tpax_driver_ctx.c index 5593ec6..b7b949e 100644 --- a/src/driver/tpax_driver_ctx.c +++ b/src/driver/tpax_driver_ctx.c @@ -34,6 +34,9 @@ | TPAX_DRIVER_WRITE_FORMAT_USTAR \ | TPAX_DRIVER_WRITE_FORMAT_RUSTAR) +#define TPAX_CACHE_MIN (1 << 12) +#define TPAX_CACHE_MAX (1 << 24) + /* package info */ static const struct tpax_source_version tpax_src_version = { TPAX_TAG_VER_MAJOR, @@ -52,6 +55,9 @@ static const struct tpax_fd_ctx tpax_default_fdctx = { .fdlog = (-1), }; +/* fallback error description */ +static const char tpax_null_errdesc[] = "<no error description>"; + struct tpax_driver_ctx_alloc { struct argv_meta * meta; struct tpax_driver_ctx_impl ctx; @@ -75,6 +81,21 @@ static uint32_t tpax_argv_flags(uint32_t flags) return ret; } +static const char * tpax_driver_errdesc(void) +{ + int lerrno; + const char * errstr; + + lerrno = errno; + errno = 0; + + errstr = strerror(lerrno); + errstr = errno ? tpax_null_errdesc : errstr; + errno = lerrno; + + return errstr; +} + static int tpax_driver_usage( int fdout, const char * program, @@ -89,7 +110,7 @@ static int tpax_driver_usage( "Synopsis:\n" " %s [-d] [-f archive]\n" " %s -r [-d] [-f archive]\n" - " %s -w [−x format] [-b blocksize] [-dtv] [-H|-L] [-f archive]\n" + " %s -w [−x format] [-b blocksize] [-dtv] [-H|-L] [-f archive] [-s replstr]... \n" " %s -r -w [-d]\n\n" "Options:\n", program,program,program,program,program); @@ -170,8 +191,7 @@ static int tpax_driver_usage_copy_mode( break; default: - if (!(errdesc = strerror(errno))) - errdesc = "<no error description>"; + errdesc = tpax_driver_errdesc(); tpax_dprintf( fdout, @@ -260,15 +280,7 @@ static int tpax_driver_error_archive_path( struct argv_meta * meta, bool fwrite) { - int lerrno; - const char * errstr; - - lerrno = errno; - errno = 0; - - errstr = strerror(lerrno); - errstr = errno ? "" : errstr; - errno = lerrno; + const char * errstr = tpax_driver_errdesc(); if (fwrite) { tpax_dprintf( @@ -504,20 +516,20 @@ static struct tpax_driver_ctx_impl * tpax_driver_ctx_alloc( for (keyval=entry->keyv; keyval->keyword; keyval++) *pkeyval++ = keyval; - if (cctx->drvflags & TPAX_DRIVER_EXEC_MODE_WRITE_COPY) { - ictx->ctx.bufsize = TPAX_FILEIO_BUFLEN; - ictx->ctx.bufaddr = mmap( - 0,ictx->ctx.bufsize, - PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS, - -1,0); + ictx->ctx.bufsize = TPAX_FILEIO_BUFLEN; + ictx->ctx.bufaddr = mmap( + 0,ictx->ctx.bufsize, + PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, + -1,0); - if (ictx->ctx.bufaddr == MAP_FAILED) { - free(ictx->ctx.keyvalv); - free(ictx); - return 0; - } + if (ictx->ctx.bufaddr == MAP_FAILED) { + free(ictx->ctx.keyvalv); + free(ictx); + return 0; + } + if (cctx->drvflags & TPAX_DRIVER_EXEC_MODE_WRITE_COPY) { ictx->ctx.dirbuff = mmap( 0,TPAX_DIRENT_BUFLEN, PROT_READ|PROT_WRITE, @@ -576,6 +588,46 @@ static int tpax_driver_keyval_error( return TPAX_ERROR; } +static int tpax_driver_srcstat_error( + struct tpax_driver_ctx_impl * ctx, + const struct argv_entry * archive, + const char * program) +{ + const char * errstr = tpax_driver_errdesc(); + + if (archive) { + tpax_dprintf( + ctx->fdctx.fderr, + "%s: could not stat archive file '%s' (%s).\n", + program,archive->arg,errstr); + } else { + tpax_dprintf( + ctx->fdctx.fderr, + "%s: could not stat input source file <fd=%d> (%s).\n", + program,ctx->fdctx.fdin,errstr); + } + + tpax_lib_free_driver_ctx(&ctx->ctx); + + return TPAX_ERROR; +} + +static int tpax_driver_cache_error( + struct tpax_driver_ctx_impl * ctx, + const char * program) +{ + const char * errstr = tpax_driver_errdesc(); + + tpax_dprintf( + ctx->fdctx.fderr, + "%s: failed to allocate source data cache (%s).\n", + program,errstr); + + tpax_lib_free_driver_ctx(&ctx->ctx); + + return TPAX_ERROR; +} + int tpax_lib_get_driver_ctx( char ** argv, char ** envp, @@ -595,6 +647,7 @@ int tpax_lib_get_driver_ctx( size_t nunits; size_t nreplstr; size_t sreplstr; + size_t cachesize; const char * program; int fddst; const char * ch; @@ -818,6 +871,8 @@ int tpax_lib_get_driver_ctx( } else if (archive) { memcpy(&lfdctx,fdctx,sizeof(*fdctx)); + cctx.srcflags = TPAX_SOURCE_DATA_PENDING; + lfdctx.fdin = openat( fdctx->fdcwd, archive->arg, @@ -829,7 +884,15 @@ int tpax_lib_get_driver_ctx( program,archive->arg, meta,false); + cctx.srcflags = TPAX_SOURCE_DATA_OPENED; + fdctx = &lfdctx; + + } else if (cctx.drvflags & TPAX_DRIVER_EXEC_MODE_WRITE) { + cctx.srcflags = TPAX_SOURCE_DATA_NONE; + + } else { + cctx.srcflags = TPAX_SOURCE_DATA_PENDING; } /* not implemented mode(s) */ @@ -872,10 +935,6 @@ int tpax_lib_get_driver_ctx( return tpax_driver_error_not_implemented( fdctx->fderr,program,"the pax format",meta); - case TPAX_DRIVER_WRITE_FORMAT_CPIO: - return tpax_driver_error_not_implemented( - fdctx->fderr,program,"the cpio format",meta); - default: break; } @@ -899,6 +958,42 @@ int tpax_lib_get_driver_ctx( if (!tpax_driver_is_valid_keyval(*pkeyval)) return tpax_driver_keyval_error(ctx,*pkeyval,program); + /* source data mapping (non-critical) */ + if (cctx.srcflags) { + if (fstat(fdctx->fdin,&ctx->srcstat) < 0) + return tpax_driver_srcstat_error(ctx,archive,program); + + ctx->mapsize = ctx->srcstat.st_size; + ctx->mapaddr = mmap( + 0,ctx->mapsize, + PROT_READ,MAP_PRIVATE, + fdctx->fdin,0); + + if (ctx->mapaddr == MAP_FAILED) { + ctx->cctx.srcflags = TPAX_SOURCE_DATA_FILEIO; + ctx->mapaddr = 0; + ctx->mapsize = 0; + } else { + ctx->cctx.srcflags = TPAX_SOURCE_DATA_MAPPED; + } + } + + /* allocate source data cache as needed */ + if (ctx->cctx.srcflags == TPAX_SOURCE_DATA_FILEIO) { + cachesize = TPAX_CACHE_MAX; + + for (; !ctx->cacheaddr && (cachesize >= TPAX_CACHE_MIN); ) + if (!(ctx->cacheaddr = calloc(cachesize,1))) + cachesize >>= 1; + + if (!ctx->cacheaddr) + return tpax_driver_cache_error(ctx,program); + + ctx->cachemark = ctx->cacheaddr; + ctx->cachecap = &ctx->cacheaddr[cachesize]; + } + + /* all done */ if (archive) { ctx->file = archive->arg; ctx->ctx.file = &ctx->file; @@ -939,6 +1034,12 @@ static void tpax_free_driver_ctx_impl(struct tpax_driver_ctx_alloc * ictx) if (ictx->ctx.keyvalv) free(ictx->ctx.keyvalv); + if (ictx->ctx.cacheaddr) + free(ictx->ctx.cacheaddr); + + if (ictx->ctx.mapaddr) + munmap(ictx->ctx.mapaddr,ictx->ctx.mapsize); + if (ictx->ctx.bufaddr) munmap(ictx->ctx.bufaddr,ictx->ctx.bufsize); @@ -954,6 +1055,9 @@ static void tpax_free_driver_ctx_impl(struct tpax_driver_ctx_alloc * ictx) if (ictx->ctx.direntv) free(ictx->ctx.direntv); + if (ictx->ctx.cpiov) + free(ictx->ctx.cpiov); + argv_free(ictx->meta); free(ictx); } |