summaryrefslogtreecommitdiff
path: root/threadproc
diff options
context:
space:
mode:
authorwrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68>2007-10-15 21:30:06 +0000
committerwrowe <wrowe@13f79535-47bb-0310-9956-ffa450edef68>2007-10-15 21:30:06 +0000
commitc3a8c2f73b2194f46baff6a29bcb36232f878e85 (patch)
tree6b1dfb5148af95fbd01884639f806b70399c95e9 /threadproc
parentc71736581d6256dc598f0ef6e535e31f464c0925 (diff)
downloadlibapr-c3a8c2f73b2194f46baff6a29bcb36232f878e85.tar.gz
Backport the std handling improvements to Netware, OS2, BeOS.
These may need massaging and do need review by their respective communities. Note that someone from the OS2 community needs to ping me with resolving the missing apr_arch_inherit.h mess; this should be very easy to translate into DosSetFHState(handle, OPEN_FLAGS_NOINHERIT); bits, but to more thoroughly resolve the issue, we should take it a step further and consider the NT implementation which toggles inheritance on only for handles as they hit proc_create, so that you don't have cross-process handle leakage into the wrong processes. git-svn-id: http://svn.apache.org/repos/asf/apr/apr/trunk@584928 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'threadproc')
-rw-r--r--threadproc/beos/proc.c206
-rw-r--r--threadproc/netware/proc.c223
-rw-r--r--threadproc/os2/proc.c240
3 files changed, 384 insertions, 285 deletions
diff --git a/threadproc/beos/proc.c b/threadproc/beos/proc.c
index 7af73036f..2623b70d1 100644
--- a/threadproc/beos/proc.c
+++ b/threadproc/beos/proc.c
@@ -17,6 +17,11 @@
#include "apr_arch_threadproc.h"
#include "apr_strings.h"
+/* Heavy on no'ops, here's what we want to pass if there is APR_NO_FILE
+ * requested for a specific child handle;
+ */
+static apr_file_t no_file = { NULL, -1, };
+
struct send_pipe {
int in;
int out;
@@ -44,70 +49,53 @@ APR_DECLARE(apr_status_t) apr_procattr_create(apr_procattr_t **new, apr_pool_t *
return APR_SUCCESS;
}
-APR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr, apr_int32_t in,
- apr_int32_t out, apr_int32_t err)
+APR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr,
+ apr_int32_t in,
+ apr_int32_t out,
+ apr_int32_t err)
{
- apr_status_t status;
- if (in != 0) {
- if ((status = apr_file_pipe_create(&attr->child_in, &attr->parent_in,
- attr->pool)) != APR_SUCCESS) {
- return status;
- }
- switch (in) {
- case APR_FULL_BLOCK:
- apr_file_pipe_timeout_set(attr->child_in, -1);
- apr_file_pipe_timeout_set(attr->parent_in, -1);
- break;
- case APR_PARENT_BLOCK:
- apr_file_pipe_timeout_set(attr->child_in, -1);
- break;
- case APR_CHILD_BLOCK:
- apr_file_pipe_timeout_set(attr->parent_in, -1);
- break;
- default:
- break;
- }
- }
- if (out) {
- if ((status = apr_file_pipe_create(&attr->parent_out, &attr->child_out,
- attr->pool)) != APR_SUCCESS) {
- return status;
- }
- switch (out) {
- case APR_FULL_BLOCK:
- apr_file_pipe_timeout_set(attr->child_out, -1);
- apr_file_pipe_timeout_set(attr->parent_out, -1);
- break;
- case APR_PARENT_BLOCK:
- apr_file_pipe_timeout_set(attr->child_out, -1);
- break;
- case APR_CHILD_BLOCK:
- apr_file_pipe_timeout_set(attr->parent_out, -1);
- break;
- default:
- break;
- }
- }
- if (err) {
- if ((status = apr_file_pipe_create(&attr->parent_err, &attr->child_err,
- attr->pool)) != APR_SUCCESS) {
- return status;
- }
- switch (err) {
- case APR_FULL_BLOCK:
- apr_file_pipe_timeout_set(attr->child_err, -1);
- apr_file_pipe_timeout_set(attr->parent_err, -1);
- break;
- case APR_PARENT_BLOCK:
- apr_file_pipe_timeout_set(attr->child_err, -1);
- break;
- case APR_CHILD_BLOCK:
- apr_file_pipe_timeout_set(attr->parent_err, -1);
- break;
- default:
- break;
- }
- }
+ apr_status_t rv;
+
+ 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)
+ rv = apr_file_inherit_unset(attr->parent_in);
+ if (rv != APR_SUCCESS)
+ return rv;
+ }
+ else if (in == APR_NO_FILE)
+ attr->child_in = &no_file;
+
+ if ((out != APR_NO_PIPE) && (out != APR_NO_FILE)) {
+ if ((rv = apr_file_pipe_create_ex(&attr->parent_out, &attr->child_out,
+ out, attr->pool)) == APR_SUCCESS)
+ rv = apr_file_inherit_unset(attr->parent_out);
+ if (rv != APR_SUCCESS)
+ return rv;
+ }
+ else if (out == APR_NO_FILE)
+ attr->child_out = &no_file;
+
+ if ((err != APR_NO_PIPE) && (err != APR_NO_FILE)) {
+ if ((rv = apr_file_pipe_create_ex(&attr->parent_err, &attr->child_err,
+ err, attr->pool)) != APR_SUCCESS)
+ rv = apr_file_inherit_unset(attr->parent_err);
+ if (rv != APR_SUCCESS)
+ return rv;
+ }
+ else if (err == APR_NO_FILE)
+ attr->child_err = &no_file;
+
return APR_SUCCESS;
}
@@ -233,9 +221,9 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new, const char *progname,
new->in = attr->parent_in;
new->err = attr->parent_err;
new->out = attr->parent_out;
- sp->in = attr->child_in ? attr->child_in->filedes : -1;
- sp->out = attr->child_out ? attr->child_out->filedes : -1;
- sp->err = attr->child_err ? attr->child_err->filedes : -1;
+ sp->in = attr->child_in ? attr->child_in->filedes : FILENO_STDIN;
+ sp->out = attr->child_out ? attr->child_out->filedes : FILENO_STDOUT;
+ sp->err = attr->child_err ? attr->child_err->filedes : FILENO_STDERR;
i = 0;
while (args && args[i]) {
@@ -277,13 +265,13 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *new, const char *progname,
resume_thread(newproc);
- if (attr->child_in) {
+ if (attr->child_in && (attr->child_in->filedes != -1)) {
apr_file_close(attr->child_in);
}
- if (attr->child_out) {
+ if (attr->child_out && (attr->child_in->filedes != -1)) {
apr_file_close(attr->child_out);
}
- if (attr->child_err) {
+ if (attr->child_err && (attr->child_in->filedes != -1)) {
apr_file_close(attr->child_err);
}
@@ -357,46 +345,84 @@ APR_DECLARE(apr_status_t) apr_proc_wait(apr_proc_t *proc,
APR_DECLARE(apr_status_t) apr_procattr_child_in_set(apr_procattr_t *attr, apr_file_t *child_in,
apr_file_t *parent_in)
{
- if (attr->child_in == NULL && attr->parent_in == NULL)
- apr_file_pipe_create(&attr->child_in, &attr->parent_in, attr->pool);
+ apr_status_t rv;
- if (child_in != NULL)
- apr_file_dup(&attr->child_in, child_in, attr->pool);
+ if (attr->child_in == NULL && attr->parent_in == NULL
+ && child_in == NULL && parent_in == NULL)
+ if ((rv = apr_file_pipe_create(&attr->child_in, &attr->parent_in,
+ attr->pool)) == APR_SUCCESS)
+ rv = apr_file_inherit_unset(attr->parent_in);
- if (parent_in != NULL)
- apr_file_dup(&attr->parent_in, parent_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 {
+ attr->child_in = NULL;
+ if ((rv = apr_file_dup(&attr->child_in, child_in, attr->pool))
+ == APR_SUCCESS)
+ rv = apr_file_inherit_set(attr->child_in);
+ }
- return APR_SUCCESS;
+ if (parent_in != NULL && rv == APR_SUCCESS) {
+ rv = apr_file_dup(&attr->parent_in, parent_in, attr->pool);
+
+ return rv;
}
APR_DECLARE(apr_status_t) apr_procattr_child_out_set(apr_procattr_t *attr, apr_file_t *child_out,
apr_file_t *parent_out)
{
- if (attr->child_out == NULL && attr->parent_out == NULL)
- apr_file_pipe_create(&attr->child_out, &attr->parent_out, attr->pool);
+ apr_status_t rv;
- if (child_out != NULL)
- apr_file_dup(&attr->child_out, child_out, attr->pool);
+ if (attr->child_out == NULL && attr->parent_out == NULL
+ && child_out == NULL && parent_out == NULL)
+ if ((rv = apr_file_pipe_create(&attr->parent_out, &attr->child_out,
+ attr->pool)) == APR_SUCCESS)
+ rv = apr_file_inherit_unset(attr->parent_out);
- if (parent_out != NULL)
- apr_file_dup(&attr->parent_out, parent_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 {
+ attr->child_out = NULL;
+ if ((rv = apr_file_dup(&attr->child_out, child_out, attr->pool))
+ == APR_SUCCESS)
+ rv = apr_file_inherit_set(attr->child_out);
+ }
+ }
+
+ if (parent_out != NULL && rv == APR_SUCCESS) {
+ rv = apr_file_dup(&attr->parent_out, parent_out, attr->pool);
- return APR_SUCCESS;
+ return rv;
}
APR_DECLARE(apr_status_t) apr_procattr_child_err_set(apr_procattr_t *attr, apr_file_t *child_err,
apr_file_t *parent_err)
{
- if (attr->child_err == NULL && attr->parent_err == NULL)
- apr_file_pipe_create(&attr->child_err, &attr->parent_err, attr->pool);
+ apr_status_t rv;
- if (child_err != NULL)
- apr_file_dup(&attr->child_err, child_err, attr->pool);
+ if (attr->child_err == NULL && attr->parent_err == NULL
+ && child_err == NULL && parent_err == NULL)
+ if ((rv = apr_file_pipe_create(&attr->parent_err, &attr->child_err,
+ attr->pool)) == APR_SUCCESS)
+ rv = apr_file_inherit_unset(attr->parent_err);
- if (parent_err != NULL)
- apr_file_dup(&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 {
+ attr->child_err = NULL;
+ if ((rv = apr_file_dup(&attr->child_err, child_err, attr->pool))
+ == APR_SUCCESS)
+ rv = apr_file_inherit_set(attr->child_err);
+ }
+ }
+
+ if (parent_err != NULL && rv == APR_SUCCESS) {
+ rv = apr_file_dup(&attr->parent_err, parent_err, attr->pool);
- return APR_SUCCESS;
+ return rv;
}
APR_DECLARE(apr_status_t) apr_procattr_limit_set(apr_procattr_t *attr, apr_int32_t what,
diff --git a/threadproc/netware/proc.c b/threadproc/netware/proc.c
index 0f7077699..bed7d2a2a 100644
--- a/threadproc/netware/proc.c
+++ b/threadproc/netware/proc.c
@@ -21,6 +21,11 @@
#include <proc.h>
+/* Heavy on no'ops, here's what we want to pass if there is APR_NO_FILE
+ * requested for a specific child handle;
+ */
+static apr_file_t no_file = { NULL, -1, };
+
apr_status_t apr_netware_proc_cleanup(void *theproc)
{
apr_proc_t *proc = theproc;
@@ -51,67 +56,53 @@ APR_DECLARE(apr_status_t) apr_procattr_create(apr_procattr_t **new,apr_pool_t *p
}
-APR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr, apr_int32_t in,
- apr_int32_t out, apr_int32_t err)
+APR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr,
+ apr_int32_t in,
+ apr_int32_t out,
+ apr_int32_t err)
{
- apr_status_t status;
- if (in != 0) {
- if ((status = apr_file_pipe_create(&attr->child_in, &attr->parent_in,
- attr->pool)) != APR_SUCCESS) {
- return status;
- }
- 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 (out) {
- 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 (err) {
- 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);
- }
- }
+ apr_status_t rv;
+
+ 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)
+ rv = apr_file_inherit_unset(attr->parent_in);
+ if (rv != APR_SUCCESS)
+ return rv;
+ }
+ else if (in == APR_NO_FILE)
+ attr->child_in = &no_file;
+
+ if ((out != APR_NO_PIPE) && (out != APR_NO_FILE)) {
+ if ((rv = apr_file_pipe_create_ex(&attr->parent_out, &attr->child_out,
+ out, attr->pool)) == APR_SUCCESS)
+ rv = apr_file_inherit_unset(attr->parent_out);
+ if (rv != APR_SUCCESS)
+ return rv;
+ }
+ else if (out == APR_NO_FILE)
+ attr->child_out = &no_file;
+
+ if ((err != APR_NO_PIPE) && (err != APR_NO_FILE)) {
+ if ((rv = apr_file_pipe_create_ex(&attr->parent_err, &attr->child_err,
+ err, attr->pool)) != APR_SUCCESS)
+ rv = apr_file_inherit_unset(attr->parent_err);
+ if (rv != APR_SUCCESS)
+ return rv;
+ }
+ else if (err == APR_NO_FILE)
+ attr->child_err = &no_file;
+
return APR_SUCCESS;
}
@@ -119,48 +110,86 @@ APR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr, apr_int32_t
APR_DECLARE(apr_status_t) apr_procattr_child_in_set(apr_procattr_t *attr, apr_file_t *child_in,
apr_file_t *parent_in)
{
- if (attr->child_in == NULL && attr->parent_in == NULL)
- apr_file_pipe_create(&attr->child_in, &attr->parent_in, attr->pool);
+ apr_status_t rv;
- if (child_in != NULL)
- apr_file_dup2(attr->child_in, child_in, attr->pool);
+ if (attr->child_in == NULL && attr->parent_in == NULL
+ && child_in == NULL && parent_in == NULL)
+ if ((rv = apr_file_pipe_create(&attr->child_in, &attr->parent_in,
+ attr->pool)) == APR_SUCCESS)
+ rv = apr_file_inherit_unset(attr->parent_in);
- if (parent_in != NULL)
- apr_file_dup2(attr->parent_in, parent_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 {
+ attr->child_in = NULL;
+ if ((rv = apr_file_dup(&attr->child_in, child_in, attr->pool))
+ == APR_SUCCESS)
+ rv = apr_file_inherit_set(attr->child_in);
+ }
- return APR_SUCCESS;
+ if (parent_in != NULL && rv == APR_SUCCESS) {
+ rv = apr_file_dup(&attr->parent_in, parent_in, attr->pool);
+
+ return rv;
}
APR_DECLARE(apr_status_t) apr_procattr_child_out_set(apr_procattr_t *attr, apr_file_t *child_out,
- apr_file_t *parent_out)
+ apr_file_t *parent_out)
{
- if (attr->child_out == NULL && attr->parent_out == NULL)
- apr_file_pipe_create(&attr->child_out, &attr->parent_out, attr->pool);
+ apr_status_t rv;
- if (child_out != NULL)
- apr_file_dup2(attr->child_out, child_out, attr->pool);
+ if (attr->child_out == NULL && attr->parent_out == NULL
+ && child_out == NULL && parent_out == NULL)
+ if ((rv = apr_file_pipe_create(&attr->parent_out, &attr->child_out,
+ attr->pool)) == APR_SUCCESS)
+ rv = apr_file_inherit_unset(attr->parent_out);
- if (parent_out != NULL)
- apr_file_dup2(attr->parent_out, parent_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 {
+ attr->child_out = NULL;
+ if ((rv = apr_file_dup(&attr->child_out, child_out, attr->pool))
+ == APR_SUCCESS)
+ rv = apr_file_inherit_set(attr->child_out);
+ }
+ }
+
+ if (parent_out != NULL && rv == APR_SUCCESS) {
+ rv = apr_file_dup(&attr->parent_out, parent_out, attr->pool);
- return APR_SUCCESS;
+ return rv;
}
APR_DECLARE(apr_status_t) apr_procattr_child_err_set(apr_procattr_t *attr, apr_file_t *child_err,
- apr_file_t *parent_err)
+ apr_file_t *parent_err)
{
- if (attr->child_err == NULL && attr->parent_err == NULL)
- apr_file_pipe_create(&attr->child_err, &attr->parent_err, attr->pool);
+ apr_status_t rv;
- if (child_err != NULL)
- apr_file_dup2(attr->child_err, child_err, attr->pool);
+ if (attr->child_err == NULL && attr->parent_err == NULL
+ && child_err == NULL && parent_err == NULL)
+ if ((rv = apr_file_pipe_create(&attr->parent_err, &attr->child_err,
+ attr->pool)) == APR_SUCCESS)
+ rv = apr_file_inherit_unset(attr->parent_err);
- if (parent_err != NULL)
- 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 {
+ attr->child_err = NULL;
+ if ((rv = apr_file_dup(&attr->child_err, child_err, attr->pool))
+ == APR_SUCCESS)
+ rv = apr_file_inherit_set(attr->child_err);
+ }
+ }
+
+ if (parent_err != NULL && rv == APR_SUCCESS) {
+ rv = apr_file_dup(&attr->parent_err, parent_err, attr->pool);
- return APR_SUCCESS;
+ return rv;
}
@@ -280,12 +309,21 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *newproc,
apr_procattr_t *attr,
apr_pool_t *pool)
{
- wiring_t wire;
- int addr_space;
-
- wire.infd = attr->child_in ? attr->child_in->filedes : FD_UNUSED;
- wire.outfd = attr->child_out ? attr->child_out->filedes : FD_UNUSED;
- wire.errfd = attr->child_err ? attr->child_err->filedes : FD_UNUSED;
+ wiring_t wire;
+ int addr_space;
+
+ wire.infd = attr->child_in
+ ? (attr->child_in->filedes != -1 ? attr->child_in->filedes
+ : FD_UNUSED)
+ : FILENO_STDIN;
+ wire.outfd = attr->child_out
+ ? (attr->child_out->filedes != -1 ? attr->child_out->filedes
+ : FD_UNUSED)
+ : FILENO_STDOUT;
+ wire.errfd = attr->child_err
+ ? (attr->child_err->filedes != -1 ? attr->child_err->filedes
+ : FD_UNUSED)
+ : FILENO_STDERR;
newproc->in = attr->parent_in;
newproc->out = attr->parent_out;
@@ -313,23 +351,22 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *newproc,
return errno;
}
- if (attr->child_in) {
+ if (attr->child_in && (attr->child_in->filedes != -1)) {
apr_pool_cleanup_kill(apr_file_pool_get(attr->child_in),
attr->child_in, apr_unix_file_cleanup);
apr_file_close(attr->child_in);
}
- if (attr->child_out) {
+ if (attr->child_out && (attr->child_out->filedes != -1)) {
apr_pool_cleanup_kill(apr_file_pool_get(attr->child_out),
attr->child_out, apr_unix_file_cleanup);
apr_file_close(attr->child_out);
}
- if (attr->child_err) {
+ if (attr->child_err && (attr->child_err->filedes != -1)) {
apr_pool_cleanup_kill(apr_file_pool_get(attr->child_err),
attr->child_err, apr_unix_file_cleanup);
apr_file_close(attr->child_err);
}
-
apr_pool_cleanup_register(pool, (void *)newproc, apr_netware_proc_cleanup,
apr_pool_cleanup_null);
diff --git a/threadproc/os2/proc.c b/threadproc/os2/proc.c
index 20dfffb8b..9fd9a5f50 100644
--- a/threadproc/os2/proc.c
+++ b/threadproc/os2/proc.c
@@ -34,6 +34,11 @@
#include <process.h>
#include <stdlib.h>
+/* Heavy on no'ops, here's what we want to pass if there is APR_NO_FILE
+ * requested for a specific child handle;
+ */
+static apr_file_t no_file = { NULL, -1, };
+
APR_DECLARE(apr_status_t) apr_procattr_create(apr_procattr_t **new, apr_pool_t *pool)
{
(*new) = (apr_procattr_t *)apr_palloc(pool,
@@ -55,118 +60,139 @@ APR_DECLARE(apr_status_t) apr_procattr_create(apr_procattr_t **new, apr_pool_t *
return APR_SUCCESS;
}
-APR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr, apr_int32_t in,
- apr_int32_t out, apr_int32_t err)
+APR_DECLARE(apr_status_t) apr_procattr_io_set(apr_procattr_t *attr,
+ apr_int32_t in,
+ apr_int32_t out,
+ apr_int32_t err)
{
- apr_status_t stat;
- if (in) {
- if ((stat = apr_file_pipe_create(&attr->child_in, &attr->parent_in,
- attr->pool)) != APR_SUCCESS) {
- return stat;
- }
- 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 (out) {
- if ((stat = apr_file_pipe_create(&attr->parent_out, &attr->child_out,
- attr->pool)) != APR_SUCCESS) {
- return stat;
- }
- 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 (err) {
- if ((stat = apr_file_pipe_create(&attr->parent_err, &attr->child_err,
- attr->pool)) != APR_SUCCESS) {
- return stat;
- }
- 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);
- }
- }
+ apr_status_t rv;
+
+ 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)
+ rv = apr_file_inherit_unset(attr->parent_in);
+ if (rv != APR_SUCCESS)
+ return rv;
+ }
+ else if (in == APR_NO_FILE)
+ attr->child_in = &no_file;
+
+ if ((out != APR_NO_PIPE) && (out != APR_NO_FILE)) {
+ if ((rv = apr_file_pipe_create_ex(&attr->parent_out, &attr->child_out,
+ out, attr->pool)) == APR_SUCCESS)
+ rv = apr_file_inherit_unset(attr->parent_out);
+ if (rv != APR_SUCCESS)
+ return rv;
+ }
+ else if (out == APR_NO_FILE)
+ attr->child_out = &no_file;
+
+ if ((err != APR_NO_PIPE) && (err != APR_NO_FILE)) {
+ if ((rv = apr_file_pipe_create_ex(&attr->parent_err, &attr->child_err,
+ err, attr->pool)) != APR_SUCCESS)
+ rv = apr_file_inherit_unset(attr->parent_err);
+ if (rv != APR_SUCCESS)
+ return rv;
+ }
+ else if (err == APR_NO_FILE)
+ attr->child_err = &no_file;
+
return APR_SUCCESS;
}
APR_DECLARE(apr_status_t) apr_procattr_child_in_set(apr_procattr_t *attr, apr_file_t *child_in,
- apr_file_t *parent_in)
+ apr_file_t *parent_in)
{
- if (attr->child_in == NULL && attr->parent_in == NULL)
- apr_file_pipe_create(&attr->child_in, &attr->parent_in, attr->pool);
-
- if (child_in != NULL)
- apr_file_dup(&attr->child_in, child_in, attr->pool);
+ apr_status_t rv;
+
+ if (attr->child_in == NULL && attr->parent_in == NULL
+ && child_in == NULL && parent_in == NULL)
+ if ((rv = apr_file_pipe_create(&attr->child_in, &attr->parent_in,
+ attr->pool)) == APR_SUCCESS)
+ rv = apr_file_inherit_unset(attr->parent_in);
+
+ 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 {
+ attr->child_in = NULL;
+ if ((rv = apr_file_dup(&attr->child_in, child_in, attr->pool))
+ == APR_SUCCESS)
+ rv = apr_file_inherit_set(attr->child_in);
+ }
- if (parent_in != NULL)
- apr_file_dup(&attr->parent_in, parent_in, attr->pool);
+ if (parent_in != NULL && rv == APR_SUCCESS) {
+ rv = apr_file_dup(&attr->parent_in, parent_in, attr->pool);
- return APR_SUCCESS;
+ return rv;
}
-
APR_DECLARE(apr_status_t) apr_procattr_child_out_set(apr_procattr_t *attr, apr_file_t *child_out,
apr_file_t *parent_out)
{
- if (attr->child_out == NULL && attr->parent_out == NULL)
- apr_file_pipe_create(&attr->child_out, &attr->parent_out, attr->pool);
-
- if (child_out != NULL)
- apr_file_dup(&attr->child_out, child_out, attr->pool);
-
- if (parent_out != NULL)
- apr_file_dup(&attr->parent_out, parent_out, attr->pool);
+ apr_status_t rv;
+
+ if (attr->child_out == NULL && attr->parent_out == NULL
+ && child_out == NULL && parent_out == NULL)
+ if ((rv = apr_file_pipe_create(&attr->parent_out, &attr->child_out,
+ attr->pool)) == APR_SUCCESS)
+ rv = apr_file_inherit_unset(attr->parent_out);
+
+ 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 {
+ attr->child_out = NULL;
+ if ((rv = apr_file_dup(&attr->child_out, child_out, attr->pool))
+ == APR_SUCCESS)
+ rv = apr_file_inherit_set(attr->child_out);
+ }
+ }
+
+ if (parent_out != NULL && rv == APR_SUCCESS) {
+ rv = apr_file_dup(&attr->parent_out, parent_out, attr->pool);
- return APR_SUCCESS;
+ return rv;
}
-
APR_DECLARE(apr_status_t) apr_procattr_child_err_set(apr_procattr_t *attr, apr_file_t *child_err,
apr_file_t *parent_err)
{
- if (attr->child_err == NULL && attr->parent_err == NULL)
- apr_file_pipe_create(&attr->child_err, &attr->parent_err, attr->pool);
-
- if (child_err != NULL)
- apr_file_dup(&attr->child_err, child_err, attr->pool);
-
- if (parent_err != NULL)
- apr_file_dup(&attr->parent_err, parent_err, attr->pool);
+ apr_status_t rv;
+
+ if (attr->child_err == NULL && attr->parent_err == NULL
+ && child_err == NULL && parent_err == NULL)
+ if ((rv = apr_file_pipe_create(&attr->parent_err, &attr->child_err,
+ attr->pool)) == APR_SUCCESS)
+ rv = apr_file_inherit_unset(attr->parent_err);
+
+ 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 {
+ attr->child_err = NULL;
+ if ((rv = apr_file_dup(&attr->child_err, child_err, attr->pool))
+ == APR_SUCCESS)
+ rv = apr_file_inherit_set(attr->child_err);
+ }
+ }
+
+ if (parent_err != NULL && rv == APR_SUCCESS) {
+ rv = apr_file_dup(&attr->parent_err, parent_err, attr->pool);
- return APR_SUCCESS;
+ return rv;
}
-
APR_DECLARE(apr_status_t) apr_procattr_dir_set(apr_procattr_t *attr, const char *dir)
{
attr->currdir = apr_pstrdup(attr->pool, dir);
@@ -284,6 +310,10 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *proc, const char *progname
char *env_block, *env_block_pos;
RESULTCODES rescodes;
+ proc->in = attr->parent_in;
+ proc->err = attr->parent_err;
+ proc->out = attr->parent_out;
+
/* Prevent other threads from running while these process-wide resources are modified */
if (attr->child_in || attr->child_out || attr->child_err || attr->currdir) {
criticalsection = TRUE;
@@ -294,24 +324,30 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *proc, const char *progname
save_in = -1;
DosDupHandle(STDIN_FILENO, &save_in);
dup = STDIN_FILENO;
- DosDupHandle(attr->child_in->filedes, &dup);
- DosSetFHState(attr->parent_in->filedes, OPEN_FLAGS_NOINHERIT);
+ if (attr->child_in->filedes == -1)
+ DosClose(dup);
+ else
+ DosDupHandle(attr->child_in->filedes, &dup);
}
if (attr->child_out) {
save_out = -1;
DosDupHandle(STDOUT_FILENO, &save_out);
dup = STDOUT_FILENO;
- DosDupHandle(attr->child_out->filedes, &dup);
- DosSetFHState(attr->parent_out->filedes, OPEN_FLAGS_NOINHERIT);
+ if (attr->child_out->filedes == -1)
+ DosClose(dup);
+ else
+ DosDupHandle(attr->child_out->filedes, &dup);
}
if (attr->child_err) {
save_err = -1;
DosDupHandle(STDERR_FILENO, &save_err);
dup = STDERR_FILENO;
- DosDupHandle(attr->child_err->filedes, &dup);
- DosSetFHState(attr->parent_err->filedes, OPEN_FLAGS_NOINHERIT);
+ if (attr->child_err->filedes == -1)
+ DosClose(dup);
+ else
+ DosDupHandle(attr->child_err->filedes, &dup);
}
apr_signal(SIGCHLD, SIG_DFL); /*not sure if this is needed or not */
@@ -464,21 +500,24 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *proc, const char *progname
}
if (attr->child_in) {
- apr_file_close(attr->child_in);
+ (attr->child_in->filedes != -1)
+ apr_file_close(attr->child_in);
dup = STDIN_FILENO;
DosDupHandle(save_in, &dup);
DosClose(save_in);
}
if (attr->child_out) {
- apr_file_close(attr->child_out);
+ (attr->child_err->filedes != -1)
+ apr_file_close(attr->child_out);
dup = STDOUT_FILENO;
DosDupHandle(save_out, &dup);
DosClose(save_out);
}
if (attr->child_err) {
- apr_file_close(attr->child_err);
+ (attr->child_err->filedes != -1)
+ apr_file_close(attr->child_err);
dup = STDERR_FILENO;
DosDupHandle(save_err, &dup);
DosClose(save_err);
@@ -487,9 +526,6 @@ APR_DECLARE(apr_status_t) apr_proc_create(apr_proc_t *proc, const char *progname
if (criticalsection)
DosExitCritSec();
- proc->in = attr->parent_in;
- proc->err = attr->parent_err;
- proc->out = attr->parent_out;
return status;
}