summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/perk/perk.h16
-rw-r--r--src/driver/pe_amain.c19
-rw-r--r--src/driver/pe_driver_ctx.c76
-rw-r--r--src/internal/perk_driver_impl.h43
-rw-r--r--src/perk.c2
5 files changed, 138 insertions, 18 deletions
diff --git a/include/perk/perk.h b/include/perk/perk.h
index d176243..675f437 100644
--- a/include/perk/perk.h
+++ b/include/perk/perk.h
@@ -126,6 +126,15 @@ struct pe_source_version {
const char * commit;
};
+struct pe_fd_ctx {
+ int fdin;
+ int fdout;
+ int fderr;
+ int fdlog;
+ int fdcwd;
+ int fddst;
+};
+
struct pe_error_info {
const struct pe_driver_ctx * edctx;
const struct pe_unit_ctx * euctx;
@@ -166,6 +175,7 @@ struct pe_info_string {
/* driver api */
perk_api int pe_get_driver_ctx (char ** argv, char ** envp, uint32_t flags,
+ const struct pe_fd_ctx *,
struct pe_driver_ctx **);
perk_api void pe_free_driver_ctx (struct pe_driver_ctx *);
@@ -175,8 +185,12 @@ perk_api int pe_get_unit_ctx (const struct pe_driver_ctx *, const cha
perk_api void pe_free_unit_ctx (struct pe_unit_ctx *);
+perk_api int pe_get_driver_fdctx (const struct pe_driver_ctx *, struct pe_fd_ctx *);
+perk_api int pe_set_driver_fdctx (struct pe_driver_ctx *, const struct pe_fd_ctx *);
+
/* utility api */
-perk_api int pe_main (int, char **, char **);
+perk_api int pe_main (int, char **, char **, const struct pe_fd_ctx *);
+
perk_api int pe_output_image_category (const struct pe_driver_ctx *, const struct pe_image_meta *, FILE *);
perk_api int pe_output_image_sections (const struct pe_driver_ctx *, const struct pe_image_meta *, FILE *);
perk_api int pe_output_image_symbols (const struct pe_driver_ctx *, const struct pe_image_meta *, FILE *);
diff --git a/src/driver/pe_amain.c b/src/driver/pe_amain.c
index 8fb1788..4ea62ef 100644
--- a/src/driver/pe_amain.c
+++ b/src/driver/pe_amain.c
@@ -9,6 +9,7 @@
#include <perk/perk.h>
#include <perk/perk_output.h>
#include "perk_driver_impl.h"
+#include "perk_dprintf_impl.h"
#ifndef PERK_DRIVER_FLAGS
#define PERK_DRIVER_FLAGS PERK_DRIVER_VERBOSITY_ERRORS \
@@ -31,15 +32,16 @@ static const char * const pe_ver_plain[6] = {
"",""
};
-static ssize_t pe_version(struct pe_driver_ctx * dctx)
+static ssize_t pe_version(int fdout, struct pe_driver_ctx * dctx)
{
const struct pe_source_version * verinfo;
const char * const * verclr;
verinfo = pe_source_version();
- verclr = isatty(STDOUT_FILENO) ? pe_ver_color : pe_ver_plain;
+ verclr = isatty(fdout) ? pe_ver_color : pe_ver_plain;
- return fprintf(stdout,vermsg,
+ return pe_dprintf(
+ fdout,vermsg,
verclr[0],dctx->program,verclr[1],
verclr[2],verinfo->major,verinfo->minor,
verinfo->revision,verclr[3],
@@ -81,20 +83,25 @@ static int pe_exit(struct pe_driver_ctx * dctx, int ret)
return ret;
}
-int pe_main(int argc, char ** argv, char ** envp)
+int pe_main(int argc, char ** argv, char ** envp, const struct pe_fd_ctx * fdctx)
{
int ret;
+ int fdout;
+ uint64_t flags;
struct pe_driver_ctx * dctx;
struct pe_unit_ctx * uctx;
const char ** unit;
- if ((ret = pe_get_driver_ctx(argv,envp,PERK_DRIVER_FLAGS,&dctx)))
+ flags = PERK_DRIVER_FLAGS;
+ fdout = fdctx ? fdctx->fdout : STDOUT_FILENO;
+
+ if ((ret = pe_get_driver_ctx(argv,envp,flags,fdctx,&dctx)))
return (ret == PERK_USAGE)
? !--argc
: PERK_ERROR;
if (dctx->cctx->drvflags & PERK_DRIVER_VERSION)
- if ((pe_version(dctx)) < 0)
+ if ((pe_version(fdout,dctx)) < 0)
return pe_exit(dctx,PERK_ERROR);
for (unit=dctx->units; *unit; unit++) {
diff --git a/src/driver/pe_driver_ctx.c b/src/driver/pe_driver_ctx.c
index 3beb073..9f9644e 100644
--- a/src/driver/pe_driver_ctx.c
+++ b/src/driver/pe_driver_ctx.c
@@ -48,6 +48,7 @@ static uint32_t pe_argv_flags(uint32_t flags)
}
static int pe_driver_usage(
+ int fdout,
const char * program,
const char * arg,
const struct argv_option ** optv,
@@ -59,7 +60,7 @@ static int pe_driver_usage(
"Usage: %s [options] <file>...\n" "Options:\n",
program);
- argv_usage(STDOUT_FILENO,header,optv,arg);
+ argv_usage(fdout,header,optv,arg);
argv_free(meta);
return PERK_USAGE;
@@ -67,6 +68,7 @@ static int pe_driver_usage(
static struct pe_driver_ctx_impl * pe_driver_ctx_alloc(
struct argv_meta * meta,
+ const struct pe_fd_ctx * fdctx,
const struct pe_common_ctx * cctx,
size_t nunits)
{
@@ -82,8 +84,8 @@ static struct pe_driver_ctx_impl * pe_driver_ctx_alloc(
if (!(ictx = calloc(1,size)))
return 0;
- if (cctx)
- memcpy(&ictx->ctx.cctx,cctx,sizeof(*cctx));
+ memcpy(&ictx->ctx.fdctx,fdctx,sizeof(*fdctx));
+ memcpy(&ictx->ctx.cctx,cctx,sizeof(*cctx));
elements = sizeof(ictx->ctx.erribuf) / sizeof(*ictx->ctx.erribuf);
@@ -108,10 +110,11 @@ static int pe_get_driver_ctx_fail(struct argv_meta * meta)
}
int pe_get_driver_ctx(
- char ** argv,
- char ** envp,
- uint32_t flags,
- struct pe_driver_ctx ** pctx)
+ char ** argv,
+ char ** envp,
+ uint32_t flags,
+ const struct pe_fd_ctx * fdctx,
+ struct pe_driver_ctx ** pctx)
{
struct pe_driver_ctx_impl * ctx;
struct pe_common_ctx cctx;
@@ -124,6 +127,17 @@ int pe_get_driver_ctx(
(void)envp;
+ if (!fdctx) {
+ fdctx = &(const struct pe_fd_ctx) {
+ .fdin = STDIN_FILENO,
+ .fdout = STDOUT_FILENO,
+ .fderr = STDERR_FILENO,
+ .fdlog = (-1),
+ .fdcwd = AT_FDCWD,
+ .fddst = AT_FDCWD,
+ };
+ }
+
argv_optv_init(pe_default_options,optv);
if (!(meta = argv_get(
@@ -139,7 +153,10 @@ int pe_get_driver_ctx(
cctx.drvflags = flags;
if (!argv[1] && (flags & PERK_DRIVER_VERBOSITY_USAGE))
- return pe_driver_usage(program,0,optv,meta);
+ return pe_driver_usage(
+ fdctx->fderr,
+ program,
+ 0,optv,meta);
/* get options, count units */
for (entry=meta->entries; entry->fopt || entry->arg; entry++) {
@@ -147,7 +164,10 @@ int pe_get_driver_ctx(
switch (entry->tag) {
case TAG_HELP:
if (flags & PERK_DRIVER_VERBOSITY_USAGE)
- return pe_driver_usage(program,entry->arg,optv,meta);
+ return pe_driver_usage(
+ fdctx->fdout,
+ program,entry->arg,
+ optv,meta);
case TAG_VERSION:
cctx.drvflags |= PERK_DRIVER_VERSION;
@@ -202,7 +222,7 @@ int pe_get_driver_ctx(
else if (pretty && !strcmp(pretty,"dlltool"))
cctx.fmtflags |= PERK_PRETTY_DLLTOOL;
- if (!(ctx = pe_driver_ctx_alloc(meta,&cctx,nunits)))
+ if (!(ctx = pe_driver_ctx_alloc(meta,fdctx,&cctx,nunits)))
return pe_get_driver_ctx_fail(meta);
ctx->ctx.program = program;
@@ -235,3 +255,39 @@ const struct pe_source_version * pe_source_version(void)
{
return &pe_src_version;
}
+
+int pe_get_driver_fdctx(
+ const struct pe_driver_ctx * dctx,
+ struct pe_fd_ctx * fdctx)
+{
+ struct pe_driver_ctx_impl * ictx;
+
+ ictx = pe_get_driver_ictx(dctx);
+
+ fdctx->fdin = ictx->fdctx.fdin;
+ fdctx->fdout = ictx->fdctx.fdout;
+ fdctx->fderr = ictx->fdctx.fderr;
+ fdctx->fdlog = ictx->fdctx.fdlog;
+ fdctx->fdcwd = ictx->fdctx.fdcwd;
+ fdctx->fddst = ictx->fdctx.fddst;
+
+ return 0;
+}
+
+int pe_set_driver_fdctx(
+ struct pe_driver_ctx * dctx,
+ const struct pe_fd_ctx * fdctx)
+{
+ struct pe_driver_ctx_impl * ictx;
+
+ ictx = pe_get_driver_ictx(dctx);
+
+ ictx->fdctx.fdin = fdctx->fdin;
+ ictx->fdctx.fdout = fdctx->fdout;
+ ictx->fdctx.fderr = fdctx->fderr;
+ ictx->fdctx.fdlog = fdctx->fdlog;
+ ictx->fdctx.fdcwd = fdctx->fdcwd;
+ ictx->fdctx.fddst = fdctx->fddst;
+
+ return 0;
+}
diff --git a/src/internal/perk_driver_impl.h b/src/internal/perk_driver_impl.h
index 4a4d231..b17b7be 100644
--- a/src/internal/perk_driver_impl.h
+++ b/src/internal/perk_driver_impl.h
@@ -32,6 +32,7 @@ enum app_tags {
struct pe_driver_ctx_impl {
struct pe_common_ctx cctx;
struct pe_driver_ctx ctx;
+ struct pe_fd_ctx fdctx;
const struct pe_unit_ctx * euctx;
const char * eunit;
struct pe_error_info ** errinfp;
@@ -73,4 +74,46 @@ static inline void pe_driver_set_ectx(
ictx->eunit = unit;
}
+static inline int pe_driver_fdin(const struct pe_driver_ctx * dctx)
+{
+ struct pe_fd_ctx fdctx;
+ pe_get_driver_fdctx(dctx,&fdctx);
+ return fdctx.fdin;
+}
+
+static inline int pe_driver_fdout(const struct pe_driver_ctx * dctx)
+{
+ struct pe_fd_ctx fdctx;
+ pe_get_driver_fdctx(dctx,&fdctx);
+ return fdctx.fdout;
+}
+
+static inline int pe_driver_fderr(const struct pe_driver_ctx * dctx)
+{
+ struct pe_fd_ctx fdctx;
+ pe_get_driver_fdctx(dctx,&fdctx);
+ return fdctx.fderr;
+}
+
+static inline int pe_driver_fdlog(const struct pe_driver_ctx * dctx)
+{
+ struct pe_fd_ctx fdctx;
+ pe_get_driver_fdctx(dctx,&fdctx);
+ return fdctx.fdlog;
+}
+
+static inline int pe_driver_fdcwd(const struct pe_driver_ctx * dctx)
+{
+ struct pe_fd_ctx fdctx;
+ pe_get_driver_fdctx(dctx,&fdctx);
+ return fdctx.fdcwd;
+}
+
+static inline int pe_driver_fddst(const struct pe_driver_ctx * dctx)
+{
+ struct pe_fd_ctx fdctx;
+ pe_get_driver_fdctx(dctx,&fdctx);
+ return fdctx.fddst;
+}
+
#endif
diff --git a/src/perk.c b/src/perk.c
index f36909b..96e5c81 100644
--- a/src/perk.c
+++ b/src/perk.c
@@ -8,5 +8,5 @@
int main(int argc, char ** argv, char ** envp)
{
- return pe_main(argc,argv,envp);
+ return pe_main(argc,argv,envp,0);
}