Hello,
While debugging a zip bug (http://pecl.php.net/bugs/bug.php?id=9278),
I was wondering what's the difference between CLI/CGI and ISAPI or
Apache2. The same code works perfectly in CLI and CGI on windows and
using all SAPIs on linux (apache1 or 2, cli, cgi). It was not that
obvious, even after having read the MS manual.
The problem seems to be the default mode for the file operation and
the binary mode being ignored by windows ("rb" or "wb").
We only force the default mode in Embed, CLI and CGI. I would suggest
to do it as well in all SAPIs:
./sapi/cgi/cgi_main.c:1042: _fmode = _O_BINARY; /* sets default
for file streams to binary */
./sapi/cli/php_cli.c:626: _fmode = _O_BINARY;
/*sets default for file streams to binary */
./sapi/embed/php_embed.c:157: _fmode = _O_BINARY;
/*sets default for file streams to binary */
_fmode is global per process. We should set the mode of stdin/out:
_setmode( _fileno( stdin ), _O_BINARY );
If we need it and if it is already opened when we init the SAPI, but
someone has to verify this point.
I do not have the time to test it now, but it should also solve a
couple of other issues in HEAD. I can write a patch and commit if we
agree on this fix.
Thanks for your upcoming comments,
--Pierre
[1] http://msdn2.microsoft.com/en-us/library/z5hh6ee9(VS.80).aspx
_fmode is global per process. We should set the mode of stdin/out:
_setmode( _fileno( stdin ), _O_BINARY );
If we need it and if it is already opened when we init the SAPI, but
someone has to verify this point.
I just checked it, we do set the mode for stderr, in and out.
--Pierre
Hi Dmitry,
I think that changing global behavior (_fmode = _O_BINARY;) is not a good
idea.
May be this code should be removed from CGI and CLI too.
A big -1. It works and is known to work. It has been there since years.
May be we have a bug somewhere and _O_BINARY is not passed to open().
It is a knonw issue on windows (which I did not know). You can check
other projects, they all force the mode using _fmode and _setmode for
std*. As CGI/CLI have proven, it works well with the mode forced to
binary. Or do you have informations telling that we should change that
in CGI/CLI and embed?
Do you think the bug is in CRT?
It is a broken behavior somewhere in the windows API. As far as I can
see, it is not in the public part, I run my code until I reached the
ASM level in the debugger but the mode was correct (try codesearch).
What VC version do you use?
It is a bug in php releases (vc6), and in all my attempts (vc express and 2003).
Unless there is a good reason to do not force the mode, I'm in favour
to do it as well in the other SAPI. We do it in FCGI and CLI which the
most used SAPI on windows, I don't think it is a good idea to
introduce bugs by changing the default mode.
I can fix this problem only in zip (like I have to do it for PECL) by
initializing the mode when I enter a zip function and restore it on
leaving. But it will be a pita and will not solve this problem for any
other extensions relying on the same windows function.
--Pierre
We cannot change it in SAPI where we are not the .exe because we don't
own the process.
Messing with that flag affects the entire process and could break
things at a higher level.
I call this kind of thing "library abuse", where one piece of code
assumes that it is the only consumer of the library. In a modular
application, this is not the case.
I think your actual bug is elsewhere, and that the binary flag isn't
being explicitly set on a stdio file handle somewhere in the zip
library code.
I'm -1 on making this change to the other SAPI.
Incidentally, using stdio is not portable in a server application that
might have more than 255 open files at one time. Best to use the
streams layer throughout if possible.
--Wez.
Hello,
While debugging a zip bug (http://pecl.php.net/bugs/bug.php?id=9278),
I was wondering what's the difference between CLI/CGI and ISAPI or
Apache2. The same code works perfectly in CLI and CGI on windows and
using all SAPIs on linux (apache1 or 2, cli, cgi). It was not that
obvious, even after having read the MS manual.The problem seems to be the default mode for the file operation and
the binary mode being ignored by windows ("rb" or "wb").We only force the default mode in Embed, CLI and CGI. I would suggest
to do it as well in all SAPIs:
./sapi/cgi/cgi_main.c:1042: _fmode = _O_BINARY; /* sets default
for file streams to binary */
./sapi/cli/php_cli.c:626: _fmode = _O_BINARY;
/*sets default for file streams to binary */
./sapi/embed/php_embed.c:157: _fmode = _O_BINARY;
/*sets default for file streams to binary */_fmode is global per process. We should set the mode of stdin/out:
_setmode( _fileno( stdin ), _O_BINARY );
If we need it and if it is already opened when we init the SAPI, but
someone has to verify this point.I do not have the time to test it now, but it should also solve a
couple of other issues in HEAD. I can write a patch and commit if we
agree on this fix.Thanks for your upcoming comments,
--Pierre
[1] http://msdn2.microsoft.com/en-us/library/z5hh6ee9(VS.80).aspx
Hello,
We cannot change it in SAPI where we are not the .exe because we don't
own the process.
Messing with that flag affects the entire process and could break
things at a higher level.I call this kind of thing "library abuse", where one piece of code
assumes that it is the only consumer of the library. In a modular
application, this is not the case.I think your actual bug is elsewhere, and that the binary flag isn't
being explicitly set on a stdio file handle somewhere in the zip
library code.
As I said, it uses "b" everywhere. It is a windows bug. Many other
projects do the same trick to get the problem solved. I'm not sure if
it affects the non binary mode or if it only fixes the binary mode. I
think fopen still works as expected in non binary mode.
I'm -1 on making this change to the other SAPI.
Why do we use it in FGCI, CLI and embed? The impact on the other
libraries used by the PHP process is the same, even if it does not
affect the server.
Incidentally, using stdio is not portable in a server application that
might have more than 255 open files at one time. Best to use the
streams layer throughout if possible.
Not possible right now but it is in the Todo, I'm not sure it will fix
the problem either, unless I use parse_mode and php_stream_fopen();
--Pierre
Hello,
We cannot change it in SAPI where we are not the .exe because we don't
own the process.
Messing with that flag affects the entire process and could break
things at a higher level.I call this kind of thing "library abuse", where one piece of code
assumes that it is the only consumer of the library. In a modular
application, this is not the case.
I just commited a better fix. At least it has no impact on other
functions in the same process. However I still think that we have a
problem here, we were only lucky until now :)
--Pierre