summaryrefslogtreecommitdiffhomepage
path: root/src/driver
diff options
context:
space:
mode:
authormidipix <writeonce@midipix.org>2015-12-29 05:15:05 -0500
committermidipix <writeonce@midipix.org>2016-01-01 22:50:23 -0500
commit389acb44d79857eb39b2afaeb8e410f6da93dcfc (patch)
treef6aa5472687dbd6a59df7791feef2fc0248c03e5 /src/driver
parent1fd161942ef2abaaccbda1188a765baf38b7cb82 (diff)
downloadapimagic-389acb44d79857eb39b2afaeb8e410f6da93dcfc.tar.bz2
apimagic-389acb44d79857eb39b2afaeb8e410f6da93dcfc.tar.xz
driver: added driver-level handling of stdin.
Diffstat (limited to 'src/driver')
-rw-r--r--src/driver/amgc_driver_ctx.c1
-rw-r--r--src/driver/amgc_unit_ctx.c70
2 files changed, 70 insertions, 1 deletions
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 <stddef.h>
#include <stdlib.h>
#include <string.h>
+#include <unistd.h>
+#include <errno.h>
#include <sys/mman.h>
#include <apimagic/apimagic.h>
@@ -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));