Sto lavorando a un'applicazione che contiene diversi socket server che vengono eseguiti in un thread univoco.
Un'utilità esterna (script) viene chiamata da uno dei thread. Questo script chiama un'utilità (client) che invia un messaggio a uno dei socket del server.socket() restituisce 0 nell'applicazione client C client
Inizialmente, stavo usando system()
per eseguire questo script esterno, ma non potevamo usarlo perché dovevamo assicurarci che i socket del server fossero chiusi nel child che era stato biforcato per eseguire lo script esterno.
Io chiamo ora fork()
e execvp()
me stesso. I fork()
e poi nel bambino chiudo tutti i socket del server e quindi chiamo execvp()
per eseguire lo script.
Ora, tutto funziona bene. Il problema è che a volte lo script segnala errori all'app del server. Lo script invia questi errori chiamando un'altra applicazione (client) che apre un socket TCP e invia i dati appropriati. Il mio problema è che l'app client ottiene un valore di 0
restituito dalla chiamata di sistema socket()
.
NOTA: questo si verifica SOLO quando l'app script/client viene chiamata utilizzando la funzione forkExec(). Se l'app script/client viene chiamata manualmente, la chiamata socket()
viene eseguita correttamente e le cose funzionano correttamente.
Sulla base di tali informazioni, sospetto che sia qualcosa nel mio codice execvp() di fork() sotto ... Qualche idea?
void forkExec()
{
int stat;
stat = fork();
if (stat < 0)
{
printf("Error forking child: %s", strerror(errno));
}
else if (stat == 0)
{
char *progArgs[3];
/*
* First, close the file descriptors that the child
* shouldn't keep open
*/
close(ServerFd);
close(XMLSocket);
close(ClientFd);
close(EventSocket);
close(monitorSocket);
/* build the arguments for script */
progArgs[0] = calloc(1, strlen("/path_to_script")+1);
strcpy(progArgs[0], "/path_to_script");
progArgs[1] = calloc(1, strlen(arg)+1);
strcpy(progArgs[1], arg);
progArgs[2] = NULL; /* Array of args must be NULL terminated for execvp() */
/* launch the script */
stat = execvp(progArgs[0], progArgs);
if (stat != 0)
{
printf("Error executing script: '%s' '%s' : %s", progArgs[0], progArgs[1], strerror(errno));
}
free(progArgs[0]);
free(progArgs[1]);
exit(0);
}
return;
}
client codice app:
static int connectToServer(void)
{
int socketFD = 0;
int status;
struct sockaddr_in address;
struct hostent* hostAddr = gethostbyname("localhost");
socketFD = socket(PF_INET, SOCK_STREAM, 0);
La chiamata restituisce sopra 0.
if (socketFD < 0)
{
fprintf(stderr, "%s-%d: Failed to create socket: %s",
__func__, __LINE__, strerror(errno));
return (-1);
}
memset(&address, 0, sizeof(struct sockaddr));
address.sin_family = AF_INET;
memcpy(&(address.sin_addr.s_addr), hostAddr->h_addr, hostAddr->h_length);
address.sin_port = htons(POLLING_SERVER_PORT);
status = connect(socketFD, (struct sockaddr *)&address, sizeof(address));
if (status < 0)
{
if (errno != ECONNREFUSED)
{
fprintf(stderr, "%s-%d: Failed to connect to server socket: %s",
__func__, __LINE__, strerror(errno));
}
else
{
fprintf(stderr, "%s-%d: Server not yet available...%s",
__func__, __LINE__, strerror(errno));
close(socketFD);
socketFD = 0;
}
}
return socketFD;
}
FYI
OS: Linux
Arco: ARM32
del kernel: 2.6.26
Potresti pubblicare il codice che chiama socket() per favore? – abc
Non ho idea di cosa sta succedendo al tuo socket. Forse è di aiuto se ti faccio notare che puoi dichiarare i tuoi argomenti molto più semplici: const char * progArgs [] = {"/ path_to_script", arg, NULL}; - Nessuna necessità di allocare e copiare, tutto ciò che serve è un array con i puntatori giusti al momento in cui si chiama execvp. – VoidPointer