Results 1 to 6 of 6
I want to execute a Perl code in memory from my C application, just opening Perl interpreter and send code to its stdin. So, my code is:
Code:
char *perl_args[] ...
- 09-04-2010 #1Linux Newbie
- Join Date
- Apr 2010
- Location
- Novosibirsk, Russia
- Posts
- 136
IPC: need redefine stdin
I want to execute a Perl code in memory from my C application, just opening Perl interpreter and send code to its stdin. So, my code is:
but program just hangs up and never ends. Where I am wrong?.. I tried to `strace` bash when executingCode:char *perl_args[] = { "/usr/bin/perl", NULL }; char *envp = {"INVOKER=myapp", NULL }; char *code = "print 'Hello!';"; int pipe_fd[2]; pipe(pipe_fd); write(pipe_fd[1], (void*) code, strlen(code)); pid_t new_pid = fork(); if(!new_pid) { dup2(pipe_fd[0], STDIN_FILENO); execve(perl_args[0], perl_args, envp); perror("execve error"); } close(pipe_fd[1]); wait((int*)0);
and it seems to me that it uses the same actions that I try to do in my code.Code:echo 'print "HELLO!";' | perl
- 09-06-2010 #2Linux Newbie
- Join Date
- Apr 2010
- Location
- Novosibirsk, Russia
- Posts
- 136
Okay, I found 'popen()' function, and I could pass data to a program...but in this way I cannot control its stdout

I still don't understand why the 'fork()' variant does not works. When I create an unnamed pipe, I do not use any buffered i/o calling 'write()' directly and closing write end of a pipe after it. But child program still continues waiting. Neither fflush(), write_unbuffered() or fsync() does not help. If UNIX was constructed for making IPC easy and to make small programs work together, why it's so hard to make it work?
and why nobody knows how to do it?..) should I dig bash source code by myself to know it?..
- 09-06-2010 #3Linux Guru
- Join Date
- Apr 2009
- Location
- I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
- Posts
- 8,974
Your problem is probably here:
Try this instead:Code:if(!new_pid) { dup2(pipe_fd[0], STDIN_FILENO); execve(perl_args[0], perl_args, envp); perror("execve error"); } close(pipe_fd[1]); /* Don't close pipe unil wait() detects the end of the child process. */ wait((int*)0);
Code:if(!new_pid) { dup2(pipe_fd[0], STDIN_FILENO); execve(perl_args[0], perl_args, envp); perror("execve error"); } else { waitpid(new_pid, 0, 0); close(pipe_fd[1]); }Sometimes, real fast is almost as good as real time.
Just remember, Semper Gumbi - always be flexible!
- 09-06-2010 #4Linux Guru
- Join Date
- Apr 2009
- Location
- I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
- Posts
- 8,974
One other thing. You should not write to pipe_fd[1] in the parent until in the parent part of the process after the fork(). Also, in the child part, close pipe_fd[1] before exceve(). In the parent part, close pipe_fd[0], and then write to pipe_fd[1], close pipe_fd[1], waitpid(), and then exit. So, this is better:
A decent overview for use of pipes is found in the section 7 man page for pipe: man 7 pipeCode:char *perl_args[] = { "/usr/bin/perl", NULL }; char *envp = {"INVOKER=myapp", NULL }; char *code = "print 'Hello!';"; int pipe_fd[2]; pid_t new_pid = 0; pipe(pipe_fd); new_pid = fork(); if(!new_pid) { close(pipd_fd[1]); dup2(pipe_fd[0], STDIN_FILENO); execve(perl_args[0], perl_args, envp); /* Error starting perl - clean up here */ perror("execve error"); close(pipe_fd[0]); } else { close(pipe_fd[0]); write(pipe_fd[1], (const void*) code, strlen(code)); close(pipe_fd[1]); waitpid(new_pid, 0, 0); /* Optionally, use wait(0) */ }
and man 2 pipe has a good example of use of pipes for IPC in a situation similar to what you are trying to do.Sometimes, real fast is almost as good as real time.
Just remember, Semper Gumbi - always be flexible!
- 09-17-2010 #5Linux Newbie
- Join Date
- Apr 2010
- Location
- Novosibirsk, Russia
- Posts
- 136
Thanks a lot, it works now!
at last I understood how the unix-like I/O works by reading some books in addition to your post ) thanks for the light in my head)
- 09-18-2010 #6Linux Guru
- Join Date
- Apr 2009
- Location
- I can be found either 40 miles west of Chicago, or in a galaxy far, far away.
- Posts
- 8,974
Yeah. A brick (upside the head) works much the same for me!
Sometimes, real fast is almost as good as real time.
Just remember, Semper Gumbi - always be flexible!


Reply With Quote