aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2017-09-27 14:13:02 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2017-09-27 14:13:02 +0300
commit0145de1db25c3840346b9cd9ea44e571812e5516 (patch)
tree92c29f344764a54ce07d99d487321896bec53162
parent80134405a63517bda8964f7993d096dc1df247c1 (diff)
downloadruncap-0145de1db25c3840346b9cd9ea44e571812e5516.tar.gz
runcap-0145de1db25c3840346b9cd9ea44e571812e5516.tar.bz2
Avoid closing stdin.
When given the RCF_STDIN flag, runcap_init failed to initialize rc_cap[RUNCAP_STDIN].sc_storfd. It remained initialized to 0 which eventually led to stdin being inadvertenlty closed by runcap_free. * runcap.c (stream_capture_alloc): Merge with stream_capture_init. All callers updated. (runcap_init): Initialize rc_cap[RUNCAP_STDIN].sc_storfd to -1 to prevent it from being closed. * t/pipe.at: Set 5 seconds timeout. * t/stdin.at: Likewise.
-rw-r--r--runcap.c45
-rw-r--r--t/pipe.at2
-rw-r--r--t/stdin.at2
3 files changed, 19 insertions, 30 deletions
diff --git a/runcap.c b/runcap.c
index f1e9410..26654f8 100644
--- a/runcap.c
+++ b/runcap.c
@@ -23,15 +23,20 @@
#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include "runcap.h"
-static int
-stream_capture_alloc(struct stream_capture *cap, size_t size)
+int
+stream_capture_init(struct stream_capture *cap, size_t size)
{
+ if (!cap) {
+ errno = EINVAL;
+ return -1;
+ }
+
if (size) {
cap->sc_base = malloc(size);
if (!cap->sc_base)
return -1;
} else
cap->sc_base = NULL;
@@ -42,26 +47,12 @@ stream_capture_alloc(struct stream_capture *cap, size_t size)
cap->sc_cur = 0;
cap->sc_storfd = -1;
cap->sc_fd = -1;
return 0;
}
-int
-stream_capture_init(struct stream_capture *cap, size_t size)
-{
- if (!cap) {
- errno = EINVAL;
- return -1;
- }
-
- if (stream_capture_alloc(cap, size))
- return -1;
-
- return 0;
-}
-
static void
stream_capture_reset(struct stream_capture *cap)
{
cap->sc_leng = 0;
cap->sc_level = 0;
cap->sc_nlines = 0;
@@ -431,44 +422,42 @@ runcap_init(struct runcap *rc, int flags)
int res;
if (!(flags & RCF_PROGRAM))
rc->rc_program = NULL;
if (!(flags & RCF_TIMEOUT))
rc->rc_timeout = 0;
+
if (flags & RCF_STDIN) {
if (rc->rc_cap[RUNCAP_STDIN].sc_size > 0
&& rc->rc_cap[RUNCAP_STDIN].sc_fd != -1) {
errno = EINVAL;
return -1;
}
rc->rc_cap[RUNCAP_STDIN].sc_level =
rc->rc_cap[RUNCAP_STDIN].sc_size;
rc->rc_cap[RUNCAP_STDIN].sc_cur = 0;
+ rc->rc_cap[RUNCAP_STDIN].sc_storfd = -1;
} else if (stream_capture_init(&rc->rc_cap[RUNCAP_STDIN], 0))
return -1;
- if (flags & RCF_STDOUT_SIZE)
- res = stream_capture_alloc(&rc->rc_cap[RUNCAP_STDOUT],
- rc->rc_cap[RUNCAP_STDOUT].sc_size);
- else
- res = stream_capture_init(&rc->rc_cap[RUNCAP_STDOUT],
- STRCAP_BUFSIZE);
+ res = stream_capture_init(&rc->rc_cap[RUNCAP_STDOUT],
+ (flags & RCF_STDOUT_SIZE)
+ ? rc->rc_cap[RUNCAP_STDOUT].sc_size
+ : STRCAP_BUFSIZE);
if (res)
return res;
if (!(flags & RCF_STDOUT_LINEMON)) {
rc->rc_cap[RUNCAP_STDOUT].sc_linemon = NULL;
rc->rc_cap[RUNCAP_STDOUT].sc_monarg = NULL;
}
- if (flags & RCF_STDERR_SIZE)
- res = stream_capture_alloc(&rc->rc_cap[RUNCAP_STDERR],
- rc->rc_cap[RUNCAP_STDERR].sc_size);
- else
- res = stream_capture_init(&rc->rc_cap[RUNCAP_STDERR],
- STRCAP_BUFSIZE);
+ res = stream_capture_init(&rc->rc_cap[RUNCAP_STDERR],
+ (flags & RCF_STDERR_SIZE)
+ ? rc->rc_cap[RUNCAP_STDERR].sc_size
+ : STRCAP_BUFSIZE);
if (res)
return res;
if (!(flags & RCF_STDERR_LINEMON)) {
rc->rc_cap[RUNCAP_STDERR].sc_linemon = NULL;
rc->rc_cap[RUNCAP_STDERR].sc_monarg = NULL;
diff --git a/t/pipe.at b/t/pipe.at
index 3b31f3f..974afa7 100644
--- a/t/pipe.at
+++ b/t/pipe.at
@@ -13,13 +13,13 @@
#
# You should have received a copy of the GNU General Public License along
# with Runcap. If not, see <http://www.gnu.org/licenses/>.
AT_SETUP([pipe stdin])
AT_KEYWORDS([pipe])
-AT_CHECK([rt -n all -i -f $INPUT -- genout -l 337 -o - -s 628 -l 734 -e $INPUT
+AT_CHECK([rt -n all -t 5 -i -f $INPUT -- genout -l 337 -o - -s 628 -l 734 -e $INPUT
],
[0],
[res=0
exit code: 0
stdout: 8 lines, 337 bytes
stderr: 11 lines, 734 bytes
diff --git a/t/stdin.at b/t/stdin.at
index 36f684c..4556145 100644
--- a/t/stdin.at
+++ b/t/stdin.at
@@ -13,13 +13,13 @@
#
# You should have received a copy of the GNU General Public License along
# with Runcap. If not, see <http://www.gnu.org/licenses/>.
AT_SETUP([supply stdin])
AT_KEYWORDS([stdin])
-AT_CHECK([rt -n all -f $INPUT -- genout -l 337 -o - -s 628 -l 734 -e $INPUT
+AT_CHECK([rt -n all -t 5 -f $INPUT -- genout -l 337 -o - -s 628 -l 734 -e $INPUT
],
[0],
[res=0
exit code: 0
stdout: 8 lines, 337 bytes
stderr: 11 lines, 734 bytes

Return to:

Send suggestions and report system problems to the System administrator.