From 23cc0aab84ceb531cfc8b3b0f33d251f78758ff9 Mon Sep 17 00:00:00 2001 From: gumartinm Date: Sun, 29 Jan 2012 07:42:50 +0100 Subject: [PATCH] Removing tabs, I know this should have been done before but I have just found out that must be done always. --- JavaFork/Daemon/javafork.c | 423 ++++++++++++++++++++++----------------------- JavaFork/Daemon/javafork.h | 2 +- 2 files changed, 210 insertions(+), 215 deletions(-) diff --git a/JavaFork/Daemon/javafork.c b/JavaFork/Daemon/javafork.c index af03de3..b164b6f 100644 --- a/JavaFork/Daemon/javafork.c +++ b/JavaFork/Daemon/javafork.c @@ -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,""); - send(socket,string,strlen(string),0); - sprintf(string,""); - 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,""); - send(socket,string,strlen(string),0); - } - if(polls[1].revents&&POLLIN) { - bzero(buf,2000); - n=read(err[0],buf,1990); - sprintf(string,""); - 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,""); + send(socket,string,strlen(string),0); + sprintf(string,""); + 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,"", (*returnstatus)); - send(socket,string,strlen(string),0); - sprintf(string,""); - 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,""); + send(socket,string,strlen(string),0); + } + + if(polls[1].revents&&POLLIN) { + bzero(buf,2000); + n=read(err[0],buf,1990); + sprintf(string,""); + 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,"", (*returnstatus)); + send(socket,string,strlen(string),0); + sprintf(string,""); + 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; diff --git a/JavaFork/Daemon/javafork.h b/JavaFork/Daemon/javafork.h index 3264e51..8abacc1 100644 --- a/JavaFork/Daemon/javafork.h +++ b/JavaFork/Daemon/javafork.h @@ -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); -- 2.1.4