a85d3e driver, library interfaces: support alternate fd's for input/output/error/log.

Authored and Committed by midipix 6 years ago
    driver, library interfaces: support alternate fd's for input/output/error/log.
    
        
file modified
+15 -1
include/perk/perk.h CHANGED
@@ -126,6 +126,15 @@ struct pe_source_version {
126
126
const char * commit;
127
127
};
128
128
129
+ struct pe_fd_ctx {
130
+ int fdin;
131
+ int fdout;
132
+ int fderr;
133
+ int fdlog;
134
+ int fdcwd;
135
+ int fddst;
136
+ };
137
+
129
138
struct pe_error_info {
130
139
const struct pe_driver_ctx * edctx;
131
140
const struct pe_unit_ctx * euctx;
@@ -166,6 +175,7 @@ struct pe_info_string {
166
175
167
176
/* driver api */
168
177
perk_api int pe_get_driver_ctx (char ** argv, char ** envp, uint32_t flags,
178
+ const struct pe_fd_ctx *,
169
179
struct pe_driver_ctx **);
170
180
171
181
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
175
185
176
186
perk_api void pe_free_unit_ctx (struct pe_unit_ctx *);
177
187
188
+ perk_api int pe_get_driver_fdctx (const struct pe_driver_ctx *, struct pe_fd_ctx *);
189
+ perk_api int pe_set_driver_fdctx (struct pe_driver_ctx *, const struct pe_fd_ctx *);
190
+
178
191
/* utility api */
179
- perk_api int pe_main (int, char **, char **);
192
+ perk_api int pe_main (int, char **, char **, const struct pe_fd_ctx *);
193
+
180
194
perk_api int pe_output_image_category (const struct pe_driver_ctx *, const struct pe_image_meta *, FILE *);
181
195
perk_api int pe_output_image_sections (const struct pe_driver_ctx *, const struct pe_image_meta *, FILE *);
182
196
perk_api int pe_output_image_symbols (const struct pe_driver_ctx *, const struct pe_image_meta *, FILE *);
file modified
+13 -6
src/driver/pe_amain.c CHANGED
@@ -9,6 +9,7 @@
9
9
#include <perk/perk.h>
10
10
#include <perk/perk_output.h>
11
11
#include "perk_driver_impl.h"
12
+ #include "perk_dprintf_impl.h"
12
13
13
14
#ifndef PERK_DRIVER_FLAGS
14
15
#define PERK_DRIVER_FLAGS PERK_DRIVER_VERBOSITY_ERRORS \
@@ -31,15 +32,16 @@ static const char * const pe_ver_plain[6] = {
31
32
"",""
32
33
};
33
34
34
- static ssize_t pe_version(struct pe_driver_ctx * dctx)
35
+ static ssize_t pe_version(int fdout, struct pe_driver_ctx * dctx)
35
36
{
36
37
const struct pe_source_version * verinfo;
37
38
const char * const * verclr;
38
39
39
40
verinfo = pe_source_version();
40
- verclr = isatty(STDOUT_FILENO) ? pe_ver_color : pe_ver_plain;
41
+ verclr = isatty(fdout) ? pe_ver_color : pe_ver_plain;
41
42
42
- return fprintf(stdout,vermsg,
43
+ return pe_dprintf(
44
+ fdout,vermsg,
43
45
verclr[0],dctx->program,verclr[1],
44
46
verclr[2],verinfo->major,verinfo->minor,
45
47
verinfo->revision,verclr[3],
@@ -81,20 +83,25 @@ static int pe_exit(struct pe_driver_ctx * dctx, int ret)
81
83
return ret;
82
84
}
83
85
84
- int pe_main(int argc, char ** argv, char ** envp)
86
+ int pe_main(int argc, char ** argv, char ** envp, const struct pe_fd_ctx * fdctx)
85
87
{
86
88
int ret;
89
+ int fdout;
90
+ uint64_t flags;
87
91
struct pe_driver_ctx * dctx;
88
92
struct pe_unit_ctx * uctx;
89
93
const char ** unit;
90
94
91
- if ((ret = pe_get_driver_ctx(argv,envp,PERK_DRIVER_FLAGS,&dctx)))
95
+ flags = PERK_DRIVER_FLAGS;
96
+ fdout = fdctx ? fdctx->fdout : STDOUT_FILENO;
97
+
98
+ if ((ret = pe_get_driver_ctx(argv,envp,flags,fdctx,&dctx)))
92
99
return (ret == PERK_USAGE)
93
100
? !--argc
94
101
: PERK_ERROR;
95
102
96
103
if (dctx->cctx->drvflags & PERK_DRIVER_VERSION)
97
- if ((pe_version(dctx)) < 0)
104
+ if ((pe_version(fdout,dctx)) < 0)
98
105
return pe_exit(dctx,PERK_ERROR);
99
106
100
107
for (unit=dctx->units; *unit; unit++) {
file modified
+66 -10
src/driver/pe_driver_ctx.c CHANGED
@@ -48,6 +48,7 @@ static uint32_t pe_argv_flags(uint32_t flags)
48
48
}
49
49
50
50
static int pe_driver_usage(
51
+ int fdout,
51
52
const char * program,
52
53
const char * arg,
53
54
const struct argv_option ** optv,
@@ -59,7 +60,7 @@ static int pe_driver_usage(
59
60
"Usage: %s [options] <file>...\n" "Options:\n",
60
61
program);
61
62
62
- argv_usage(STDOUT_FILENO,header,optv,arg);
63
+ argv_usage(fdout,header,optv,arg);
63
64
argv_free(meta);
64
65
65
66
return PERK_USAGE;
@@ -67,6 +68,7 @@ static int pe_driver_usage(
67
68
68
69
static struct pe_driver_ctx_impl * pe_driver_ctx_alloc(
69
70
struct argv_meta * meta,
71
+ const struct pe_fd_ctx * fdctx,
70
72
const struct pe_common_ctx * cctx,
71
73
size_t nunits)
72
74
{
@@ -82,8 +84,8 @@ static struct pe_driver_ctx_impl * pe_driver_ctx_alloc(
82
84
if (!(ictx = calloc(1,size)))
83
85
return 0;
84
86
85
- if (cctx)
86
- memcpy(&ictx->ctx.cctx,cctx,sizeof(*cctx));
87
+ memcpy(&ictx->ctx.fdctx,fdctx,sizeof(*fdctx));
88
+ memcpy(&ictx->ctx.cctx,cctx,sizeof(*cctx));
87
89
88
90
elements = sizeof(ictx->ctx.erribuf) / sizeof(*ictx->ctx.erribuf);
89
91
@@ -108,10 +110,11 @@ static int pe_get_driver_ctx_fail(struct argv_meta * meta)
108
110
}
109
111
110
112
int pe_get_driver_ctx(
111
- char ** argv,
112
- char ** envp,
113
- uint32_t flags,
114
- struct pe_driver_ctx ** pctx)
113
+ char ** argv,
114
+ char ** envp,
115
+ uint32_t flags,
116
+ const struct pe_fd_ctx * fdctx,
117
+ struct pe_driver_ctx ** pctx)
115
118
{
116
119
struct pe_driver_ctx_impl * ctx;
117
120
struct pe_common_ctx cctx;
@@ -124,6 +127,17 @@ int pe_get_driver_ctx(
124
127
125
128
(void)envp;
126
129
130
+ if (!fdctx) {
131
+ fdctx = &(const struct pe_fd_ctx) {
132
+ .fdin = STDIN_FILENO,
133
+ .fdout = STDOUT_FILENO,
134
+ .fderr = STDERR_FILENO,
135
+ .fdlog = (-1),
136
+ .fdcwd = AT_FDCWD,
137
+ .fddst = AT_FDCWD,
138
+ };
139
+ }
140
+
127
141
argv_optv_init(pe_default_options,optv);
128
142
129
143
if (!(meta = argv_get(
@@ -139,7 +153,10 @@ int pe_get_driver_ctx(
139
153
cctx.drvflags = flags;
140
154
141
155
if (!argv[1] && (flags & PERK_DRIVER_VERBOSITY_USAGE))
142
- return pe_driver_usage(program,0,optv,meta);
156
+ return pe_driver_usage(
157
+ fdctx->fderr,
158
+ program,
159
+ 0,optv,meta);
143
160
144
161
/* get options, count units */
145
162
for (entry=meta->entries; entry->fopt || entry->arg; entry++) {
@@ -147,7 +164,10 @@ int pe_get_driver_ctx(
147
164
switch (entry->tag) {
148
165
case TAG_HELP:
149
166
if (flags & PERK_DRIVER_VERBOSITY_USAGE)
150
- return pe_driver_usage(program,entry->arg,optv,meta);
167
+ return pe_driver_usage(
168
+ fdctx->fdout,
169
+ program,entry->arg,
170
+ optv,meta);
151
171
152
172
case TAG_VERSION:
153
173
cctx.drvflags |= PERK_DRIVER_VERSION;
@@ -202,7 +222,7 @@ int pe_get_driver_ctx(
202
222
else if (pretty && !strcmp(pretty,"dlltool"))
203
223
cctx.fmtflags |= PERK_PRETTY_DLLTOOL;
204
224
205
- if (!(ctx = pe_driver_ctx_alloc(meta,&cctx,nunits)))
225
+ if (!(ctx = pe_driver_ctx_alloc(meta,fdctx,&cctx,nunits)))
206
226
return pe_get_driver_ctx_fail(meta);
207
227
208
228
ctx->ctx.program = program;
@@ -235,3 +255,39 @@ const struct pe_source_version * pe_source_version(void)
235
255
{
236
256
return &pe_src_version;
237
257
}
258
+
259
+ int pe_get_driver_fdctx(
260
+ const struct pe_driver_ctx * dctx,
261
+ struct pe_fd_ctx * fdctx)
262
+ {
263
+ struct pe_driver_ctx_impl * ictx;
264
+
265
+ ictx = pe_get_driver_ictx(dctx);
266
+
267
+ fdctx->fdin = ictx->fdctx.fdin;
268
+ fdctx->fdout = ictx->fdctx.fdout;
269
+ fdctx->fderr = ictx->fdctx.fderr;
270
+ fdctx->fdlog = ictx->fdctx.fdlog;
271
+ fdctx->fdcwd = ictx->fdctx.fdcwd;
272
+ fdctx->fddst = ictx->fdctx.fddst;
273
+
274
+ return 0;
275
+ }
276
+
277
+ int pe_set_driver_fdctx(
278
+ struct pe_driver_ctx * dctx,
279
+ const struct pe_fd_ctx * fdctx)
280
+ {
281
+ struct pe_driver_ctx_impl * ictx;
282
+
283
+ ictx = pe_get_driver_ictx(dctx);
284
+
285
+ ictx->fdctx.fdin = fdctx->fdin;
286
+ ictx->fdctx.fdout = fdctx->fdout;
287
+ ictx->fdctx.fderr = fdctx->fderr;
288
+ ictx->fdctx.fdlog = fdctx->fdlog;
289
+ ictx->fdctx.fdcwd = fdctx->fdcwd;
290
+ ictx->fdctx.fddst = fdctx->fddst;
291
+
292
+ return 0;
293
+ }
src/internal/perk_driver_impl.h CHANGED
@@ -32,6 +32,7 @@ enum app_tags {
32
32
struct pe_driver_ctx_impl {
33
33
struct pe_common_ctx cctx;
34
34
struct pe_driver_ctx ctx;
35
+ struct pe_fd_ctx fdctx;
35
36
const struct pe_unit_ctx * euctx;
36
37
const char * eunit;
37
38
struct pe_error_info ** errinfp;
@@ -73,4 +74,46 @@ static inline void pe_driver_set_ectx(
73
74
ictx->eunit = unit;
74
75
}
75
76
77
+ static inline int pe_driver_fdin(const struct pe_driver_ctx * dctx)
78
+ {
79
+ struct pe_fd_ctx fdctx;
80
+ pe_get_driver_fdctx(dctx,&fdctx);
81
+ return fdctx.fdin;
82
+ }
83
+
84
+ static inline int pe_driver_fdout(const struct pe_driver_ctx * dctx)
85
+ {
86
+ struct pe_fd_ctx fdctx;
87
+ pe_get_driver_fdctx(dctx,&fdctx);
88
+ return fdctx.fdout;
89
+ }
90
+
91
+ static inline int pe_driver_fderr(const struct pe_driver_ctx * dctx)
92
+ {
93
+ struct pe_fd_ctx fdctx;
94
+ pe_get_driver_fdctx(dctx,&fdctx);
95
+ return fdctx.fderr;
96
+ }
97
+
98
+ static inline int pe_driver_fdlog(const struct pe_driver_ctx * dctx)
99
+ {
100
+ struct pe_fd_ctx fdctx;
101
+ pe_get_driver_fdctx(dctx,&fdctx);
102
+ return fdctx.fdlog;
103
+ }
104
+
105
+ static inline int pe_driver_fdcwd(const struct pe_driver_ctx * dctx)
106
+ {
107
+ struct pe_fd_ctx fdctx;
108
+ pe_get_driver_fdctx(dctx,&fdctx);
109
+ return fdctx.fdcwd;
110
+ }
111
+
112
+ static inline int pe_driver_fddst(const struct pe_driver_ctx * dctx)
113
+ {
114
+ struct pe_fd_ctx fdctx;
115
+ pe_get_driver_fdctx(dctx,&fdctx);
116
+ return fdctx.fddst;
117
+ }
118
+
76
119
#endif
file modified
+1 -1
src/perk.c CHANGED
@@ -8,5 +8,5 @@
8
8
9
9
int main(int argc, char ** argv, char ** envp)
10
10
{
11
- return pe_main(argc,argv,envp);
11
+ return pe_main(argc,argv,envp,0);
12
12
}