File: popenRWE.c

package info (click to toggle)
irssi-plugin-xmpp 0.53-1~bpo8+1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-backports
  • size: 1,540 kB
  • sloc: ansic: 8,300; makefile: 108; perl: 58
file content (95 lines) | stat: -rw-r--r-- 1,798 bytes parent folder | download | duplicates (3)
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
/**
 * Copyright 2009-2010 Bart Trojanowski <bart@jukie.net>
 * Licensed under GPLv2, or later, at your choosing.
 *
 * bidirectional popen() call
 *
 * @param rwepipe - int array of size three
 * @param exe - program to run
 * @param argv - argument list
 * @return pid or -1 on error
 *
 * The caller passes in an array of three integers (rwepipe), on successful
 * execution it can then write to element 0 (stdin of exe), and read from
 * element 1 (stdout) and 2 (stderr).
 */

/* Modified by Stephen Paul Weber to take a path and pass it to sh -c */

#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>

#include "popenRWE.h"

int popenRWE(int *rwepipe, const char *path) {
	int in[2];
	int out[2];
	int err[2];
	int pid;
	int rc;
	const char *argv[4] = {"sh", "-c", NULL, NULL};
	argv[2] = path;

	rc = pipe(in);
	if (rc<0)
		goto error_in;

	rc = pipe(out);
	if (rc<0)
		goto error_out;

	rc = pipe(err);
	if (rc<0)
		goto error_err;

	pid = fork();
	if (pid > 0) { /* parent */
		close(in[0]);
		close(out[1]);
		close(err[1]);
		rwepipe[0] = in[1];
		rwepipe[1] = out[0];
		rwepipe[2] = err[0];
		return pid;
	} else if (pid == 0) { /* child */
		close(in[1]);
		close(out[0]);
		close(err[0]);
		close(0);
		if(dup(in[0]) < 0) exit(2);
		close(1);
		if(dup(out[1]) < 0) exit(2);
		close(2);
		if(dup(err[1]) < 0) exit(2);

		execvp(argv[0], (char**)argv);
		exit(1);
	} else
		goto error_fork;

	return pid;

error_fork:
	close(err[0]);
	close(err[1]);
error_err:
	close(out[0]);
	close(out[1]);
error_out:
	close(in[0]);
	close(in[1]);
error_in:
	return -1;
}

int pcloseRWE(int pid, int *rwepipe) {
	int rc, status;
	close(rwepipe[0]);
	close(rwepipe[1]);
	close(rwepipe[2]);
	do {
		rc = waitpid(pid, &status, 0);
	} while (rc != 0 && ! WIFEXITED(status));
	return status;
}