ID: 31363
User updated by: ian at snork dot net
Reported By: ian at snork dot net
-Status: Feedback
+Status: Open
Bug Type: Filesystem function related
Operating System: Debian woody (i386)
PHP Version: 5CVS-2005-03-09
New Comment:
My apologies -- I posted just before your message from
bugs.php.net arrived. :)
http://www.snork.net/flock.diff
Previous Comments:
------------------------------------------------------------------------
[2005-04-05 18:01:34] tony2001@php.net
The URL to the patch would be much better.
------------------------------------------------------------------------
[2005-04-05 17:59:11] ian at snork dot net
Aw, shucks. It's been word-wrapped.
Oh well -- send mail if you need an unmolested copy of the
patch. :)
------------------------------------------------------------------------
[2005-04-05 17:57:55] tony2001@php.net
Please, generate diffs with diff -upd and put them somewhere in the
Net.
Thanks you.
------------------------------------------------------------------------
[2005-04-05 17:53:57] ian at snork dot net
The cause looks to be two separate bugs; here's a patch to
fix both.
*** php5-200504050030.orig/ext/standard/file.c Sun Mar 27
16:30:05 2005
--- php5-200504050030/ext/standard/file.c Tue Apr 5
15:26:08 2005
***************
*** 339,351 ****
/* flock_values contains all possible actions if
(operation & 4) we won't block on the lock */
act = flock_values[act - 1] | (operation & 4 ?
LOCK_NB : 0);
! if (!php_stream_lock(stream, act)) {
if (operation && errno == EWOULDBLOCK &&
arg3 && PZVAL_IS_REF(arg3)) {
Z_LVAL_P(arg3) = 1;
}
! RETURN_TRUE;
}
! RETURN_FALSE;
}
/* }}} */
--- 339,351 ----
/* flock_values contains all possible actions if
(operation & 4) we won't block on the lock */
act = flock_values[act - 1] | (operation & 4 ?
LOCK_NB : 0);
! if (php_stream_lock(stream, act)) {
if (operation && errno == EWOULDBLOCK &&
arg3 && PZVAL_IS_REF(arg3)) {
Z_LVAL_P(arg3) = 1;
}
! RETURN_FALSE;
}
! RETURN_TRUE;
}
/* }}} */
*** php5-200504050030.orig/main/streams/plain_wrapper.c
Thu Oct 28 06:35:19 2004
--- php5-200504050030/main/streams/plain_wrapper.c
Tue Apr 5 15:45:51 2005
***************
*** 578,584 ****
return 0;
}
! if (!flock(fd, value) || (errno ==
EWOULDBLOCK && value & LOCK_NB)) {
data->lock_flag = value;
return 0;
} else {
--- 578,584 ----
return 0;
}
! if (!flock(fd, value)) {
data->lock_flag = value;
return 0;
} else {
------------------------------------------------------------------------
[2005-04-05 01:55:32] maurice at gitaar dot net
I had the same problem. It seems that errno is not reset to zero in the
flock implementation. Therefore the last errno will be used. In case no
other errno-modifying call is made before retrying the flock() call,
the call will conclude in an EWOULDBLOCK situation (my conclusion after
a very quick scan of the code).
Looking with truss on Solaris to the process shows that the first fcntl
call (during which I have already locked the file) returns an EAGAIN
error, meaning that the file was already locked. The second fnctl call
(on the now unlocked file) does not return an error. So the call is
successfull. But the call from the php code does set the $wouldblock
parameter to a true value.
For me a workaround for now is something like this (no error checking
on flock and a bit of pseudo-coded, but the workaround is the important
part):
for (;;)
{
flock($fd, LOCK_EX|LOCK_NB, $wouldblock);
if (! $wouldblock) break;
fopen("/this/is/no/real/file", "r");
}
The fopen() call sets errno to the file not found error, which makes
the flock() call act like the first time it is called. This is not
great coding, but it does work for me till a real fix is implemented in
PHP.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
http://bugs.php.net/31363--
Edit this bug report at http://bugs.php.net/?id=31363&edit=1