Removing tabs, I know this should have been done before but
authorgumartinm <gu.martinm@gmail.com>
Sun, 29 Jan 2012 06:42:50 +0000 (07:42 +0100)
committergumartinm <gu.martinm@gmail.com>
Sun, 29 Jan 2012 06:42:50 +0000 (07:42 +0100)
I have just found out that must be done always.

JavaFork/Daemon/javafork.c
JavaFork/Daemon/javafork.h

index af03de3..b164b6f 100644 (file)
@@ -47,11 +47,11 @@ static int closeSafely(int fd)
 
 int main (int argc, char *argv[]) 
 {
-       int c;                                          /*Getopt parameter*/
+       int c;                      /*Getopt parameter*/
        /*Default values*/
-       char *avalue = IPADDRESS;       /*Address: numeric value or hostname*/
-       int pvalue = PORT;              /*TCP port*/
-       int qvalue = QUEUE;                 /*TCP listen queue*/
+       char *avalue = IPADDRESS;   /*Address: numeric value or hostname*/
+       int pvalue = PORT;          /*TCP port*/
+       int qvalue = QUEUE;         /*TCP listen queue*/
        
        
        /*This process is intended to be used as a daemon, it sould be launched by the INIT process, because of that*/
@@ -109,7 +109,7 @@ int main (int argc, char *argv[])
                return 1;
        }
        
-       if (main_child(avalue, pvalue, qvalue) < 0)
+       if (main_daemon (avalue, pvalue, qvalue) < 0)
                return 1;
        
        return 0;
@@ -117,16 +117,16 @@ int main (int argc, char *argv[])
 
 
 
