wrowe 2003/01/24 09:15:56
Modified: file_io/win32 pipe.c
include/arch/win32 apr_arch_file_io.h
threadproc/win32 proc.c
Log:
Eliminate open_nt_process_pipe and give apr_create_nt_pipe a very similar
blocking argument. Fixes mixed blocking modes for the child stdin pipe
and creates full blocking pipes with apr_file_pipe_create, just as on Unix.
Corrects the bug introduced in file_io/win32/pipe.c rev 1.46 - as process
std handles should never be created async (nonblocking, or overlapped.)
Revision Changes Path
1.50 +8 -5 apr/file_io/win32/pipe.c
Index: pipe.c
===================================================================
RCS file: /home/cvs/apr/file_io/win32/pipe.c,v
retrieving revision 1.49
retrieving revision 1.50
diff -u -r1.49 -r1.50
--- pipe.c 7 Jan 2003 00:52:54 -0000 1.49
+++ pipe.c 24 Jan 2003 17:15:55 -0000 1.50
@@ -89,7 +89,8 @@
APR_DECLARE(apr_status_t) apr_file_pipe_create(apr_file_t **in, apr_file_t
**out, apr_pool_t *p)
{
- return apr_create_nt_pipe(in, out, TRUE, TRUE, p);
+ /* Unix creates full blocking pipes. */
+ return apr_create_nt_pipe(in, out, APR_FULL_BLOCK, p);
}
/* apr_create_nt_pipe()
@@ -111,7 +112,7 @@
* have to poll the pipe to detect i/o on a non-blocking pipe.
*/
apr_status_t apr_create_nt_pipe(apr_file_t **in, apr_file_t **out,
- BOOLEAN bAsyncRead, BOOLEAN bAsyncWrite,
+ apr_int32_t blocking_mode,
apr_pool_t *p)
{
#ifdef _WIN32_WCE
@@ -156,7 +157,8 @@
if (apr_os_level >= APR_WIN_NT) {
/* Create the read end of the pipe */
dwOpenMode = PIPE_ACCESS_INBOUND;
- if (bAsyncRead) {
+ if (blocking_mode == APR_WRITE_BLOCK /* READ_NONBLOCK */
+ || blocking_mode == APR_FULL_NONBLOCK) {
dwOpenMode |= FILE_FLAG_OVERLAPPED;
(*in)->pOverlapped = (OVERLAPPED*) apr_pcalloc(p,
sizeof(OVERLAPPED));
(*in)->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE,
NULL);
@@ -164,7 +166,7 @@
dwPipeMode = 0;
- sprintf(name, "\\\\.\\pipe\\%d.%d", getpid(), id++);
+ sprintf(name, "\\\\.\\pipe\\apr-pipe-%u.%lu", getpid(), id++);
(*in)->filehand = CreateNamedPipe(name,
dwOpenMode,
@@ -177,7 +179,8 @@
/* Create the write end of the pipe */
dwOpenMode = FILE_ATTRIBUTE_NORMAL;
- if (bAsyncWrite) {
+ if (blocking_mode == APR_READ_BLOCK /* WRITE_NONBLOCK */
+ || blocking_mode == APR_FULL_NONBLOCK) {
dwOpenMode |= FILE_FLAG_OVERLAPPED;
(*out)->pOverlapped = (OVERLAPPED*) apr_pcalloc(p,
sizeof(OVERLAPPED));
(*out)->pOverlapped->hEvent = CreateEvent(NULL, FALSE, FALSE,
NULL);
1.2 +23 -1 apr/include/arch/win32/apr_arch_file_io.h
Index: apr_arch_file_io.h
===================================================================
RCS file: /home/cvs/apr/include/arch/win32/apr_arch_file_io.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- apr_arch_file_io.h 7 Jan 2003 00:52:54 -0000 1.1
+++ apr_arch_file_io.h 24 Jan 2003 17:15:56 -0000 1.2
@@ -282,8 +282,30 @@
/**
* Internal function to create a Win32/NT pipe that respects some async
* timeout options.
+ * @param in new read end of the created pipe
+ * @param out new write end of the created pipe
+ * @param blocking_mode one of
+ * <pre>
+ * APR_FULL_BLOCK
+ * APR_READ_BLOCK
+ * APR_WRITE_BLOCK
+ * APR_FULL_NONBLOCK
+ * </pre>
+ * @remark It so happens that APR_FULL_BLOCK and APR_FULL_NONBLOCK
+ * are common to apr_procattr_io_set() in, out and err modes.
+ * Because APR_CHILD_BLOCK and APR_WRITE_BLOCK share the same value,
+ * as do APR_PARENT_BLOCK and APR_READ_BLOCK, it's possible to use
+ * that value directly for creating the stdout/stderr pipes. When
+ * creating the stdin pipe, the values must be transposed.
+ * @see apr_procattr_io_set
*/
apr_status_t apr_create_nt_pipe(apr_file_t **in, apr_file_t **out,
- BOOLEAN bAsyncRead, BOOLEAN bAsyncWrite,
+ apr_int32_t blocking_mode,
apr_pool_t *p);
+
+/** @see apr_create_nt_pipe */
+#define APR_READ_BLOCK 3
+/** @see apr_create_nt_pipe */
+#define APR_WRITE_BLOCK 4
+
#endif /* ! FILE_IO_H */
1.86 +19 -40 apr/threadproc/win32/proc.c
Index: proc.c
===================================================================
RCS file: /home/cvs/apr/threadproc/win32/proc.c,v
retrieving revision 1.85
retrieving revision 1.86
diff -u -r1.85 -r1.86
--- proc.c 7 Jan 2003 00:52:57 -0000 1.85
+++ proc.c 24 Jan 2003 17:15:56 -0000 1.86
@@ -99,59 +99,38 @@
return APR_SUCCESS;
}
-static apr_status_t open_nt_process_pipe(apr_file_t **read, apr_file_t
**write,
- apr_int32_t iBlockingMode,
- apr_pool_t *pool)
-{
- apr_status_t stat;
- BOOLEAN bAsyncRead, bAsyncWrite;
-
- switch (iBlockingMode) {
- case APR_FULL_BLOCK:
- bAsyncRead = bAsyncWrite = FALSE;
- break;
- case APR_PARENT_BLOCK:
- bAsyncRead = FALSE;
- bAsyncWrite = TRUE;
- break;
- case APR_CHILD_BLOCK:
- bAsyncRead = TRUE;
- bAsyncWrite = FALSE;
- break;
- default:
- bAsyncRead = TRUE;
- bAsyncWrite = TRUE;
- }
- if ((stat = apr_create_nt_pipe(read, write, bAsyncRead, bAsyncWrite,
- pool)) != APR_SUCCESS)
- return stat;
-
- 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_int32_t in,
+ apr_int32_t out,
+ apr_int32_t err)
{
apr_status_t stat = APR_SUCCESS;
if (in) {
- stat = open_nt_process_pipe(&attr->child_in, &attr->parent_in, in,
- attr->pool);
+ /* APR_CHILD_BLOCK maps to APR_WRITE_BLOCK, while
+ * APR_PARENT_BLOCK maps to APR_READ_BLOCK, so we
+ * must transpose the CHILD/PARENT blocking flags
+ * only for the stdin pipe. stdout/stderr naturally
+ * map to the correct mode.
+ */
+ if (in == APR_CHILD_BLOCK)
+ in = APR_READ_BLOCK;
+ else if (in == APR_PARENT_BLOCK)
+ in = APR_WRITE_BLOCK;
+ stat = apr_create_nt_pipe(&attr->child_in, &attr->parent_in, in,
+ attr->pool);
if (stat == APR_SUCCESS)
stat = apr_file_inherit_unset(attr->parent_in);
}
if (out && stat == APR_SUCCESS) {
- stat = open_nt_process_pipe(&attr->parent_out, &attr->child_out, out,
- attr->pool);
+ stat = apr_create_nt_pipe(&attr->parent_out, &attr->child_out, out,
+ attr->pool);
if (stat == APR_SUCCESS)
stat = apr_file_inherit_unset(attr->parent_out);
}
if (err && stat == APR_SUCCESS) {
- stat = open_nt_process_pipe(&attr->parent_err, &attr->child_err, err,
- attr->pool);
+ stat = apr_create_nt_pipe(&attr->parent_err, &attr->child_err, err,
+ attr->pool);
if (stat == APR_SUCCESS)
stat = apr_file_inherit_unset(attr->parent_err);
}