Enlightenment CVS committal Author : onefang Project : e17 Module : libs/ecore
Dir : e17/libs/ecore/src/lib/ecore Modified Files: ecore_exe.c Log Message: Beginnings of fork'n'pipe. Don't use ecore_exe_pipe_run() yet, it is not finished. You can use ecore_exe_pipe_write(), but it will do nothing. I committed this because someone wanted to play with it in it's current state. ecore_exe_pipe_run() will startup your exe, and open the pipes that you request, and everything should get cleaned up when the exe closes. The pipes are in the Ecore_Exe struct, you can use them. The next thing I will add will be proper use of the pipes. =================================================================== RCS file: /cvsroot/enlightenment/e17/libs/ecore/src/lib/ecore/ecore_exe.c,v retrieving revision 1.16 retrieving revision 1.17 diff -u -3 -r1.16 -r1.17 --- ecore_exe.c 25 Oct 2005 07:30:29 -0000 1.16 +++ ecore_exe.c 9 Nov 2005 14:09:28 -0000 1.17 @@ -82,9 +82,8 @@ pid_t pid = 0; int dataPipe[2] = { -1, -1 }; int statusPipe[2] = { -1, -1 }; - int n; + int n = 0; volatile int vfork_exec_errno = 0; - char **args; /* FIXME: * set up fd handler in ecore_exe struct @@ -94,6 +93,8 @@ * connection is closed. once this event has been handled the child * ecore_exe struct is freed automatically and is no longer valid. * + * _ecore_con_svr_cl_handler(void *data, Ecore_Fd_Handler *fd_handler) + * * when fd handlers report data - if line buffering is nto enabled instantly * copy data to a exe data event struct and add the event like ecore_con. if * line buffering is enabled, parse new data block for a \n. if there is @@ -111,129 +112,116 @@ if (shell == 0) { shell = getenv("SHELL"); - if (shell == 0) - shell = "/bin/sh"; + if (shell == 0) + shell = "/bin/sh"; } - args = (char **) calloc(4, sizeof(char *)); - n = 0; - args[n++] = shell; - args[n++] = "-c"; - args[n++] = exe_cmd; - args[n++] = 0; - - if (pipe(dataPipe) < 0 || pipe(statusPipe) < 0) - printf("Failed to create pipe\n"); - /* FIXME: I should check this. */ - signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ + exe = calloc(1, sizeof(Ecore_Exe)); + if (exe == NULL) return NULL; + + exe->args[n++] = shell; + exe->args[n++] = "-c"; + exe->args[n++] = exe_cmd; + exe->args[n++] = NULL; + + if ((pipe(dataPipe) == -1) || pipe(statusPipe) == -1) + printf("Failed to create pipes\n"); + /* FIXME: I should double check this. After a quick look around, this is already done, but via a more modern method. */ + /* signal(SIGPIPE, SIG_IGN); /* we only want EPIPE on errors */ pid = fork(); - if (pid == 0) - { /* child */ - setsid(); + if (pid == -1) + { + printf("Failed to fork process\n"); + pid = 0; + } + else if (pid == 0) /* child */ + { + setsid(); /* FIXME: Check for -1 then errno. */ + close(STDOUT_FILENO); /* FIXME: Check for -1 then errno. */ + close(STDERR_FILENO); /* FIXME: Check for -1 then errno. */ + close(STDIN_FILENO); /* FIXME: Check for -1 then errno. */ if (flags & ECORE_EXE_PIPE_READ) { - dup2(dataPipe[1], STDOUT_FILENO); - dup2(dataPipe[1], STDERR_FILENO); + dup2(dataPipe[1], STDOUT_FILENO); /* FIXME: Check for -1 then errno. */ + dup2(dataPipe[1], STDERR_FILENO); /* FIXME: Check for -1 then errno. */ } else { - close(dataPipe[1]); - close(STDOUT_FILENO); - close(STDERR_FILENO); + close(dataPipe[1]); /* FIXME: Check for -1 then errno. */ } if (flags & ECORE_EXE_PIPE_WRITE) { - dup2(dataPipe[0], STDIN_FILENO); + dup2(dataPipe[0], STDIN_FILENO); /* FIXME: Check for -1 then errno. */ } else { - close(dataPipe[0]); - close(STDIN_FILENO); + close(dataPipe[0]); /* FIXME: Check for -1 then errno. */ } - close(statusPipe[0]); - fcntl(statusPipe[1], F_SETFD, FD_CLOEXEC); /* close on exec shows sucess */ + close(statusPipe[0]); /* FIXME: Check for -1 then errno. */ + fcntl(statusPipe[1], F_SETFD, FD_CLOEXEC); /* close on exec shows sucess */ /* FIXME: Check for -1 then errno. */ errno = 0; - execvp(shell, (char **) args); + execvp(shell, (char **) exe->args); + /* Something went 'orribly wrong. */ vfork_exec_errno = errno; - close(statusPipe[1]); +// if (! (flags & ECORE_EXE_PIPE_READ)) +// close(dataPipe[1]); /* FIXME: Check for -1 then errno. */ +// if (! (flags & ECORE_EXE_PIPE_WRITE)) +// close(dataPipe[0]); /* FIXME: Check for -1 then errno. */ +// close(statusPipe[1]); /* FIXME: Check for -1 then errno. */ _exit(-1); } - else if (pid > 0) - { /* parent */ + else /* parent */ + { if (! (flags & ECORE_EXE_PIPE_READ)) - close(dataPipe[0]); + close(dataPipe[0]); /* FIXME: Check for -1 then errno. */ if (! (flags & ECORE_EXE_PIPE_WRITE)) - close(dataPipe[1]); - close(statusPipe[1]); + close(dataPipe[1]); /* FIXME: Check for -1 then errno. */ + close(statusPipe[1]); /* FIXME: Check for -1 then errno. */ - while (1) + /* FIXME: after having a good look at the current e fd handling, investigate fcntl(dataPipe[x], F_SETSIG, ...) */ + + while (1) /* Wait for it to start executing. */ { char buf; n = read(statusPipe[0], &buf, 1); - if (n == 0 && vfork_exec_errno != 0) + if ((n == -1) && ((errno == EAGAIN) || (errno == EINTR))) + continue; /* try it again */ + if (n == 0) { - errno = vfork_exec_errno; - printf("Could not exec process\n"); - } - break; + if (vfork_exec_errno != 0) + { + n = vfork_exec_errno; + printf("Could not exec process\n"); /* FIXME: maybe set the pid to 0? */ + } + break; + } } close(statusPipe[0]); } - else - { - printf("Failed to fork process\n"); - pid = 0; - } - n = 0; if (pid) { - if (WIFEXITED(n)) - { - if (flags & ECORE_EXE_PIPE_READ) - close(dataPipe[0]); - if (flags & ECORE_EXE_PIPE_WRITE) - close(dataPipe[1]); - - n = WEXITSTATUS(n); - printf("Process %s returned %i\n", exe_cmd, n); - pid = 0; - } - else - { - n = -1; - - exe = calloc(1, sizeof(Ecore_Exe)); - if (!exe) - { - if (flags & ECORE_EXE_PIPE_READ) - close(dataPipe[0]); - if (flags & ECORE_EXE_PIPE_WRITE) - close(dataPipe[1]); - kill(pid, SIGKILL); - printf("No memory for Ecore_Exe %s\n", exe_cmd); - return NULL; - } - ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE); - exe->pid = pid; - exe->flags = flags; - exe->data = (void *)data; - if (flags & ECORE_EXE_PIPE_READ) - exe->child_fd_read = dataPipe[0]; - if (flags & ECORE_EXE_PIPE_WRITE) - exe->child_fd_write = dataPipe[1]; - exes = _ecore_list2_append(exes, exe); - } + ECORE_MAGIC_SET(exe, ECORE_MAGIC_EXE); + exe->pid = pid; + exe->flags = flags; + exe->data = (void *)data; + exe->cmd = exe_cmd; /* FIXME: should calloc and cpy. */ + if (flags & ECORE_EXE_PIPE_READ) + exe->child_fd_read = dataPipe[0]; + if (flags & ECORE_EXE_PIPE_WRITE) + exe->child_fd_write = dataPipe[1]; + exes = _ecore_list2_append(exes, exe); + n = 0; + printf("Ecore_Exe %s success!\n", exe_cmd); } - free(args); errno = n; return exe; @@ -374,6 +362,25 @@ */ /** + * Makes sure the process is dead, one way or another. + * @param exe Process handle to the given process. + * @ingroup Ecore_Exe_Signal_Group + */ +void +ecore_exe_kill_maybe(Ecore_Exe *exe) +{ + if (!ECORE_MAGIC_CHECK(exe, ECORE_MAGIC_EXE)) + { + /* Since Ecore_Exe's can be freed without the users knowledge, we need a way to kill them without bitchin'. */ + /* FIXME: On the other hand, handling the exe exit event may be the way to go. */ + return; + } + kill(exe->pid, SIGTERM); +/* FIXME: should pause for a bit. */ + kill(exe->pid, SIGKILL); +} + +/** * Pauses the given process by sending it a @c SIGSTOP signal. * @param exe Process handle to the given process. * @ingroup Ecore_Exe_Signal_Group @@ -506,8 +513,15 @@ { void *data; - /* FIXME: close fdhanlders and free buffers if they exist */ +printf("FREEING Ecore_Exe %s\n", exe->cmd); data = exe->data; + + /* FIXME: close fdhanlders and free buffers if they exist */ + if (exe->flags & ECORE_EXE_PIPE_READ) + close(exe->child_fd_read); /* FIXME: Check for -1 then errno. */ + if (exe->flags & ECORE_EXE_PIPE_WRITE) + close(exe->child_fd_write); /* FIXME: Check for -1 then errno. */ + exes = _ecore_list2_remove(exes, exe); ECORE_MAGIC_SET(exe, ECORE_MAGIC_NONE); if (exe->tag) free(exe->tag); ------------------------------------------------------- SF.Net email is sponsored by: Tame your development challenges with Apache's Geronimo App Server. Download it for free - -and be entered to win a 42" plasma tv or your very own Sony(tm)PSP. Click here to play: http://sourceforge.net/geronimo.php _______________________________________________ enlightenment-cvs mailing list enlightenment-cvs@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/enlightenment-cvs