-int main_child (char *address, int port, int queue)
+int main_daemon (char *address, int port, int queue)
 {
-       struct protoent *protocol;                      /*Network protocol*/
+       struct protoent *protocol;          /*Network protocol*/
        struct sockaddr_in addr_server;     /*struct with the server socket address*/
        struct sockaddr_in  addr_client;    /*struct with the client socket address*/
-       int sockclient = -1;                            /*File descriptor for the accepted socket*/
-       pthread_t idThread;                                     /*Thread identifier number*/
+       int sockclient = -1;                /*File descriptor for the accepted socket*/
+       pthread_t idThread;                 /*Thread identifier number*/
        socklen_t clilen;
        int optval;
-       int returnValue = 0;                            /*The return value from this function, OK by default*/
+       int returnValue = 0;                /*The return value from this function, OK by default*/
        
        
        /*Retrieve protocol number from /etc/protocols file */
@@ -196,9 +196,9 @@ int daemonize(const char *pname, int facility, int option)
        int fd = -1;    /*Temporaly store for the /dev/tty and /dev/null file descriptors*/
        
        if ((fd = TEMP_FAILURE_RETRY(open( "/dev/tty", O_RDWR, 0))) == -1) {
-               /*We already have no tty control*/
-               closeSafely(fd);
-               return 0;
+/*We already have no tty control*/
+closeSafely(fd);
+return 0;
        }
        
        /*Sending messages to log*/
@@ -238,9 +238,9 @@ void *serverThread (void * arg)
 {
        int socket = -1;                    /*Open socket by the Java client*/
        long timeout, utimeout;             /*Timeout for reading data from client: secs and usecs respectively*/
-       int len;                                            /*Control parameter used while receiving data from the client*/
-       char buffer[1025];                          /*This buffer is intended to store the data received from the client*/
-       char *command = NULL;                   /*The command sent by the client, to be executed by this process*/      
+       int len;                            /*Control parameter used while receiving data from the client*/
+       char buffer[1025];                  /*This buffer is intended to store the data received from the client*/
+       char *command = NULL;               /*The command sent by the client, to be executed by this process*/  
        uint32_t *commandLength = NULL;     /*Store the command length*/
        
        socket = (int) arg;
@@ -252,75 +252,69 @@ void *serverThread (void * arg)
         goto err;
        
        
-       /************************************************************************************************************/
-       /*                                      Just over 1 TCP connection                                                                                                                      */
-       /*                                      COMMAND_LENGTH: Java integer 4 bytes, BIG-ENDIAN (the same as network order)            */
-       /*                                      COMMAND: locale character set encoding                                                                                  */
-       /*                                      RESULTS: locale character set encoding                                                                                  */
-       /*                                                                                                                                                                                                              */
-       /*                                                      JAVA CLIENT: ------------ COMMAND_LENGTH -------> :SERVER                                       */
-       /*                                                      JAVA CLIENT: -------------- COMMAND ------------> :SERVER                                       */
-       /*                                                      JAVA CLIENT: <-------------- RESULTS ------------ :SERVER                                       */
-       /*                                                      JAVA CLIENT: <---------- CLOSE CONNECTION ------- :SERVER                                       */
-       /*                                                                                                                                                                                                              */
-       /************************************************************************************************************/
+            /****************************************************************************************/
+            /*   Just over 1 TCP connection                                                         */
+            /*   COMMAND_LENGTH: Java integer 4 bytes, BIG-ENDIAN (the same as network order)       */
+            /*   COMMAND: locale character set encoding                                             */
+            /*   RESULTS: locale character set encoding                                             */
+            /*                                                                                      */                                                                                         
+            /*   JAVA CLIENT: ------------ COMMAND_LENGTH -------> :SERVER                          */
+            /*   JAVA CLIENT: -------------- COMMAND ------------> :SERVER                          */
+            /*   JAVA CLIENT: <-------------- RESULTS ------------ :SERVER                          */
+            /*   JAVA CLIENT: <---------- CLOSE CONNECTION ------- :SERVER                          */
+            /*                                                                                      */
+            /****************************************************************************************/
 
     /*Wait max 2 seconds for data coming from client, otherwise exits with error.*/
     timeout = 2;
     utimeout = 0;
 
 
+    /*1. COMMAND LENGTH*/
+    /*First of all we receive the command size as a Java integer (4 bytes primitive type)*/    
+    if ((commandLength = (uint32_t *) malloc(sizeof(uint32_t))) == NULL) {
+        syslog (LOG_ERR, "commandLength malloc failed: %m");
+        goto err;
+    }
 
-       /*1. COMMAND LENGTH*/
-       /*First of all we receive the command size as a Java integer (4 bytes primitive type)*/ 
-       if ((commandLength = (uint32_t *) malloc(sizeof(uint32_t))) == NULL) {
-               syslog (LOG_ERR, "commandLength malloc failed: %m");
-               goto err;
-       }
-
-       bzero(buffer, sizeof(buffer));
-       len = sizeof(uint32_t);
+    bzero(buffer, sizeof(buffer));
+    len = sizeof(uint32_t);
 
     if (receive_from_socket (socket, buffer, len, timeout, utimeout) < 0)
         goto err;
 
-       /*Retrieve integer (4 bytes) from buffer*/
-       memcpy (commandLength, buffer, sizeof(uint32_t));
-       /*Java sends the primitive integer using big-endian order (it is the same as network order)*/
-       *commandLength = be32toh (*commandLength);
-
+    /*Retrieve integer (4 bytes) from buffer*/
+    memcpy (commandLength, buffer, sizeof(uint32_t));
+    /*Java sends the primitive integer using big-endian order (it is the same as network order)*/
+    *commandLength = be32toh (*commandLength);
 
 
-               
-       /*2. COMMAND*/
-       /*Reserving commandLength + 1 because of the string end character*/
-       if ((command = (char *) malloc(*commandLength + 1)) == NULL) {
-               syslog (LOG_ERR, "command malloc failed: %m");
-               goto err;
-       } 
+    /*2. COMMAND*/
+    /*Reserving commandLength + 1 because of the string end character*/
+    if ((command = (char *) malloc(*commandLength + 1)) == NULL) {
+        syslog (LOG_ERR, "command malloc failed: %m");
+        goto err;
+    }
 
-       bzero(command, ((*commandLength) + 1));
+    bzero(command, ((*commandLength) + 1));
     len = *commandLength;
-       /*Wait max 2 seconds for data coming from client, otherwise exits with error.*/
-       if (receive_from_socket (socket, command, len, timeout, utimeout) < 0)
+    /*Wait max 2 seconds for data coming from client, otherwise exits with error.*/
+    if (receive_from_socket (socket, command, len, timeout, utimeout) < 0)
         goto err;
 
 
-
-       /*3. RESULTS*/  
-       pre_fork_system(socket, command);       
-
+    /*3. RESULTS*/     
+    pre_fork_system(socket, command);
 
 
-
-       /*4. CLOSE CONNECTION AND FINISH*/
+    /*4. CLOSE CONNECTION AND FINISH*/
 
 err:
-       free(command);
+    free(command);
     closeSafely(socket);
-       free(commandLength);
+    free(commandLength);
 
-       pthread_exit(0);
+    pthread_exit(0);
 }
 
 
@@ -384,10 +378,10 @@ int readable_timeout (int fd, long timeout, long utimeout)
 int receive_from_socket (int socket, char *data, int len, long timeout, long utimeout)
 {
     int nData, iPos;   /*Control variables.*/
-       int ret;                        /*Store return value from select.*/
+    int ret;            /*Store return value from select.*/
 
-       nData = iPos = 0;
-       do {
+    nData = iPos = 0;
+    do {
         ret = readable_timeout(socket, timeout, utimeout);
 
         if (ret == 0) {
@@ -415,8 +409,8 @@ int receive_from_socket (int socket, char *data, int len, long timeout, long uti
             return -1;
         }
 
-               len -= nData;
-               iPos += nData;
+        len -= nData;
+        iPos += nData;
     } while (len > 0);
 
     return 0;
@@ -425,25 +419,25 @@ int receive_from_socket (int socket, char *data, int len, long timeout, long uti
 
 int pre_fork_system(int socket, char *command)
 {
-       /*Required variables in order to share memory between processes*/
-       key_t keyvalue;
-       int idreturnstatus = -1;
-       /*Store the return status from the process launched using system or execve*/
-       /*Using shared memory between the child and parent process*/
-       int *returnstatus = NULL;
-       
-       /*Required variables in order to share the semaphore between processes*/
-       key_t keysemaphore;
-       int idsemaphore = -1;
-       sem_t *semaphore = NULL;        /*Used as a barrier: the child process just can start after sending the XML init code*/
-
-       int returnValue = -1;       /*Return value from this function can be caught by upper layers, NOK by default*/
+    /*Required variables in order to share memory between processes*/
+    key_t keyvalue;
+    int idreturnstatus = -1;
+    /*Store the return status from the process launched using system or execve*/
+    /*Using shared memory between the child and parent process*/
+    int *returnstatus = NULL;
+       
+    /*Required variables in order to share the semaphore between processes*/
+    key_t keysemaphore;
+    int idsemaphore = -1;
+    sem_t *semaphore = NULL;    /*Used as a barrier: the child process just can start after sending the XML init code*/
+
+    int returnValue = -1;       /*Return value from this function can be caught by upper layers, NOK by default*/
                
        
        
-       /*Allocate shared memory because we can not use named semaphores*/
-       /*We are using this semaphore as a barrier, because we just want to start the child process when the parent process has sent*/
-       /*the XML header (see: for_system function)*/
+    /*Allocate shared memory because we can not use named semaphores*/
+    /*We are using this semaphore as a barrier, because we just want to start the child process when the parent process has sent*/
+    /*the XML header (see: for_system function)*/
        
     keysemaphore=ftok("/bin/ls", SHAREMEMSEM);  /*the /bin/ls must exist otherwise this does not work... */
     if (keysemaphore == -1) {
@@ -473,12 +467,12 @@ int pre_fork_system(int socket, char *command)
        
        
        
-       /*Allocate shared memory for the return status code from the process which is going to be launched by the system function.*/
-       /*We want to share the returnstatus variable between this process and the child that is going to be created in the fork_system method.*/
-       /*The goal is to store in this variable the return status code received from the process launched with the system method by the child process,*/
-       /*then the parent process can retrieve that return status code and send it by TCP to the Java client.*/
-       /*There are not concurrency issues because the parent process will just try to read this variable when the child process is dead, taking*/
-       /*in that moment its last value and sending it to the Java client.*/
+    /*Allocate shared memory for the return status code from the process which is going to be launched by the system function.*/
+    /*We want to share the returnstatus variable between this process and the child that is going to be created in the fork_system method.*/
+    /*The goal is to store in this variable the return status code received from the process launched with the system method by the child process,*/
+    /*then the parent process can retrieve that return status code and send it by TCP to the Java client.*/
+    /*There are not concurrency issues because the parent process will just try to read this variable when the child process is dead, taking*/
+    /*in that moment its last value and sending it to the Java client.*/
 
 
     keyvalue=ftok("/bin/ls", SHAREMEMKEY);  /*the /bin/ls must exist otherwise this does not work... */
@@ -499,10 +493,9 @@ int pre_fork_system(int socket, char *command)
         goto end_release_mem;
     } 
 
+    /*After allocating and attaching shared memory we reach this code if everything went OK.*/
 
-       /*After allocating and attaching shared memory we reach this code if everything went OK.*/      
-       
-       returnValue = fork_system(socket, command, semaphore, returnstatus);
+    returnValue = fork_system(socket, command, semaphore, returnstatus);
 
 
 end_release_mem:
@@ -535,146 +528,148 @@ end:
 
 
 
-int fork_system(int socket, char *command, sem_t *semaphore, int *returnstatus) {
-       int pid;
-       int out[2], err[2];         /*Store pipes file descriptors. Write ends attached to the stdout and stderr streams.*/
-       char buf[2000];                 /*Read data buffer.*/
-       char string[100];
-       /*We are going to use a poll in order to find out if there are data coming from the*/
-       /*pipes attached to the stdout and stderr streams.*/
-       struct pollfd polls[2];
-       int n;
-       int childreturnstatus;
-       int returnValue = 0;   /*eturn value from this function can be caught by upper layers, OK by default*/
-
-
-       /*Value by default*/
+int fork_system(int socket, char *command, sem_t *semaphore, int *returnstatus) 
+{
+    int pid;
+    int out[2], err[2];     /*Store pipes file descriptors. Write ends attached to the stdout and stderr streams.*/
+    char buf[2000];         /*Read data buffer.*/
+    char string[100];
+    /*We are going to use a poll in order to find out if there are data coming from the*/
+    /*pipes attached to the stdout and stderr streams.*/
+    struct pollfd polls[2];
+    int n;
+    int childreturnstatus;
+    int returnValue = 0;    /*return value from this function can be caught by upper layers, OK by default*/
+
+
+    /*Value by default*/
     (*returnstatus) = 0;
 
        
-       out[0] = out[1] = err[0] = err[1]  = -1;
+    out[0] = out[1] = err[0] = err[1]  = -1;
 
 
-       /*Creating the pipes, they will be attached to the stderr and stdout streams*/  
-       if (pipe(out) < 0 || pipe(err) < 0) {
-           syslog (LOG_ERR, "pipe failed: %m");
-               goto err;
+    /*Creating the pipes, they will be attached to the stderr and stdout streams*/     
+    if (pipe(out) < 0 || pipe(err) < 0) {
+        syslog (LOG_ERR, "pipe failed: %m");
+        goto err;
     }
-       
-       
-       if ((pid=fork()) == -1) {
-               syslog (LOG_ERR, "fork failed: %m");
-               goto err;
-       }
-       
-       if (pid == 0) {
-               /*Child process*/
-               /*It has to launch another one using system or execve*/
-               if ((TEMP_FAILURE_RETRY(dup2(out[1],1)) < 0) || (TEMP_FAILURE_RETRY(dup2(err[1],2)) < 0)) {     
-                       syslog (LOG_ERR, "child dup2 failed: %m");
+
+    if ((pid=fork()) == -1) {
+        syslog (LOG_ERR, "fork failed: %m");
+        goto err;
+    }
+
+    if (pid == 0) {
+        /*Child process*/
+        /*It has to launch another one using system or execve*/
+        if ((TEMP_FAILURE_RETRY(dup2(out[1],1)) < 0) || (TEMP_FAILURE_RETRY(dup2(err[1],2)) < 0)) {    
+            syslog (LOG_ERR, "child dup2 failed: %m");
             /*Going to zombie state, hopefully waitpid will catch it*/ 
-                       exit(-1);
-               }
-               if (TEMP_FAILURE_RETRY(sem_wait(semaphore)) < 0) {
-                       syslog (LOG_ERR, "child semaphore wait failed: %m");
+            exit(-1);
+        }
+
+        if (TEMP_FAILURE_RETRY(sem_wait(semaphore)) < 0) {
+            syslog (LOG_ERR, "child semaphore wait failed: %m");
             /*Going to zombie state, hopefully waitpid will catch it*/
-                       exit(-1);
-               }
-               
-               *returnstatus=system(command);
-               
-               if (WIFEXITED(returnstatus) == 1)
-                       (*returnstatus) = WEXITSTATUS(*returnstatus);
-               else
-                       (*returnstatus) = -1;
-               exit(0);
-       }
-       else {
-               /*Parent process*/
-               /*It sends data to the Java client using a TCP connection.*/
-               polls[0].fd=out[0];
-               polls[1].fd=err[0];
-               polls[0].events=POLLIN;
-               polls[1].events=POLLIN;
-               sprintf(string,"<?xml version=\"1.0\"?>");
-               send(socket,string,strlen(string),0);
-               sprintf(string,"<streams>");
-               send(socket,string,strlen(string),0);
-               
-               /*Releasing barrier, the child process can keep running*/
-               if (sem_post(semaphore) < 0 ) {
-                       syslog (LOG_ERR, "parent error releasing barrier: %m");
-            /*TODO: May I kill a child process if it is already dead? I mean,*/
-            /*      what could happen if the child process is dead?*/
-            /*      Should I implement a SIGCHILD handler?*/
-            /*TODO: Should I have a SIGTERM handler in the child process?*/
-                       kill(pid, SIGTERM);
-                       goto err;
-               }
+            exit(-1);
+        }
 
-               while(1) {
-                       if(poll(polls,2,100)) {
-                               if(polls[0].revents&&POLLIN) {
-                                       bzero(buf,2000);
-                                       n=read(out[0],buf,1990);
-                                       sprintf(string,"<out><![CDATA[");
-                                       send(socket,string,strlen(string),0);
-                                       send(socket,buf,n,0);
-                                       sprintf(string,"]]></out>");
-                                       send(socket,string,strlen(string),0);
-                               } 
-                               if(polls[1].revents&&POLLIN) {
-                                       bzero(buf,2000);
-                                       n=read(err[0],buf,1990);
-                                       sprintf(string,"<error><![CDATA[");
-                                       send(socket,string,strlen(string),0);
-                                       send(socket,buf,n,0);
-                                       sprintf(string,"]]></error>");
-                                       send(socket,string,strlen(string),0);
-                               }
-                               if(!polls[0].revents&&POLLIN && !polls[1].revents&&POLLIN) {
-                                       syslog (LOG_ERR, "parent error polling pipes: %m");
-                                       /*TODO: May I kill a child process if it is already dead? I mean,*/
-                    /*      what could happen if the child process is dead?*/
-                    /*      Should I implement a SIGCHILD handler?*/
-                    /*TODO: Should I have a SIGTERM handler in the child process?*/
-                                       kill(pid, SIGTERM);
-                                       /*I want to send an error status to the remote calling process*/
-                    /*TODO: Before giving this value I should make sure the child process is dead*/
-                    /*      otherwise I could finish having in *returnstatus the value from the child process*/
-                                       (*returnstatus) = -1;
-                                       break;
-                               }
-                       }
-                       else {
-                               /*When timeout*/
-                               if(waitpid(pid, &childreturnstatus, WNOHANG)) {
-                                       /*Child is dead, we can finish the connection*/
-                                       /*First of all, we check the exit status of our child process*/
-                                       /*In case of error send an error status to the remote calling process*/
-                                       if (WIFEXITED(childreturnstatus) != 1)
-                                               (*returnstatus) = -1;
-                                       break;
-                               }
-                               /*The child process is not dead, keep polling more data from stdout or stderr streams*/
-                       }
-               }
+        *returnstatus=system(command);
+        if (WIFEXITED(returnstatus) == 1)
+            (*returnstatus) = WEXITSTATUS(*returnstatus);
+        else
+            (*returnstatus) = -1;
+        /*Going to zombie state, hopefully waitpid will catch it*/
+        exit(0);
+    }
+    else {
+        /*Parent process*/
+        /*It sends data to the Java client using a TCP connection.*/
+        polls[0].fd=out[0];
+        polls[1].fd=err[0];
+        polls[0].events=POLLIN;
+        polls[1].events=POLLIN;
+        sprintf(string,"<?xml version=\"1.0\"?>");
+        send(socket,string,strlen(string),0);
+        sprintf(string,"<streams>");
+        send(socket,string,strlen(string),0);
+
+        /*Releasing barrier, the child process can keep running*/
+        if (sem_post(semaphore) < 0 ) {
+            syslog (LOG_ERR, "parent error releasing barrier: %m");
+            /*TODO: May I kill a child process if it is already dead? I mean,   */
+            /*      what could happen if the child process is dead?             */
+            /*      Should I implement a SIGCHILD handler?                      */
+            /*TODO: Should I have a SIGTERM handler in the child process?       */
+            kill(pid, SIGTERM);
+            goto err;
+        }
 
-       }
-       /*Reaching this code when child finished or if error while polling pipes*/
-       sprintf(string,"<ret><![CDATA[%d]]></ret>", (*returnstatus));
-       send(socket,string,strlen(string),0);
-       sprintf(string,"</streams>");
-       send(socket,string,strlen(string),0);
+        while(1) {
+            if(poll(polls,2,100)) {
+                if(polls[0].revents&&POLLIN) {
+                    bzero(buf,2000);
+                    n=read(out[0],buf,1990);
+                    sprintf(string,"<out><![CDATA[");
+                    send(socket,string,strlen(string),0);
+                    send(socket,buf,n,0);
+                    sprintf(string,"]]></out>");
+                    send(socket,string,strlen(string),0);
+                }
+                if(polls[1].revents&&POLLIN) {
+                    bzero(buf,2000);
+                    n=read(err[0],buf,1990);
+                    sprintf(string,"<error><![CDATA[");
+                    send(socket,string,strlen(string),0);
+                    send(socket,buf,n,0);
+                    sprintf(string,"]]></error>");
+                    send(socket,string,strlen(string),0);
+                }
+
+                if(!polls[0].revents&&POLLIN && !polls[1].revents&&POLLIN) {
+                    syslog (LOG_ERR, "parent error polling pipes: %m");
+                    /*TODO: May I kill a child process if it is already dead? I mean,   */
+                    /*      what could happen if the child process is dead?             */
+                    /*      Should I implement a SIGCHILD handler?                      */
+                    /*TODO: Should I have a SIGTERM handler in the child process?       */
+                    kill(pid, SIGTERM);
+                    /*I want to send an error status to the remote calling process                              */
+                    /*TODO: Before giving this value I should make sure the child process is dead               */
+                    /*      otherwise I could finish having in *returnstatus the value from the child process   */
+                    (*returnstatus) = -1;
+                    break;
+                }
+            }   
+            else {
+                /*When timeout*/
+                if(waitpid(pid, &childreturnstatus, WNOHANG)) {
+                    /*Child is dead, we can finish the connection*/
+                    /*First of all, we check the exit status of our child process*/
+                    /*In case of error send an error status to the remote calling process*/
+                    if (WIFEXITED(childreturnstatus) != 1)
+                        (*returnstatus) = -1;
+                    break;
+                }
+                /*The child process is not dead, keep polling more data from stdout or stderr streams*/
+            }
+        }
+    }
+    /*Reaching this code when child finished or if error while polling pipes*/
+    sprintf(string,"<ret><![CDATA[%d]]></ret>", (*returnstatus));
+    send(socket,string,strlen(string),0);
+    sprintf(string,"</streams>");
+    send(socket,string,strlen(string),0);
 
-       /*Stuff just done by the Parent process. The child process ends with exit*/
-       
+    /*Stuff just done by the Parent process. The child process ends with exit*/
 
 end:
     closeSafely (out[0]);
     closeSafely (out[1]);
     closeSafely (err[0]);
     closeSafely (err[1]);
+    return returnValue;
 err:
     returnValue = -1;
        goto end;
index 3264e51..8abacc1 100644 (file)
@@ -37,7 +37,7 @@ int daemonize(const char *pname, int facility, int option);
 * INPUT PARAMETER: socket file descriptor                                               *
 * RETURNS: int                                                                         *
 ****************************************************************************************/
-int main_child (char *address, int port, int queue);
+int main_daemon (char *address, int port, int queue);