APR doesn't seem to currently offer a buffered stdin/stdout/stderr. (Or
am I missing something?)

Unfortunately the lack of a buffered stdin is killing an application I'm
porting to APR (httpd's support/logresolve.c).

The attached patch implements some;

        apr_file_open_buffered_std(in|out|err)

functions. 

-- 
Colm MacCárthaigh                        Public Key: [EMAIL PROTECTED]
Index: include/apr_file_io.h
===================================================================
--- include/apr_file_io.h       (revision 279021)
+++ include/apr_file_io.h       (working copy)
@@ -304,12 +304,13 @@
 APR_DECLARE(apr_status_t) apr_file_open_stderr(apr_file_t **thefile,
                                                apr_pool_t *pool);
 
+
 /**
  * open standard output as an apr file pointer.
  * @param thefile The apr file to use as stdout.
  * @param pool The pool to allocate the file out of.
  * 
- * @remark See remarks for apr_file_open_stdout.
+ * @remark See remarks for apr_file_open_stderr.
  */
 APR_DECLARE(apr_status_t) apr_file_open_stdout(apr_file_t **thefile,
                                                apr_pool_t *pool);
@@ -319,12 +320,51 @@
  * @param thefile The apr file to use as stdin.
  * @param pool The pool to allocate the file out of.
  * 
- * @remark See remarks for apr_file_open_stdout.
+ * @remark See remarks for apr_file_open_stderr.
  */
 APR_DECLARE(apr_status_t) apr_file_open_stdin(apr_file_t **thefile,
                                               apr_pool_t *pool);
 
 /**
+ * Open standard error as a buffered apr file pointer.
+ * @param thefile The apr file to use as stderr.
+ * @param pool The pool to allocate the file out of.
+ * 
+ * @remark The only reason that the apr_file_open_std* functions exist
+ * is that you may not always have a stderr/out/in on Windows.  This
+ * is generally a problem with newer versions of Windows and services.
+ * 
+ * @remark The other problem is that the C library functions generally work
+ * differently on Windows and Unix.  So, by using apr_file_open_std*
+ * functions, you can get a handle to an APR struct that works with
+ * the APR functions which are supposed to work identically on all
+ * platforms.
+ */
+APR_DECLARE(apr_status_t) apr_file_open_buffered_stderr(apr_file_t **thefile,
+                                                        apr_pool_t *pool);
+
+/**
+ * open standard output as a buffered apr file pointer.
+ * @param thefile The apr file to use as stdout.
+ * @param pool The pool to allocate the file out of.
+ * 
+ * @remark See remarks for apr_file_open_buffered_stderr.
+ */
+APR_DECLARE(apr_status_t) apr_file_open_buffered_stdout(apr_file_t **thefile,
+                                                        apr_pool_t *pool);
+
+/**
+ * open standard input as a buffered apr file pointer.
+ * @param thefile The apr file to use as stdin.
+ * @param pool The pool to allocate the file out of.
+ * 
+ * @remark See remarks for apr_file_open_buffered_stderr.
+ */
+APR_DECLARE(apr_status_t) apr_file_open_buffered_stdin(apr_file_t **thefile,
+                                                       apr_pool_t *pool);
+
+
+/**
  * Read data from the specified file.
  * @param thefile The file descriptor to read from.
  * @param buf The buffer to store the data to.
Index: file_io/win32/open.c
===================================================================
--- file_io/win32/open.c        (revision 279021)
+++ file_io/win32/open.c        (working copy)
@@ -627,6 +627,69 @@
 #endif
 }
 
+APR_DECLARE(apr_status_t) apr_file_open_buffered_stderr(apr_file_t **thefile, 
apr_pool_t *pool)
+{
+#ifdef _WIN32_WCE
+    return APR_ENOTIMPL;
+#else
+    apr_os_file_t file_handle;
+
+    apr_set_os_error(APR_SUCCESS);
+    file_handle = GetStdHandle(STD_ERROR_HANDLE);
+    if (!file_handle || (file_handle == INVALID_HANDLE_VALUE)) {
+        apr_status_t rv = apr_get_os_error();
+        if (rv == APR_SUCCESS) {
+            return APR_EINVAL;
+        }
+        return rv;
+    }
+
+    return apr_os_file_put(thefile, &file_handle, APR_FOPEN_BUFFERED, pool);
+#endif
+}
+
+APR_DECLARE(apr_status_t) apr_file_open_buffered_stdout(apr_file_t **thefile, 
apr_pool_t *pool)
+{
+#ifdef _WIN32_WCE
+    return APR_ENOTIMPL;
+#else
+    apr_os_file_t file_handle;
+
+    apr_set_os_error(APR_SUCCESS);
+    file_handle = GetStdHandle(STD_OUTPUT_HANDLE);
+    if (!file_handle || (file_handle == INVALID_HANDLE_VALUE)) {
+        apr_status_t rv = apr_get_os_error();
+        if (rv == APR_SUCCESS) {
+            return APR_EINVAL;
+        }
+        return rv;
+    }
+
+    return apr_os_file_put(thefile, &file_handle, APR_FOPEN_BUFFERED, pool);
+#endif
+}
+
+APR_DECLARE(apr_status_t) apr_file_open_buffered_stdin(apr_file_t **thefile, 
apr_pool_t *pool)
+{
+#ifdef _WIN32_WCE
+    return APR_ENOTIMPL;
+#else
+    apr_os_file_t file_handle;
+
+    apr_set_os_error(APR_SUCCESS);
+    file_handle = GetStdHandle(STD_INPUT_HANDLE);
+    if (!file_handle || (file_handle == INVALID_HANDLE_VALUE)) {
+        apr_status_t rv = apr_get_os_error();
+        if (rv == APR_SUCCESS) {
+            return APR_EINVAL;
+        }
+        return rv;
+    }
+
+    return apr_os_file_put(thefile, &file_handle, APR_FOPEN_BUFFERED, pool);
+#endif
+}
+
 APR_POOL_IMPLEMENT_ACCESSOR(file);
 
 APR_IMPLEMENT_INHERIT_SET(file, flags, pool, file_cleanup)
Index: file_io/os2/open.c
===================================================================
--- file_io/os2/open.c  (revision 279021)
+++ file_io/os2/open.c  (working copy)
@@ -237,6 +237,27 @@
     return apr_os_file_put(thefile, &fd, 0, pool);
 }
 
+APR_DECLARE(apr_status_t) apr_file_open_buffered_stderr(apr_file_t **thefile, 
apr_pool_t *pool)
+{
+    apr_os_file_t fd = 2;
+
+    return apr_os_file_put(thefile, &fd, APR_FOPEN_BUFFERED, pool);
+}
+
+APR_DECLARE(apr_status_t) apr_file_open_buffered_stdout(apr_file_t **thefile, 
apr_pool_t *pool)
+{
+    apr_os_file_t fd = 1;
+
+    return apr_os_file_put(thefile, &fd, APR_FOPEN_BUFFERED, pool);
+}
+
+APR_DECLARE(apr_status_t) apr_file_open_buffered_stdin(apr_file_t **thefile, 
apr_pool_t *pool)
+{
+    apr_os_file_t fd = 0;
+
+    return apr_os_file_put(thefile, &fd, APR_FOPEN_BUFFERED, pool);
+}
+
 APR_POOL_IMPLEMENT_ACCESSOR(file);
 
 APR_IMPLEMENT_INHERIT_SET(file, flags, pool, apr_file_cleanup)
Index: file_io/unix/open.c
===================================================================
--- file_io/unix/open.c (revision 279021)
+++ file_io/unix/open.c (working copy)
@@ -286,6 +286,30 @@
     return apr_os_file_put(thefile, &fd, 0, pool);
 }
 
+APR_DECLARE(apr_status_t) apr_file_open_buffered_stderr(apr_file_t **thefile, 
+                                               apr_pool_t *pool)
+{
+    int fd = STDERR_FILENO;
+
+    return apr_os_file_put(thefile, &fd, APR_FOPEN_BUFFERED, pool);
+}
+
+APR_DECLARE(apr_status_t) apr_file_open_buffered_stdout(apr_file_t **thefile, 
+                                               apr_pool_t *pool)
+{
+    int fd = STDOUT_FILENO;
+
+    return apr_os_file_put(thefile, &fd, APR_FOPEN_BUFFERED, pool);
+}
+
+APR_DECLARE(apr_status_t) apr_file_open_buffered_stdin(apr_file_t **thefile, 
+                                              apr_pool_t *pool)
+{
+    int fd = STDIN_FILENO;
+
+    return apr_os_file_put(thefile, &fd, APR_FOPEN_BUFFERED, pool);
+}
+
 APR_IMPLEMENT_INHERIT_SET(file, flags, pool, apr_unix_file_cleanup)
 
 APR_IMPLEMENT_INHERIT_UNSET(file, flags, pool, apr_unix_file_cleanup)

Reply via email to