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 ---- daver...@acm.org "So why don't you make like a tree, and get outta here." -- Biff in "Back to the Future"
/*********************************************************************** * 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; }
-- 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