Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <string.h>
- #include <unistd.h>
- #include <sys/time.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <sys/stat.h>
- #include <sys/select.h>
- #include <fcntl.h>
- #include <signal.h>
- #define BUFLEN (6*1024)
- #define EXECFILE "/usr/bin/python"
- char *itoa(int n, char *s, int b) {
- static char digits[] = "0123456789abcdefghijklmnopqrstuvwxyz";
- int i=0, sign;
- if ((sign = n) < 0)
- n = -n;
- do {
- s[i++] = digits[n % b];
- } while ((n /= b) > 0);
- if (sign < 0)
- s[i++] = '-';
- s[i] = '\0';
- return s;
- }
- /*
- int set_nonblock(int sockfd) { // set socket to non blocking
- int arg,i;
- if ((arg=fcntl(sockfd, F_GETFL, NULL)) < 0) {
- printf("error getting socket flag for fd %i: fcntl(..., F_GETFL): %i\n", sockfd, errno);
- return -1;
- }
- // set O_NONBLOCK flag
- arg |= O_NONBLOCK;
- if ((i=fcntl(sockfd, F_SETFL, arg)) < 0) {
- printf("error setting socket flag for fd %i: fcntl(..., F_SETFL): %i\n", sockfd, errno);
- return -1;
- }
- return i;
- }
- int set_block(int sockfd) { // set socket to blocking
- int arg,i;
- if ((arg=fcntl(sockfd, F_GETFL, NULL)) < 0) {
- printf("error getting socket flag for fd %i: fcntl(..., F_GETFL): %i\n", sockfd, errno);
- return -1;
- }
- // clean O_NONBLOCK flag
- arg &= (~O_NONBLOCK);
- if ((i=fcntl(sockfd, F_SETFL, arg)) < 0) {
- printf("error setting socket flag for fd %i: fcntl(..., F_SETFL): %i\n", sockfd, errno);
- return -1;
- }
- return i;
- }
- */
- int main() {
- FILE *input;
- char slice[BUFLEN];
- int status = 0;
- pid_t pid;
- int err;
- int newfd;
- // if you want you can pass arguments to the program to execute
- // char *const arguments[] = {EXECFILE, "-v", NULL};
- char *const arguments[] = {EXECFILE, NULL};
- int father2child_pipefd[2];
- int child2father_pipefd[2];
- char *read_data = NULL;
- FILE *retclam;
- fd_set myset;
- int x=1;
- signal(SIGPIPE, SIG_IGN);
- newfd = dup(0);
- input = fdopen(newfd, "r");
- pipe(father2child_pipefd); // Father speaking to child
- pipe(child2father_pipefd); // Child speaking to father
- pid = fork();
- if (pid > 0) { // Father
- close(father2child_pipefd[0]);
- close(child2father_pipefd[1]);
- // Write to the pipe reading from stdin
- retclam = fdopen(child2father_pipefd[0], "r");
- // set the two fd non blocking
- //set_nonblock(0);
- //set_nonblock(child2father_pipefd[0]);
- //set_nonblock(fileno(retclam));
- while(x==1) {
- // clear the file descriptor set
- FD_ZERO(&myset);
- // add the stdin to the set
- FD_SET(fileno(input), &myset);
- // add the child pipe to the set
- FD_SET(fileno(retclam), &myset);
- // here we wait for data to arrive from stdin or from the child pipe. The last argument is a timeout, if you like
- err = select(fileno(retclam)+1, &myset, NULL, NULL, NULL);
- switch(err) {
- case -1:
- // Problem with select(). The errno variable knows why
- //exit(1);
- x=0;
- break;
- case 0:
- // timeout on select(). Data did not arrived in time, only valid if the last attribute of select() was specified
- break;
- default:
- // data is ready to be read
- bzero(slice, BUFLEN);
- if (FD_ISSET(fileno(retclam), &myset)) { // data ready on the child
- //set_block(fileno(retclam));
- read_data = fgets(slice, BUFLEN, retclam); // read a line from the child (max BUFLEN bytes)
- //set_nonblock(fileno(retclam));
- if (read_data == NULL) {
- //exit(0);
- x=0;
- break;
- }
- // write data back to stdout
- write (1, slice, strlen(slice));
- if(feof(retclam)) {
- //exit(0);
- x=0;
- break;
- }
- break;
- }
- bzero(slice, BUFLEN);
- if (FD_ISSET(fileno(input), &myset)) { // data ready on stdin
- //printf("father\n");
- //set_block(fileno(input));
- read_data = fgets(slice, BUFLEN, input); // read a line from stdin (max BUFLEN bytes)
- //set_nonblock(fileno(input));
- if (read_data == NULL) {
- //exit (0);
- close(father2child_pipefd[1]);
- waitpid(pid, &status, 0);
- //fclose(input);
- break;
- }
- // write data to the child
- write (father2child_pipefd[1], slice, strlen(slice));
- /*
- if(feof(input)) {
- exit(0);
- }*/
- break;
- }
- }
- }
- close(father2child_pipefd[1]);
- fclose(input);
- fsync(1);
- waitpid(pid, &status, 0);
- // child process terminated
- fclose (retclam);
- // Parse output data from child
- // write (1, "you can append somethind else on stdout if you like");
- if (WEXITSTATUS(status) == 0) {
- exit (0); // child process exited successfully
- }
- }
- if (pid == 0) { // Child
- close (0); // stdin is not needed
- close (1); // stdout is not needed
- // Close the write side of this pipe
- close(father2child_pipefd[1]);
- // Close the read side of this pipe
- close(child2father_pipefd[0]);
- // Let's read on stdin, but this stdin is associated to the read pipe
- dup2(father2child_pipefd[0], 0);
- // Let's speak on stdout, but this stdout is associated to the write pipe
- dup2(child2father_pipefd[1], 1);
- // if you like you can put something back to the father before execve
- //write (child2father_pipefd[1], "something", 9);
- //fsync(child2father_pipefd[1]);
- err = execve(EXECFILE, arguments, NULL);
- // we'll never be here again after execve succeeded!! So we get here only if the execve() failed
- //fprintf(stderr, "Problem executing file %s: %i: %s\n", EXECFILE, err, strerror(errno));
- exit (1);
- }
- if (pid < 0) { // Error
- exit (1);
- }
- fclose(input);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment