1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
|
/* runcap - run program and capture its output
Copyright (C) 2017 Sergey Poznyakoff
Runcap is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 3 of the License, or (at your
option) any later version.
Runcap is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with Runcap. If not, see <http://www.gnu.org/licenses/>. */
#ifndef _RUNCAP_H_
# define _RUNCAP_H_ 1
struct stream_capture
{
int sc_fd; /* Input descriptor */
char *sc_base; /* buffer space */
size_t sc_size; /* size of the buffer */
size_t sc_level; /* number of characters currently in buffer */
size_t sc_cur; /* current offset in buffer */
off_t sc_leng; /* total length of captured data */
size_t sc_nlines; /* number of captured lines */
int sc_storfd; /* Storage file descriptor */
void (*sc_linemon) (const char *, size_t, void *);
/* Line monitor function */
void *sc_monarg; /* Line monitor argument */
};
#define STRCAP_BUFSIZE 4096
enum {
RUNCAP_STDIN,
RUNCAP_STDOUT,
RUNCAP_STDERR,
RUNCAP_NBUF
};
struct runcap
{
char *rc_program; /* [IN] (Path)name of the program to run */
char **rc_argv; /* [IN] Argument vector */
unsigned rc_timeout; /* [IN] Execution timeout */
struct stream_capture rc_cap[RUNCAP_NBUF];
/* rc_cap[RUNCAP_STDIN] - [IN], rest - [OUT] */
pid_t rc_pid; /* [OUT] - PID of the process */
int rc_status; /* [OUT] - Termination status */
int rc_errno; /* [OUT] - Value of errno, if terminated on error */
};
#define RCF_PROGRAM 0x0001 /* rc_program is set */
#define RCF_TIMEOUT 0x0002 /* rc_timeout is set */
#define RCF_STDIN 0x0004 /* rc_cap[RUNCAP_STDIN] is set */
#define RCF_STDOUT_SIZE 0x0008
#define RCF_STDOUT_LINEMON 0x0010
#define RCF_STDERR_SIZE 0x0020
#define RCF_STDERR_LINEMON 0x0040
int stream_capture_init(struct stream_capture *fc, size_t size);
void stream_capture_free(struct stream_capture *fc);
int runcap(struct runcap *rc, int flags);
void runcap_free(struct runcap *rc);
static inline struct stream_capture *
runcap_stream_capture(struct runcap *rc, int stream)
{
struct stream_capture *fp;
if (stream != RUNCAP_STDOUT && stream != RUNCAP_STDERR) {
errno = EINVAL;
return NULL;
}
fp = &rc->rc_cap[stream];
if (!fp->sc_base || fp->sc_size == 0) {
errno = EINVAL;
return NULL;
}
return fp;
}
int runcap_getc(struct runcap *rc, int stream, char *cp);
ssize_t runcap_getline(struct runcap *rc, int stream, char **pstr, size_t *psize);
off_t runcap_tell(struct runcap *rc, int stream);
int runcap_seek(struct runcap *rc, int stream, off_t off, int whence);
static inline int
runcap_rewind(struct runcap *rc, int stream)
{
return runcap_seek(rc, stream, 0, 0);
}
#endif
|