You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@httpd.apache.org by Bill Stoddard <st...@raleigh.ibm.com> on 2000/02/15 19:09:08 UTC

dup2() on Windows

Windows does not support a native (non-POSIX) equivalent to dup2, which
means that ap_dupfile() cannot be correctly implemented in APR on Windows.
(ap_dupfile() does a dup or dup2 under the covers, depending on the
arguments passed in. We cannot handle the dup2 case in Windows). Thus,
ap_open_logs is broken for Windows.

I have two solutions available. I can use #ifdef WIN32 blocks in
ap_open_file(), or extend APR with the following new functions:

ap_dup2stderr()
ap_dup2stdin()
ap_dup2stdout()

Windows supports a dup2 like function for the standard I/O functions.
Apache primarily uses dup2 to hook the stdio handles, so this should work
well for Posix implementation of Apache as well.

If I hear no objections (and we don't come up with anything better), I'll
implement this in APR.

Bill

________________________________________________
Bill Stoddard stoddard@raleigh.ibm.com

Come to the first official Apache Software Foundation
Conference!  <http://ApacheCon.Com/>




Re: dup2() on Windows

Posted by Peter 'Luna' Runestig <pe...@runestig.com>.
Ooops, sorry! Didn't read Bill's first post well enough! Never mind my previous post!



Re: dup2() on Windows

Posted by Bill Stoddard <st...@raleigh.ibm.com>.
> I think you could also check out Win32's DuplicateHandle().
> 
DuplicateHandle() will replace dup(), but not dup2(). 

Bill


Re: dup2() on Windows

Posted by jim cox <jc...@superlink.net>.
I think you could also check out Win32's DuplicateHandle().

On Wed, 16 Feb 2000, Peter 'Luna' Runestig wrote:

> > Windows does not support a native (non-POSIX) equivalent to dup2, which
> > means that ap_dupfile() cannot be correctly implemented in APR on Windows.
> 
> Hmmm... There are _dup() and _dup2() calls in Win32. This is from MSDN (haven't tested them though):
> 
> _dup, _dup2
> Create a second handle for an open file (_dup), or reassign a file handle (_dup2).
> 
> int_dup( int handle );
> 
> int _dup2( int handle1, int handle2 );
> 
> Routine Required Header Compatibility 
> _dup <io.h> Win 95, Win NT 
> _dup2 <io.h> Win 95, Win NT 
> 
> For additional compatibility information, see Compatibility in the Introduction.
> 
> Libraries
> 
> LIBC.LIB Single thread static library, retail version 
> LIBCMT.LIB Multithread static library, retail version 
> MSVCRT.LIB Import library for MSVCRT.DLL, retail version 
> 
> Return Value
> 
> _dup returns a new file handle. _dup2 returns 0 to indicate success. If an error occurs, each function returns -1 and sets errno to EBADF if the file handle is invalid, or to EMFILE if no more file handles are available.
> 
> Parameters
> 
> handle, handle1
> 
> Handles referring to open file
> 
> handle2
> 
> Any handle value
> 
> Remarks
> 
> The _dup and _dup2 functions associate a second file handle with a currently open file. These functions can be used to associate a predefined file handle, such as that for stdout, with a different file. Operations on the file can be carried out using either file handle. The type of access allowed for the file is unaffected by the creation of a new handle. _dup returns the next available file handle for the given file._dup2 forces handle2 to refer to the same file as handle1. If handle2 is associated with an open file at the time of the call, that file is closed.
> 
> Both _dup and _dup2 accept file handles as parameters. To pass a stream (FILE *) to either of these functions, use _fileno. The fileno routine returns the file handle currently associated with the given stream. The following example shows how to associate stderr (defined as FILE * in STDIO.H) with a handle:
> 
> cstderr = _dup( _fileno( stderr ));
> 
> Example
> 
> /* DUP.C: This program uses the variable old to save
>  * the original stdout. It then opens a new file named
>  * new and forces stdout to refer to it. Finally, it
>  * restores stdout to its original state.
>  */
> 
> #include <io.h>
> #include <stdlib.h>
> #include <stdio.h>
> 
> void main( void )
> {
>    int old;
>    FILE *new;
> 
>    old = _dup( 1 );   /* "old" now refers to "stdout" */
>                       /* Note:  file handle 1 == "stdout" */
>    if( old == -1 )
>    {
>       perror( "_dup( 1 ) failure" );
>       exit( 1 );
>    }
>    write( old, "This goes to stdout first\r\n", 27 );
>    if( ( new = fopen( "data", "w" ) ) == NULL )
>    {
>       puts( "Can't open file 'data'\n" );
>       exit( 1 );
>    }
> 
>    /* stdout now refers to file "data" */
>    if( -1 == _dup2( _fileno( new ), 1 ) )
>    {
>       perror( "Can't _dup2 stdout" );
>       exit( 1 );
>    }
>    puts( "This goes to file 'data'\r\n" );
> 
>    /* Flush stdout stream buffer so it goes to correct file */
>    fflush( stdout );
>    fclose( new );
> 
>    /* Restore original stdout */
>    _dup2( old, 1 );
>    puts( "This goes to stdout\n" );
>    puts( "The file 'data' contains:" );
>    system( "type data" );
> }
> 
> 
> Output
> 
> This goes to stdout first
> This goes to file 'data'
> 
> This goes to stdout
> 
> The file 'data' contains:
> 
> This goes to file 'data'
> 
> 
> 


Re: dup2() on Windows

Posted by Peter 'Luna' Runestig <pe...@runestig.com>.
> Windows does not support a native (non-POSIX) equivalent to dup2, which
> means that ap_dupfile() cannot be correctly implemented in APR on Windows.

Hmmm... There are _dup() and _dup2() calls in Win32. This is from MSDN (haven't tested them though):

_dup, _dup2
Create a second handle for an open file (_dup), or reassign a file handle (_dup2).

int_dup( int handle );

int _dup2( int handle1, int handle2 );

Routine Required Header Compatibility 
_dup <io.h> Win 95, Win NT 
_dup2 <io.h> Win 95, Win NT 

For additional compatibility information, see Compatibility in the Introduction.

Libraries

LIBC.LIB Single thread static library, retail version 
LIBCMT.LIB Multithread static library, retail version 
MSVCRT.LIB Import library for MSVCRT.DLL, retail version 

Return Value

_dup returns a new file handle. _dup2 returns 0 to indicate success. If an error occurs, each function returns -1 and sets errno to EBADF if the file handle is invalid, or to EMFILE if no more file handles are available.

Parameters

handle, handle1

Handles referring to open file

handle2

Any handle value

Remarks

The _dup and _dup2 functions associate a second file handle with a currently open file. These functions can be used to associate a predefined file handle, such as that for stdout, with a different file. Operations on the file can be carried out using either file handle. The type of access allowed for the file is unaffected by the creation of a new handle. _dup returns the next available file handle for the given file._dup2 forces handle2 to refer to the same file as handle1. If handle2 is associated with an open file at the time of the call, that file is closed.

Both _dup and _dup2 accept file handles as parameters. To pass a stream (FILE *) to either of these functions, use _fileno. The fileno routine returns the file handle currently associated with the given stream. The following example shows how to associate stderr (defined as FILE * in STDIO.H) with a handle:

cstderr = _dup( _fileno( stderr ));

Example

/* DUP.C: This program uses the variable old to save
 * the original stdout. It then opens a new file named
 * new and forces stdout to refer to it. Finally, it
 * restores stdout to its original state.
 */

#include <io.h>
#include <stdlib.h>
#include <stdio.h>

void main( void )
{
   int old;
   FILE *new;

   old = _dup( 1 );   /* "old" now refers to "stdout" */
                      /* Note:  file handle 1 == "stdout" */
   if( old == -1 )
   {
      perror( "_dup( 1 ) failure" );
      exit( 1 );
   }
   write( old, "This goes to stdout first\r\n", 27 );
   if( ( new = fopen( "data", "w" ) ) == NULL )
   {
      puts( "Can't open file 'data'\n" );
      exit( 1 );
   }

   /* stdout now refers to file "data" */
   if( -1 == _dup2( _fileno( new ), 1 ) )
   {
      perror( "Can't _dup2 stdout" );
      exit( 1 );
   }
   puts( "This goes to file 'data'\r\n" );

   /* Flush stdout stream buffer so it goes to correct file */
   fflush( stdout );
   fclose( new );

   /* Restore original stdout */
   _dup2( old, 1 );
   puts( "This goes to stdout\n" );
   puts( "The file 'data' contains:" );
   system( "type data" );
}


Output

This goes to stdout first
This goes to file 'data'

This goes to stdout

The file 'data' contains:

This goes to file 'data'




Re: dup2() on Windows

Posted by David Reid <dr...@jetnet.co.uk>.
+1

Sounds like a good idea and if it helps...

david
----- Original Message -----
From: "Bill Stoddard" <st...@raleigh.ibm.com>
To: <ne...@apache.org>
Sent: Tuesday, February 15, 2000 6:09 PM
Subject: dup2() on Windows


> Windows does not support a native (non-POSIX) equivalent to dup2, which
> means that ap_dupfile() cannot be correctly implemented in APR on Windows.
> (ap_dupfile() does a dup or dup2 under the covers, depending on the
> arguments passed in. We cannot handle the dup2 case in Windows). Thus,
> ap_open_logs is broken for Windows.
>
> I have two solutions available. I can use #ifdef WIN32 blocks in
> ap_open_file(), or extend APR with the following new functions:
>
> ap_dup2stderr()
> ap_dup2stdin()
> ap_dup2stdout()
>
> Windows supports a dup2 like function for the standard I/O functions.
> Apache primarily uses dup2 to hook the stdio handles, so this should work
> well for Posix implementation of Apache as well.
>
> If I hear no objections (and we don't come up with anything better), I'll
> implement this in APR.
>
> Bill
>
> ________________________________________________
> Bill Stoddard stoddard@raleigh.ibm.com
>
> Come to the first official Apache Software Foundation
> Conference!  <http://ApacheCon.Com/>
>
>
>
>


Re: dup2() on Windows

Posted by Bill Stoddard <st...@raleigh.ibm.com>.
> I hate the whole idea of these functions.  :-)
I knew you would :-)

> The fact that they are
> necessary is absolutely horrid.  I question if they really are.  Are you
> telling me, if I have two open handles on Windows, I can't make them point
> to the same file?
If it's possible, I don't know how to do it. I don't think it is possible.
The only thing close to this is the SetStdHandle() call which allows you to
change the handle to stdio. For example, I can call
SetStdHandle(STD_ERROR_HANDLE, hErrorLog) to cause the error log to
intercept data directed to stderr.

>
> Regardless, is the dup2 semantic important to Windows?
Yes. In ap_open_logs, we redirect stderr out to the error log. That is the
case that is important to Apache on Windows that is handled by
ap_dup2stderr().
> Can we accomplish
> the same thing with the other semantic of ap_dupfile?
I don't think so.

> However, if we add ap_dup2std(err|in|out), those functions will always be
> in APR, so I am -1 for adding those to APR.  I would rather see #ifdefs in
> http_log until M$ wakes up and adds some functions to their API.
Better not hold your breath. I figured there'd be opposition, which is why I
mailed the note.  BTW, you will have the same problem on other platforms
that do not support dup2 (if there are any). For now, I'll #ifdef WIN32 it
unless another dup2 deficient platform pops up, at which time I'll consider
creating a feature macro.

Bill



Re: dup2() on Windows

Posted by rb...@apache.org.
> Windows does not support a native (non-POSIX) equivalent to dup2, which
> means that ap_dupfile() cannot be correctly implemented in APR on Windows.
> (ap_dupfile() does a dup or dup2 under the covers, depending on the
> arguments passed in. We cannot handle the dup2 case in Windows). Thus,
> ap_open_logs is broken for Windows.
> 
> I have two solutions available. I can use #ifdef WIN32 blocks in
> ap_open_file(), or extend APR with the following new functions:
> 
> ap_dup2stderr()
> ap_dup2stdin()
> ap_dup2stdout()
> 
 
I hate the whole idea of these functions.  :-)  The fact that they are
necessary is absolutely horrid.  I question if they really are.  Are you 
telling me, if I have two open handles on Windows, I can't make them point
to the same file?  That is ludicrous, IMHO.

Regardless, is the dup2 semantic important to Windows?  Can we accomplish
the same thing with the other semantic of ap_dupfile?  I'm just asking,
not having a Windows box right now, I can't really investigate much.

However, if we add ap_dup2std(err|in|out), those functions will always be
in APR, so I am -1 for adding those to APR.  I would rather see #ifdefs in
http_log until M$ wakes up and adds some functions to their API.

Ryan

Come to the first official Apache Software Foundation
Conference!!!   <http://ApacheCon.Com/>

_______________________________________________________________________________
Ryan Bloom                        	rbb@ntrnet.net
2121 Stonehenge Dr. Apt #3
Raleigh, NC 27615		Ryan Bloom -- thinker, adventurer, artist,
				     writer, but mostly, friend.
-------------------------------------------------------------------------------