This is the mail archive of the
cygwin
mailing list for the Cygwin project.
spawnv() unlocks files in the calling program
- From: "Steven Bardwell" <SBardwell at lbmsys dot com>
- To: <cygwin at cygwin dot com>
- Date: Sun, 9 Feb 2014 13:25:30 -0500
- Subject: spawnv() unlocks files in the calling program
- Authentication-results: sourceware.org; auth=none
- Reply-to: <sbardwell at lbmsys dot com>
I have a simple programs that show the following issue:
1) program locks a file (in my test /tmp/yyy)
2) program then calls spawnv() (in my test "/bin/sh -c /bin/touch
/tmp/xxx").
3) after the spawnv(), the file /tmp/yyy is no longer locked.
It seems to me that this is wrong. Perhaps I am misunderstanding how file
locking works. On the other hand, the file lock is preserved if the child
task is started with posix_spawn() rather than spawnv().
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <process.h>
#include <fcntl.h>
#include <time.h>
#include <spawn.h>
extern char **environ;
main()
{
int status;
pid_t pid, task_pid;
struct flock lock;
const char * argv[] = {"/bin/sh", "-c", "/usr/bin/touch /tmp/xxx", (char
*) 0};
pid = open("/tmp/yyy", O_WRONLY|O_CREAT,0666); // create file to be
locked
if (pid==(pid_t)-1) {
fprintf(stderr, "Error creating /tmp/yyy - %s\n", strerror(errno));
exit(1);
}
lock.l_type = F_WRLCK; // lock /tmp/yyy
lock.l_start = 0;
lock.l_whence = 0;
lock.l_len = 0;
errno = 0;
if (fcntl(pid, F_SETLKW, &lock) < 0) {
fprintf(stderr, "Error locking /tmp/yyy - %s\n", strerror(errno));
exit(1);
}
write_status("/tmp/yyy is locked ... sleeping for 10 seconds\n");
sleep(10);
status = spawnv(_P_NOWAIT, "/bin/sh", argv); // spawn some random program
/* status = posix_spawn(&task_pid, "/bin/sh", NULL, NULL, argv, environ);
*/
if (errno != 0)
fprintf(stderr, "Error starting %s (%s)\n", argv[2], strerror(errno));
else {
write_status("spawnv() succeeded\n");
}
if (access("/tmp/xxx", F_OK)) { // check to make sure our
random program worked
write_status("spawned program did not complete\n");
} else {
write_status("spawned program completed\n");
}
while (1) {
write_status("main program idle\n");
sleep(2);
}
exit(0);
}
write_status(char *message)
{
char ctbuf[90];
time_t t,time(time_t *);
t=time((time_t*)0); /* make a time stamp */
strcpy(ctbuf,(char *)ctime(&t));
if (ctbuf[strlen(ctbuf)-1]=='\n') ctbuf[strlen(ctbuf)-1]=(char)0;
strcat(ctbuf, ": ");
strcat(ctbuf, message);
fprintf(stderr, ctbuf);
}
Steve Bardwell
--
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