summaryrefslogtreecommitdiffabout
path: root/runcap.h
blob: 0ece8e7bfd92a80f5f291d25e1935c2f82ce7b24 (plain)
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;     /* 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_get_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);
off_t 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) != 0;
}	

#endif

Return to:

Send suggestions and report system problems to the System administrator.