summaryrefslogtreecommitdiff
path: root/threadproc
diff options
context:
space:
mode:
authorwrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68>2007-10-14 06:57:18 +0000
committerwrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68>2007-10-14 06:57:18 +0000
commit65eced15c1d89f1c99f40715b8cb0c4c4b10410b (patch)
tree554864afd43da8b4563620218e55797d83846a0d /threadproc
parent464177724ae9b769e214884993f124865017b2eb (diff)
downloadlibapr-65eced15c1d89f1c99f40715b8cb0c4c4b10410b.tar.gz
Solve two potential problems with one shot.
First; we absolutely do NOT want to waste our time creating a pipe, when the caller has their own file descriptors all set up to give to the child process (and use itself). We can also presume a single ended pipe is about as interesting as the sound of one hand clapping. Create the pipe only when we don't already have any child/parent pipes set up, and when the caller passes no files for us to use. Otherwise, we simply dup for our own use rather than dup2. Second; we absolutely cannot dup2 into the static 'no_file' special fd, so we'll guard against this and also dup, instead, for this case. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@584500 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'threadproc')
-rw-r--r--threadproc/unix/proc.c143
1 files changed, 66 insertions, 77 deletions
diff --git a/threadproc/unix/proc.c b/threadproc/unix/proc.c
index 21b44d4b8..7ade722fa 100644
--- a/threadproc/unix/proc.c
+++ b/threadproc/unix/proc.c
@@ -44,78 +44,41 @@ APR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr,
apr_int32_t out,
apr_int32_t err)
{
- apr_status_t status;
- if ((in != APR_NO_PIPE) && (in != APR_NO_FILE)) {
- if ((status = apr_file_pipe_create(&attr->child_in, &attr->parent_in,
- attr->pool)) != APR_SUCCESS) {
- return status;
- }
+ apr_status_t rv;
- switch (in) {
- case APR_FULL_BLOCK:
- break;
- case APR_PARENT_BLOCK:
- apr_file_pipe_timeout_set(attr->child_in, 0);
- break;
- case APR_CHILD_BLOCK:
- apr_file_pipe_timeout_set(attr->parent_in, 0);
- break;
- default:
- apr_file_pipe_timeout_set(attr->child_in, 0);
- apr_file_pipe_timeout_set(attr->parent_in, 0);
- }
+ if ((in != APR_NO_PIPE) && (in != APR_NO_FILE)) {
+ /* APR_CHILD_BLOCK maps to APR_WRITE_BLOCK, while
+ * APR_PARENT_BLOCK maps to APR_READ_BLOCK, so transpose
+ * the CHILD/PARENT blocking flags for the stdin pipe.
+ * stdout/stderr map to the correct mode by default.
+ */
+ if (in == APR_CHILD_BLOCK)
+ in = APR_READ_BLOCK;
+ else if (in == APR_PARENT_BLOCK)
+ in = APR_WRITE_BLOCK;
+
+ if ((rv = apr_file_pipe_create_ex(&attr->child_in, &attr->parent_in,
+ in, attr->pool)) != APR_SUCCESS)
+ return rv;
}
- else if (in == APR_NO_FILE) {
+ else if (in == APR_NO_FILE)
attr->child_in = &no_file;
- }
if ((out != APR_NO_PIPE) && (out != APR_NO_FILE)) {
- if ((status = apr_file_pipe_create(&attr->parent_out, &attr->child_out,
- attr->pool)) != APR_SUCCESS) {
- return status;
- }
-
- switch (out) {
- case APR_FULL_BLOCK:
- break;
- case APR_PARENT_BLOCK:
- apr_file_pipe_timeout_set(attr->child_out, 0);
- break;
- case APR_CHILD_BLOCK:
- apr_file_pipe_timeout_set(attr->parent_out, 0);
- break;
- default:
- apr_file_pipe_timeout_set(attr->child_out, 0);
- apr_file_pipe_timeout_set(attr->parent_out, 0);
- }
+ if ((rv = apr_file_pipe_create_ex(&attr->parent_out, &attr->child_out,
+ out, attr->pool)) != APR_SUCCESS)
+ return rv;
}
- else if (out == APR_NO_FILE) {
+ else if (out == APR_NO_FILE)
attr->child_out = &no_file;
- }
if ((err != APR_NO_PIPE) && (err != APR_NO_FILE)) {
- if ((status = apr_file_pipe_create(&attr->parent_err, &attr->child_err,
- attr->pool)) != APR_SUCCESS) {
- return status;
- }
-
- switch (err) {
- case APR_FULL_BLOCK:
- break;
- case APR_PARENT_BLOCK:
- apr_file_pipe_timeout_set(attr->child_err, 0);
- break;
- case APR_CHILD_BLOCK:
- apr_file_pipe_timeout_set(attr->parent_err, 0);
- break;
- default:
- apr_file_pipe_timeout_set(attr->child_err, 0);
- apr_file_pipe_timeout_set(attr->parent_err, 0);
- }
+ if ((rv = apr_file_pipe_create_ex(&attr->parent_err, &attr->child_err,
+ err, attr->pool)) != APR_SUCCESS)
+ return rv;
}
- else if (err == APR_NO_FILE) {
+ else if (err == APR_NO_FILE)
attr->child_err = &no_file;
- }
return APR_SUCCESS;
}
@@ -127,14 +90,23 @@ APR_DECLARE(apr_status_t) apr_procattr_child_in_set(apr_procattr_t *attr,
{
apr_status_t rv = APR_SUCCESS;
- if (attr->child_in == NULL && attr->parent_in == NULL)
+ if (attr->child_in == NULL && attr->parent_in == NULL
+ && child_in == NULL && parent_in == NULL)
rv = apr_file_pipe_create(&attr->child_in, &attr->parent_in, attr->pool);
- if (child_in != NULL && rv == APR_SUCCESS)
- rv = apr_file_dup2(attr->child_in, child_in, attr->pool);
+ if (child_in != NULL && rv == APR_SUCCESS) {
+ if (attr->child_in && (attr->child_in->filedes != -1))
+ rv = apr_file_dup2(attr->child_in, child_in, attr->pool);
+ else
+ rv = apr_file_dup(&attr->child_in, child_in, attr->pool);
+ }
- if (parent_in != NULL && rv == APR_SUCCESS)
- rv = apr_file_dup2(attr->parent_in, parent_in, attr->pool);
+ if (parent_in != NULL && rv == APR_SUCCESS) {
+ if (attr->parent_in)
+ rv = apr_file_dup2(attr->parent_in, parent_in, attr->pool);
+ else
+ rv = apr_file_dup(&attr->parent_in, parent_in, attr->pool);
+ }
return rv;
}
@@ -146,14 +118,23 @@ APR_DECLARE(apr_status_t) apr_procattr_child_out_set(apr_procattr_t *attr,
{
apr_status_t rv = APR_SUCCESS;
- if (attr->child_out == NULL && attr->parent_out == NULL)
+ if (attr->child_out == NULL && attr->parent_out == NULL
+ && child_out == NULL && parent_out == NULL)
rv = apr_file_pipe_create(&attr->child_out, &attr->parent_out, attr->pool);
- if (child_out != NULL && rv == APR_SUCCESS)
- rv = apr_file_dup2(attr->child_out, child_out, attr->pool);
+ if (child_out != NULL && rv == APR_SUCCESS) {
+ if (attr->child_out && (attr->child_out->filedes != -1))
+ rv = apr_file_dup2(attr->child_out, child_out, attr->pool);
+ else
+ rv = apr_file_dup(&attr->child_out, child_out, attr->pool);
+ }
- if (parent_out != NULL && rv == APR_SUCCESS)
- rv = apr_file_dup2(attr->parent_out, parent_out, attr->pool);
+ if (parent_out != NULL && rv == APR_SUCCESS) {
+ if (attr->parent_out)
+ rv = apr_file_dup2(attr->parent_out, parent_out, attr->pool);
+ else
+ rv = apr_file_dup(&attr->parent_out, parent_out, attr->pool);
+ }
return rv;
}
@@ -165,14 +146,22 @@ APR_DECLARE(apr_status_t) apr_procattr_child_err_set(apr_procattr_t *attr,
{
apr_status_t rv = APR_SUCCESS;
- if (attr->child_err == NULL && attr->parent_err == NULL)
+ if (attr->child_err == NULL && attr->parent_err == NULL
+ && child_err == NULL && parent_err == NULL)
rv = apr_file_pipe_create(&attr->child_err, &attr->parent_err, attr->pool);
- if (child_err != NULL && rv == APR_SUCCESS)
- rv = apr_file_dup2(attr->child_err, child_err, attr->pool);
-
- if (parent_err != NULL && rv == APR_SUCCESS)
- rv = apr_file_dup2(attr->parent_err, parent_err, attr->pool);
+ if (child_err != NULL && rv == APR_SUCCESS) {
+ if (attr->child_err && (attr->child_err->filedes != -1))
+ rv = apr_file_dup2(attr->child_err, child_err, attr->pool);
+ else
+ rv = apr_file_dup(&attr->child_err, child_err, attr->pool);
+ }
+ if (parent_err != NULL && rv == APR_SUCCESS) {
+ if (attr->parent_err)
+ rv = apr_file_dup2(attr->parent_err, parent_err, attr->pool);
+ else
+ rv = apr_file_dup(&attr->parent_err, parent_err, attr->pool);
+ }
return rv;
}