Problem with fork inside a thread and execv()

C

CMorgan

Hi everybody,
I am experiencing an annoying problem with fork() and execv().
In my program I need to launch the "pppd" from a thread, so, I create
a new process with fork and then in the child process I launch with
execv the pppd to connect an embedded system to internet.
The problem is that pppd fails.

I have made two test program just to discard bugs (my
applications is really big) and the result is that when
I call execv from a child process created from a thread the pppd
script fails!!!!
On the other hand when I call execv from a process created from a fork
(without threads) the code works!!!
:-o

Here I paste my two test program, the test that fails, the test that
success:

------- TEST PROGRAM THAT FAILS -------
#include <pthread.h>
#include <sys/time.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

static bool ActivarGPRS (void);
static void* macapi_gprs_connect_thread(void *param);

int main(int argc,char** argv)
{
pthread_t thread;

pthread_create(&thread,NULL,&macapi_gprs_connect_thread,NULL);

while(1)
{
sleep(100);
}
return 0;

}

static void* macapi_gprs_connect_thread(void *param)
{
if( true == ActivarGPRS() )
printf("GPRS activado\n");
else
printf("No se puede activar el GPRS\n");

}

static bool ActivarGPRS (void)
{
int pid;
struct timeval T0, T1;
FILE *fp = NULL;

//************ GPRS *************
printf ("ActivarGPRS\n");
if ((pid = fork ()) < 0)
{
printf ("Error fork\n");
return false;
}
// Tiempo de arranque
gettimeofday (&T0, NULL);
if (pid == 0)
{
char* argv[] = {"/usr/sbin/pppd","call","gprs",NULL};
// Proceso hijo
//system ("/usr/sbin/pppd call gprs > /home/sattoll/
StatusGPRS");
execv(argv[0],argv);
printf("execv failure:%s\n",strerror(errno));
system ("rm -f /home/sattoll/StatusGPRS");
exit (0);
}
else
{
// Proceso padre
while ((fp = fopen ("/home/sattoll/GPRSOK", "r")) == NULL)
{
// Si pasa mucho tiempo sin conexion (1 minutos), se
sale y se reintentera mas tarde
gettimeofday (&T1, NULL);
if ((T1.tv_sec - T0.tv_sec) > 40)
{
printf ("Timeout\n");
system ("killall -2 pppd");
// hay que esperar porque si no se ha conectado al
CE
system ("sleep 3");
system ("rm -f /home/sattoll/StatusGPRS");
return false;
}
}
return true;
}
}

------- END OF TEST PROGRAM THAT FAILS -------
------- TEST PROGRAM THAT WORKS -------------
#include <sys/time.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

static bool ActivarGPRS (void);

int main(int argc,char** argv)
{
if( true == ActivarGPRS() )
printf("GPRS activado\n");
else
printf("No se puede activar el GPRS\n");

}

static bool ActivarGPRS (void)
{
int pid;
struct timeval T0, T1;
FILE *fp = NULL;

//************ GPRS *************
printf ("ActivarGPRS\n");
if ((pid = fork ()) < 0)
{
printf ("Error fork\n");
return false;
}
// Tiempo de arranque
gettimeofday (&T0, NULL);
if (pid == 0)
{
char* argv[] = {"/usr/sbin/pppd","call","gprs",NULL};
// Proceso hijo
//system ("/usr/sbin/pppd call gprs > /home/sattoll/
StatusGPRS");
execv(argv[0],argv);
printf("execv failure:%s\n",strerror(errno));
system ("rm -f /home/sattoll/StatusGPRS");
exit (0);
}
else
{
// Proceso padre
while ((fp = fopen ("/home/sattoll/GPRSOK", "r")) == NULL)
{
// Si pasa mucho tiempo sin conexion (1 minutos), se
sale y se reintentera mas tarde
gettimeofday (&T1, NULL);
if ((T1.tv_sec - T0.tv_sec) > 40)
{
printf ("Timeout\n");
system ("killall -2 pppd");
// hay que esperar porque si no se ha conectado al
CE
system ("sleep 3");
system ("rm -f /home/sattoll/StatusGPRS");
return false;
}
}
return true;
}
}

----------- END OF TEST PROGRAM THAT WORKS
 
W

Walter Roberson

CMorgan said:
I am experiencing an annoying problem with fork() and execv().

Neither fork() nor execv() nor threads are part of the C language.
Please consult a newsgroup that deals with whatever extensions
or external library that you are using that is providing fork()
and execv() for you. Possibly comp.unix.programmer or
comp.programming.threads (or group names similar to those.)
 
K

Kenny McCormack

Neither fork() nor execv() nor threads are part of the C language.
Please consult a newsgroup that deals with whatever extensions
or external library that you are using that is providing fork()
and execv() for you. Possibly comp.unix.programmer or
comp.programming.threads (or group names similar to those.)

IOW:

Off topic. Not portable. Cant discuss it here. Blah, blah, blah.

--
Useful clc-related links:

