Mail Archives: cygwin/2012/02/18/16:52:24
--------------090003090902050204080406
Content-Type: text/plain; charset=ISO-8859-1
Content-Transfer-Encoding: 7bit
On 2/16/2012 8:04 AM, Corinna Vinschen wrote:
> On Feb 16 07:56, David Rothenberger wrote:
>> On 2/16/2012 6:09 AM, Corinna Vinschen wrote:
>>> I read the Linux man page again (http://linux.die.net/man/2/flock)
>>> and I just hacked the following testcase, based on your flock STC.
>>
>> That sounds pretty close to what the APR test case is doing, as far as I
>> understand.
>>
>>> The testcase is attached. I'm pretty curious what your test is actually
>>> testing.
>>
>> I got to work at my real job all last night, so couldn't extract the STC
>> from the APR test suite. But, here's the test in APR-ese in case you're
>> interested. I'll remove the APRisms as soon as I can to get you another
>> test case.
I've extracted the test case, which is attached.
I must humbly apologize. The test case was actually using fcntl() for
file locking, not flock(). I got thrown off by the name of the test:
"testflock". It seems APR prefers fcntl() for file locking if available.
The attached test works fine for me on Linux, but fails on Cygwin
starting with the 20120215 snapshot.
--
David Rothenberger ---- daveroth AT acm DOT org
"So why don't you make like a tree, and get outta here."
-- Biff in "Back to the Future"
--------------090003090902050204080406
Content-Type: text/plain;
name="stc-fcntl-forkexec.c"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="stc-fcntl-forkexec.c"
/***********************************************************************
* This is a STC to show a process can get an exclusive lock on a file using
* fcntl, even though another process has an exclusive lock.
*
* A parent process uses fcntl to get an exclusive lock. It then
* uses fork/exec to spawn a child of itself, which also tries to get an
* exclusive lock on the file.
*
* If all works correctly, the child should not be able to get the
* lock. However, the child is able to get the lock.
*
* This test was extracted from the APR test suite.
*
* Compile: gcc -Wall -o stc-fcntl-forkexec stc-fcntl-forkexec.c
***********************************************************************/
#define _GNU_SOURCE
#include <sys/types.h>
#include <sys/file.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#define TESTFILE "testfile.lock"
error_t
lock_file (int fd, int cmd)
{
int rc;
struct flock l = { 0 };
int fc;
l.l_whence = SEEK_SET; /* lock from current point */
l.l_start = 0; /* begin lock at this offset */
l.l_len = 0; /* lock to end of file */
l.l_type = F_WRLCK;
fc = cmd;
/* keep trying if fcntl() gets interrupted (by a signal) */
while ((rc = fcntl(fd, fc, &l)) < 0 && errno == EINTR)
continue;
if (rc == -1) {
/* on some Unix boxes (e.g., Tru64), we get EACCES instead
* of EAGAIN; we don't want APR_STATUS_IS_EAGAIN() matching EACCES
* since that breaks other things, so fix up the retcode here
*/
if (errno == EACCES) {
return EAGAIN;
}
return errno;
}
return 0;
}
/* The child */
void
tryread ()
{
int fd;
error_t status;
fd = open (TESTFILE, O_WRONLY, 0666);
if (fd < 0)
{
perror ("child open failed");
exit (2);
}
status = lock_file (fd, F_SETLK);
if (status == 0)
exit(0);
if (status == EAGAIN)
exit(1);
exit(2);
}
int
main (int argc, const char *const *argv)
{
int fd;
const char *args[3];
pid_t pid;
pid_t pstatus;
int exit_int;
if (argc > 1)
{
/* Called to run the child. */
tryread ();
fprintf (stderr, "Should not get here!\n");
return 2;
}
/* Create the lock file. */
fd = open (TESTFILE, O_WRONLY|O_CREAT, 0666);
if (fd < 0)
{
perror ("open failed");
return 1;
}
/* Lock the file. */
if (lock_file (fd, F_SETLKW) != 0)
{
perror ("lock");
return 1;
}
/* Spawn the child reader */
if ((pid = fork ()) < 0)
{
perror ("fork");
return 1;
}
else if (pid == 0) {
/* child */
args[0] = program_invocation_name;
args[1] = "child";
args[2] = NULL;
execl (program_invocation_name, program_invocation_name, "child", NULL);
fprintf (stderr, "execv failed\n");
_exit (2);
}
/* Wait for the child. */
do {
pstatus = waitpid (pid, &exit_int, WUNTRACED);
} while (pstatus < 0 && errno == EINTR);
if (WIFEXITED (exit_int))
{
exit_int = WEXITSTATUS (exit_int);
if (exit_int == 0)
printf ("FAILED: Child was able to get a lock when it shouldn't.\n");
else if (exit_int == 1)
printf ("SUCCESS: Child was not able to get the lock.\n");
else
fprintf (stderr, "Unexpected error from child: %d\n", exit_int);
}
else
fprintf (stderr, "Child did not terminate normally.\n");
/* Close the file */
close (fd);
/* Clean up. */
unlink (TESTFILE);
return 0;
}
--------------090003090902050204080406
Content-Type: text/plain; charset=us-ascii
--
Problem reports: http://cygwin.com/problems.html
FAQ: http://cygwin.com/faq/
Documentation: http://cygwin.com/docs.html
Unsubscribe info: http://cygwin.com/ml/#unsubscribe-simple
--------------090003090902050204080406--
- Raw text -