I am working on an application containing several server sockets, each of which runs in a unique thread.
One of the threads is called by an external utility (script). This script calls a utility (client) that sends a message to one of the server sockets.
Initially, I used system() to execute this external script, but we could not use it because we needed to make sure that the server sockets were closed in a child element that was forked to execute the external script.
Now I call fork() and execvp() . I fork() and then in the child I close all server sockets and then call execvp() to execute the script.
Now it all works great. The problem is that at times the script reports errors to the server application. The script sends these errors, invoking another application (client) that opens the TCP socket and sends the corresponding data. My problem is that the client application gets the value 0 returned by the socket() system call.
NOTE. This ONLY happens when the script / client application is called using my forkExec () function. If the script / client application is called manually, the socket() call is executed appropriately and everything works fine.
Based on this information, I suspect it is something in the fork () execvp () code below ... Any ideas?
void forkExec() { int stat; stat = fork(); if (stat < 0) { printf("Error forking child: %s", strerror(errno)); } else if (stat == 0) { char *progArgs[3]; close(ServerFd); close(XMLSocket); close(ClientFd); close(EventSocket); close(monitorSocket); 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; 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 Application Code:
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);
The above call returns 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
Arch: ARM32
Kernel: 2.6.26