http://en.wikipedia.org/wiki/Aspergers
http://en.wikipedia.org/wiki/Clique
http://en.wikipedia.org/wiki/C_programming_language
 
S

suresh shenoy

Hi everybody,
I am experiencing an annoying problem with fork() and execv().
In my program I need to launch the "pppd" from a thread, so, I create
a new process with fork and then in the child process I launch with
execv the pppd to connect an embedded system to internet.
The problem is that pppd fails.

I have made two test program just to discard bugs (my
applications is really big) and the result is that when
I call execv from a child process created from a thread the pppd
script fails!!!!
On the other hand when I call execv from a process created from a fork
(without threads) the code works!!!
:-o

Here I paste my two test program, the test that fails, the test that
success:

------- TEST PROGRAM THAT FAILS -------
#include <pthread.h>
#include <sys/time.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

static bool ActivarGPRS (void);
static void* macapi_gprs_connect_thread(void *param);

int main(int argc,char** argv)
{
    pthread_t thread;

    pthread_create(&thread,NULL,&macapi_gprs_connect_thread,NULL);

    while(1)
    {
        sleep(100);
    }
    return 0;

}

static void* macapi_gprs_connect_thread(void *param)
{
    if( true == ActivarGPRS() )
        printf("GPRS activado\n");
    else
        printf("No se puede activar el GPRS\n");

}

static bool ActivarGPRS (void)
{
int pid;
struct timeval T0, T1;
FILE *fp = NULL;

        //************ GPRS *************
        printf ("ActivarGPRS\n");
        if ((pid = fork ()) < 0)
        {
            printf ("Error fork\n");
            return false;
        }
        // Tiempo de arranque
        gettimeofday (&T0, NULL);
        if (pid == 0)
        {
            char* argv[] = {"/usr/sbin/pppd","call","gprs",NULL};
            // Proceso hijo
            //system ("/usr/sbin/pppd call gprs > /home/sattoll/
StatusGPRS");
            execv(argv[0],argv);
            printf("execv failure:%s\n",strerror(errno));
            system ("rm -f /home/sattoll/StatusGPRS");
            exit (0);
        }
        else
        {
            // Proceso padre
            while ((fp = fopen ("/home/sattoll/GPRSOK", "r")) == NULL)
            {
                // Si pasa mucho tiempo sin conexion (1 minutos), se
sale y se reintentera mas tarde
                gettimeofday (&T1, NULL);
                if ((T1.tv_sec - T0.tv_sec) > 40)
                    {
                    printf ("Timeout\n");
                    system ("killall -2 pppd");
                    // hay que esperar porque si no se ha conectado al
CE
                    system ("sleep 3");
                    system ("rm -f /home/sattoll/StatusGPRS");
                    return false;
                    }
            }
            return true;
        }

}

------- END OF TEST PROGRAM THAT FAILS -------
------- TEST PROGRAM THAT WORKS -------------
#include <sys/time.h>
#include <stdbool.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>

static bool ActivarGPRS (void);

int main(int argc,char** argv)
{
    if( true == ActivarGPRS() )
        printf("GPRS activado\n");
    else
        printf("No se puede activar el GPRS\n");

}

static bool ActivarGPRS (void)
{
int pid;
struct timeval T0, T1;
FILE *fp = NULL;

        //************ GPRS *************
        printf ("ActivarGPRS\n");
        if ((pid = fork ()) < 0)
        {
            printf ("Error fork\n");
            return false;
        }
        // Tiempo de arranque
        gettimeofday (&T0, NULL);
        if (pid == 0)
        {
            char* argv[] = {"/usr/sbin/pppd","call","gprs",NULL};
            // Proceso hijo
            //system ("/usr/sbin/pppd call gprs > /home/sattoll/
StatusGPRS");
            execv(argv[0],argv);
            printf("execv failure:%s\n",strerror(errno));
            system ("rm -f /home/sattoll/StatusGPRS");
            exit (0);
        }
        else
        {
            // Proceso padre
            while ((fp = fopen ("/home/sattoll/GPRSOK", "r")) == NULL)
            {
                // Si pasa mucho tiempo sin conexion (1 minutos), se
sale y se reintentera mas tarde
                gettimeofday (&T1, NULL);
                if ((T1.tv_sec - T0.tv_sec) > 40)
                    {
                    printf ("Timeout\n");
                    system ("killall -2 pppd");
                    // hay que esperar porque si no se ha conectado al
CE
                    system ("sleep 3");
                    system ("rm -f /home/sattoll/StatusGPRS");
                    return false;
                    }
            }
            return true;
        }

}

----------- END OF TEST PROGRAM THAT WORKS

CMorgan,

Firstly, I would recommend you to perform error checking, this
will help you resolve any sutle issues at the earliest. Also, i think
you should compare the pid of the thread and not fix it to 0 since you
have spawned a thread. You should get that information from the
'thread' instance created in pthread_create(..);

Suresh M. Shenoy
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top