Mail Archives: cygwin/2012/03/08/20:14:29
--mYCpIKhGyMATD0i+
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
I would like to point out a regression, seemingly introduced in 1.7.10.
If a program is exec'ed after forking in a thread and the program is
a native Windows program, it (seemingly) fails to start.
Please, find attached a test case. You can try it with gvim, for example.
There's no problem with the cygwin version of gvim:
$ ./fork_in_thread /usr/bin/gvim
but trying to start the native windows version:
$ ./fork_in_thread "/cygdrive/c/Program Files/Vim/vim73/gvim"
fails, in the sense that nothing happens and no error is reported.
A workaround here is using env. Indeed, the following works:
$ ./fork_in_thread env "/cygdrive/c/Program Files/Vim/vim73/gvim"
However, what puzzles me is the fact that a wrapper (like the one below)
starting gvim by using system() and compiled with i686-pc-mingw32-gcc
works, too!
All the previous examples were working in 1.7.9.
----- wrapper.c -----
#include <stdio.h>
int main(void)
{
system("\"C:/Program Files/Vim/vim73/gvim\"");
return 0;
}
---------------------
--
Enrico
--mYCpIKhGyMATD0i+
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="fork_in_thread.c"
/*
* Forks a program in a thread.
*/
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/wait.h>
void *start(void *arg)
{
int pid, status;
char **av = (char **)arg;
printf("Forking in a thread to start %s\n", av[0]);
pid = fork();
if (pid == -1) {
perror("fork");
exit(1);
}
if (pid == 0) {
execvp(av[0], av);
perror("execvp");
exit(1);
}
printf("Waiting in thread for %s to finish\n", av[0]);
if (wait(&status) == -1) {
perror("wait");
exit(1);
}
if (WIFEXITED(status) && WEXITSTATUS(status))
fprintf(stderr, "%s returned nonzero status %d", av[0], WEXITSTATUS(status));
pthread_exit(NULL);
}
int main (int argc, char *argv[])
{
pthread_t thread;
int i, rc;
char **av;
if (argc < 2) {
printf("Usage: %s <prog> [<arg> ...]\n", argv[0]);
exit(0);
}
/* Build the argument vector for the child */
av = malloc(argc * sizeof(char *));
if (!av) {
fprintf(stderr, "%s: no memory\n", argv[0]);
exit(1);
}
for (i = 0; i < argc - 1; ++i) {
av[i] = strdup(argv[i + 1]);
if (!av[i]) {
fprintf(stderr, "%s: no memory\n", argv[0]);
exit(1);
}
}
av[argc - 1] = NULL;
printf("Main: creating thread for starting %s\n", argv[1]);
rc = pthread_create(&thread, NULL, start, (void *)av);
if (rc) {
fprintf(stderr, "Error: return code from pthread_create() is %d\n", rc);
exit(1);
}
return 0;
}
--mYCpIKhGyMATD0i+
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
--mYCpIKhGyMATD0i+--
- Raw text -