diff --git a/src/driver/amgc_driver_ctx.c b/src/driver/amgc_driver_ctx.c index bef0c44..35d3899 100644 --- a/src/driver/amgc_driver_ctx.c +++ b/src/driver/amgc_driver_ctx.c @@ -89,6 +89,7 @@ static struct amgc_driver_ctx_impl * amgc_driver_ctx_alloc( *units++ = entry->arg; ictx->meta = meta; + ictx->ctx.fdtmpin = -1; ictx->ctx.ctx.units = ictx->units; return &ictx->ctx; } diff --git a/src/driver/amgc_unit_ctx.c b/src/driver/amgc_unit_ctx.c index d2268fd..0498a68 100644 --- a/src/driver/amgc_unit_ctx.c +++ b/src/driver/amgc_unit_ctx.c @@ -8,6 +8,8 @@ #include #include #include +#include +#include #include #include @@ -23,18 +25,84 @@ static int amgc_free_unit_ctx_impl(struct amgc_unit_ctx_impl * ctx, int status) return status; } +static FILE * amgc_stdin_to_tmp(const struct amgc_driver_ctx * dctx) +{ + struct amgc_driver_ctx_impl * ictx; + uintptr_t addr; + int fdtmp; + + FILE * ftmp; + char buf[4096]; + ssize_t nread; + int ret; + + addr = (uintptr_t)dctx - offsetof(struct amgc_driver_ctx_impl,ctx); + ictx = (struct amgc_driver_ctx_impl *)addr; + + if (ictx->fdtmpin >= 0) { + if ((fdtmp = dup(ictx->fdtmpin)) < 0) + return 0; + + if (!(ftmp = fdopen(fdtmp,"r"))) + close(fdtmp); + + return ftmp; + } + + if (!(ftmp = tmpfile())) + return 0; + + if ((ictx->fdtmpin = dup(fileno(ftmp))) < 0) { + fclose(ftmp); + return 0; + } + + nread = read(0,buf,sizeof(buf)-1); + + while (nread) { + if (nread > 0) { + buf[nread] = '\0'; + ret = fputs(buf,ftmp); + } else + ret = (errno == EINTR) ? 0 : -1; + + if (ret < 0) { + fclose(ftmp); + return 0; + } + + nread = read(0,buf,sizeof(buf)-1); + } + + return ftmp; +} + int amgc_get_unit_ctx( const struct amgc_driver_ctx * dctx, const char * path, struct amgc_unit_ctx ** pctx) { struct amgc_unit_ctx_impl * ctx; + FILE * ftmp; + int fd; if (!dctx || !(ctx = calloc(sizeof(*ctx),1))) return -1; - if (amgc_map_input(-1,path,PROT_READ,&ctx->map)) + if (strcmp(path,"-")) + fd = -1; + else if (!(ftmp = amgc_stdin_to_tmp(dctx))) + return amgc_free_unit_ctx_impl(ctx,-1); + else if ((fd = dup(fileno(ftmp))) < 0) return amgc_free_unit_ctx_impl(ctx,-1); + else + fclose(ftmp); + + if (amgc_map_input(fd,path,PROT_READ,&ctx->map)) + return amgc_free_unit_ctx_impl(ctx,-1); + + if (fd > 0) + close(fd); memcpy(&ctx->cctx,dctx->cctx, sizeof(ctx->cctx)); diff --git a/src/internal/apimagic_driver_impl.h b/src/internal/apimagic_driver_impl.h index a3c6238..9054708 100644 --- a/src/internal/apimagic_driver_impl.h +++ b/src/internal/apimagic_driver_impl.h @@ -15,6 +15,7 @@ enum app_tags { struct amgc_driver_ctx_impl { struct amgc_common_ctx cctx; struct amgc_driver_ctx ctx; + int fdtmpin; }; struct amgc_unit_ctx_impl {