Je travaille sur une application qui contient plusieurs sockets serveur exécutés chacun dans un thread unique.
Un utilitaire externe (script) est appelé par l'un des threads. Ce script appelle un utilitaire (client) qui envoie un message à l'une des sockets du serveur. Initialement, j'utilisais system()
pour exécuter ce script externe, mais nous ne pouvions pas l'utiliser car nous devions nous assurer que les sockets du serveur étaient fermés dans l'enfant qui était forké pour exécuter le script externe.
Je m'appelle maintenant fork()
et execvp()
moi-même. Je fork()
puis dans l'enfant, je ferme toutes les sockets du serveur, puis appelez execvp()
pour exécuter le script.) renvoie 0 dans l'application du serveur client C
Maintenant, tout cela fonctionne très bien. Le problème est que parfois le script signale des erreurs à l'application du serveur. Le script envoie ces erreurs en appelant une autre application (client) qui ouvre un socket TCP et envoie les données appropriées. Mon problème est que l'application cliente obtient une valeur de 0
renvoyée par l'appel système socket()
.
REMARQUE: cela se produit UNIQUEMENT lorsque l'application script/client est appelée à l'aide de ma fonction forkExec(). Si l'application script/client est appelée manuellement, l'appel socket()
s'exécute de manière appropriée et tout fonctionne correctement. Sur la base de ces informations, je suppose que c'est quelque chose dans mon code fork() execvp() ci-dessous ... Des idées?
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;
}
code de l'application client:
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);
Les retours d'appel ci-dessus 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;
}
Pour votre information
OS: Linux
Arch: ARM32
Noyau: 2.6.26
Pourriez-vous poster le code qui appelle socket() s'il vous plaît? – abc
Aucune idée encore ce qui se passe à votre socket. Peut-être que c'est utile si je souligne que vous pouvez déclarer vos arguments beaucoup plus simple: const char * progArgs [] = {"/ path_to_script", arg, NULL}; - Pas besoin d'allouer et de copier, tout ce dont vous avez besoin est un tableau avec les bons pointeurs au moment où vous appelez execvp. – VoidPointer