Redirect printf() to STDIN of another process












0















I have been trying to write some code that redirects writes to STDOUT_FILENO, via write(1, line, strlen(line)) or printf(), to the STDIN_FILENO of another process. The other process will be /usr/bin/less. Nothing seems to work, despite trying quite a few attempts on this site, a lot of man page reading and trying every combination of close() and dup2().



Appreciate your help, thanks.



#include  <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <termios.h>
#include <unistd.h>
#define INPUT_END 1
#define OUTPUT_END 0
int main(int argc, char* argv){
pid_t pid1;
pid_t pid2;
int fd1[2], fd2[2];
int x;
pipe(fd1);
pipe(fd2);
pid1 = fork();

if (pid1 == -1) {
fprintf(stderr, "pid errorn");
exit(1);
}

if(pid1 == 0) {
close(fd1[INPUT_END]);
dup2(fd1[OUTPUT_END], STDIN_FILENO);
close(fd1[OUTPUT_END]);
close(fd2[OUTPUT_END]);
dup2(fd2[INPUT_END], STDOUT_FILENO);
close(fd2[INPUT_END]);
execlp("less", "-r",(char*) NULL);

}else {
close(fd1[OUTPUT_END]);
dup2(fd1[INPUT_END], STDOUT_FILENO);
close(fd1[INPUT_END]);
close(fd2[INPUT_END]);
dup2(fd2[OUTPUT_END], STDIN_FILENO);
close(fd2[OUTPUT_END]);

for(x=0;x<100;x++) {
write(STDOUT_FILENO, "AAAn", 4);
printf("AAAn");
fflush(stdout);
}

close(fd1[OUTPUT_END]);
close(fd1[INPUT_END]);
close(fd2[OUTPUT_END]);
close(fd2[INPUT_END]);
waitpid(-1, NULL, 0);
}
}









share|improve this question

























  • Someone on IRC helped me out with this code. However, it uses filepointers, rather than overwriting stdout: pastebin.de/10715 However, I am have a requirement to dup2() over the STDOUT, which doesn't seem to do the trick.

    – Farhan Yusufzai
    Nov 20 '18 at 1:44


















0















I have been trying to write some code that redirects writes to STDOUT_FILENO, via write(1, line, strlen(line)) or printf(), to the STDIN_FILENO of another process. The other process will be /usr/bin/less. Nothing seems to work, despite trying quite a few attempts on this site, a lot of man page reading and trying every combination of close() and dup2().



Appreciate your help, thanks.



#include  <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <termios.h>
#include <unistd.h>
#define INPUT_END 1
#define OUTPUT_END 0
int main(int argc, char* argv){
pid_t pid1;
pid_t pid2;
int fd1[2], fd2[2];
int x;
pipe(fd1);
pipe(fd2);
pid1 = fork();

if (pid1 == -1) {
fprintf(stderr, "pid errorn");
exit(1);
}

if(pid1 == 0) {
close(fd1[INPUT_END]);
dup2(fd1[OUTPUT_END], STDIN_FILENO);
close(fd1[OUTPUT_END]);
close(fd2[OUTPUT_END]);
dup2(fd2[INPUT_END], STDOUT_FILENO);
close(fd2[INPUT_END]);
execlp("less", "-r",(char*) NULL);

}else {
close(fd1[OUTPUT_END]);
dup2(fd1[INPUT_END], STDOUT_FILENO);
close(fd1[INPUT_END]);
close(fd2[INPUT_END]);
dup2(fd2[OUTPUT_END], STDIN_FILENO);
close(fd2[OUTPUT_END]);

for(x=0;x<100;x++) {
write(STDOUT_FILENO, "AAAn", 4);
printf("AAAn");
fflush(stdout);
}

close(fd1[OUTPUT_END]);
close(fd1[INPUT_END]);
close(fd2[OUTPUT_END]);
close(fd2[INPUT_END]);
waitpid(-1, NULL, 0);
}
}









share|improve this question

























  • Someone on IRC helped me out with this code. However, it uses filepointers, rather than overwriting stdout: pastebin.de/10715 However, I am have a requirement to dup2() over the STDOUT, which doesn't seem to do the trick.

    – Farhan Yusufzai
    Nov 20 '18 at 1:44
















0












0








0








I have been trying to write some code that redirects writes to STDOUT_FILENO, via write(1, line, strlen(line)) or printf(), to the STDIN_FILENO of another process. The other process will be /usr/bin/less. Nothing seems to work, despite trying quite a few attempts on this site, a lot of man page reading and trying every combination of close() and dup2().



Appreciate your help, thanks.



#include  <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <termios.h>
#include <unistd.h>
#define INPUT_END 1
#define OUTPUT_END 0
int main(int argc, char* argv){
pid_t pid1;
pid_t pid2;
int fd1[2], fd2[2];
int x;
pipe(fd1);
pipe(fd2);
pid1 = fork();

if (pid1 == -1) {
fprintf(stderr, "pid errorn");
exit(1);
}

if(pid1 == 0) {
close(fd1[INPUT_END]);
dup2(fd1[OUTPUT_END], STDIN_FILENO);
close(fd1[OUTPUT_END]);
close(fd2[OUTPUT_END]);
dup2(fd2[INPUT_END], STDOUT_FILENO);
close(fd2[INPUT_END]);
execlp("less", "-r",(char*) NULL);

}else {
close(fd1[OUTPUT_END]);
dup2(fd1[INPUT_END], STDOUT_FILENO);
close(fd1[INPUT_END]);
close(fd2[INPUT_END]);
dup2(fd2[OUTPUT_END], STDIN_FILENO);
close(fd2[OUTPUT_END]);

for(x=0;x<100;x++) {
write(STDOUT_FILENO, "AAAn", 4);
printf("AAAn");
fflush(stdout);
}

close(fd1[OUTPUT_END]);
close(fd1[INPUT_END]);
close(fd2[OUTPUT_END]);
close(fd2[INPUT_END]);
waitpid(-1, NULL, 0);
}
}









share|improve this question
















I have been trying to write some code that redirects writes to STDOUT_FILENO, via write(1, line, strlen(line)) or printf(), to the STDIN_FILENO of another process. The other process will be /usr/bin/less. Nothing seems to work, despite trying quite a few attempts on this site, a lot of man page reading and trying every combination of close() and dup2().



Appreciate your help, thanks.



#include  <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <sys/stat.h>
#include <termios.h>
#include <unistd.h>
#define INPUT_END 1
#define OUTPUT_END 0
int main(int argc, char* argv){
pid_t pid1;
pid_t pid2;
int fd1[2], fd2[2];
int x;
pipe(fd1);
pipe(fd2);
pid1 = fork();

if (pid1 == -1) {
fprintf(stderr, "pid errorn");
exit(1);
}

if(pid1 == 0) {
close(fd1[INPUT_END]);
dup2(fd1[OUTPUT_END], STDIN_FILENO);
close(fd1[OUTPUT_END]);
close(fd2[OUTPUT_END]);
dup2(fd2[INPUT_END], STDOUT_FILENO);
close(fd2[INPUT_END]);
execlp("less", "-r",(char*) NULL);

}else {
close(fd1[OUTPUT_END]);
dup2(fd1[INPUT_END], STDOUT_FILENO);
close(fd1[INPUT_END]);
close(fd2[INPUT_END]);
dup2(fd2[OUTPUT_END], STDIN_FILENO);
close(fd2[OUTPUT_END]);

for(x=0;x<100;x++) {
write(STDOUT_FILENO, "AAAn", 4);
printf("AAAn");
fflush(stdout);
}

close(fd1[OUTPUT_END]);
close(fd1[INPUT_END]);
close(fd2[OUTPUT_END]);
close(fd2[INPUT_END]);
waitpid(-1, NULL, 0);
}
}






redirect fork stdout dup2






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 20 '18 at 4:45









kit

1,1063816




1,1063816










asked Nov 20 '18 at 1:10









Farhan YusufzaiFarhan Yusufzai

52111




52111













  • Someone on IRC helped me out with this code. However, it uses filepointers, rather than overwriting stdout: pastebin.de/10715 However, I am have a requirement to dup2() over the STDOUT, which doesn't seem to do the trick.

    – Farhan Yusufzai
    Nov 20 '18 at 1:44





















  • Someone on IRC helped me out with this code. However, it uses filepointers, rather than overwriting stdout: pastebin.de/10715 However, I am have a requirement to dup2() over the STDOUT, which doesn't seem to do the trick.

    – Farhan Yusufzai
    Nov 20 '18 at 1:44



















Someone on IRC helped me out with this code. However, it uses filepointers, rather than overwriting stdout: pastebin.de/10715 However, I am have a requirement to dup2() over the STDOUT, which doesn't seem to do the trick.

– Farhan Yusufzai
Nov 20 '18 at 1:44







Someone on IRC helped me out with this code. However, it uses filepointers, rather than overwriting stdout: pastebin.de/10715 However, I am have a requirement to dup2() over the STDOUT, which doesn't seem to do the trick.

– Farhan Yusufzai
Nov 20 '18 at 1:44














1 Answer
1






active

oldest

votes


















0














Your program does exactly what you programmed it to do: It creates two pipes and a child running less, using the pipes to redirect stdout of the program to stdin of less AND stdout of less to stdin of the program. It then writes a bunch of data (which less will copy to its stdout -- stdin of the program) and the waits for less to exit. But that will never happen, as less is waiting for more input.



If you want things to stop, you'll need to close(STDOUT_FILENO) before the call to waitpid -- if you add this, less will exit, and the waitpid will return and your program will then proceed (and exit). You still won't see anything on your terminal, as nothing is ever being written to the terminal -- less is writing to stdin of your program (which you are never reading).



If you increase the amount of data being written, you will see a deadlock -- as you are never reading stdin, once the fd2 pipe fills up, less will block writing, and then once fd1 also fills up, your program will block. The default pipe sizes on Linux are quite large, however, so this will take a lot of data.



Note that you could just as well use cat as less -- less essentially devolves to cat when stdout is not a terminal.



If what you want is to output data to your terminal, using less to mediate that (stopping after a page, etc), then you need to leave stdout of less pointing at your terminal. Simply delete fd2 and every line referring to fd2 from your above code, and it should work -- though it will still hang at the end if you don't close(STDOUT_FILENO)






share|improve this answer


























  • I added that line close(STDOUT_FILENO), but instead of reading even a little bit, it immediately ending. If 'less' is executed at all, I get no messages whatsoever. I do not want to increase the amount of data read, I want it to be unlimited data - at least send data in "chunks". Is that possible?

    – Farhan Yusufzai
    Nov 20 '18 at 4:50











  • You get no messages because you've redirected them to stdin of your program, which you never read.

    – Chris Dodd
    Nov 20 '18 at 5:41











  • To be clear, is that in reference to this line? dup2(fd2[INPUT_END], STDOUT_FILENO);?

    – Farhan Yusufzai
    Nov 20 '18 at 6:18











  • @FarhanYusufzai: yes, that is the line that redirects stdout of less to the fd2 pipe input

    – Chris Dodd
    Nov 21 '18 at 5:58













Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53384838%2fredirect-printf-to-stdin-of-another-process%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes









0














Your program does exactly what you programmed it to do: It creates two pipes and a child running less, using the pipes to redirect stdout of the program to stdin of less AND stdout of less to stdin of the program. It then writes a bunch of data (which less will copy to its stdout -- stdin of the program) and the waits for less to exit. But that will never happen, as less is waiting for more input.



If you want things to stop, you'll need to close(STDOUT_FILENO) before the call to waitpid -- if you add this, less will exit, and the waitpid will return and your program will then proceed (and exit). You still won't see anything on your terminal, as nothing is ever being written to the terminal -- less is writing to stdin of your program (which you are never reading).



If you increase the amount of data being written, you will see a deadlock -- as you are never reading stdin, once the fd2 pipe fills up, less will block writing, and then once fd1 also fills up, your program will block. The default pipe sizes on Linux are quite large, however, so this will take a lot of data.



Note that you could just as well use cat as less -- less essentially devolves to cat when stdout is not a terminal.



If what you want is to output data to your terminal, using less to mediate that (stopping after a page, etc), then you need to leave stdout of less pointing at your terminal. Simply delete fd2 and every line referring to fd2 from your above code, and it should work -- though it will still hang at the end if you don't close(STDOUT_FILENO)






share|improve this answer


























  • I added that line close(STDOUT_FILENO), but instead of reading even a little bit, it immediately ending. If 'less' is executed at all, I get no messages whatsoever. I do not want to increase the amount of data read, I want it to be unlimited data - at least send data in "chunks". Is that possible?

    – Farhan Yusufzai
    Nov 20 '18 at 4:50











  • You get no messages because you've redirected them to stdin of your program, which you never read.

    – Chris Dodd
    Nov 20 '18 at 5:41











  • To be clear, is that in reference to this line? dup2(fd2[INPUT_END], STDOUT_FILENO);?

    – Farhan Yusufzai
    Nov 20 '18 at 6:18











  • @FarhanYusufzai: yes, that is the line that redirects stdout of less to the fd2 pipe input

    – Chris Dodd
    Nov 21 '18 at 5:58


















0














Your program does exactly what you programmed it to do: It creates two pipes and a child running less, using the pipes to redirect stdout of the program to stdin of less AND stdout of less to stdin of the program. It then writes a bunch of data (which less will copy to its stdout -- stdin of the program) and the waits for less to exit. But that will never happen, as less is waiting for more input.



If you want things to stop, you'll need to close(STDOUT_FILENO) before the call to waitpid -- if you add this, less will exit, and the waitpid will return and your program will then proceed (and exit). You still won't see anything on your terminal, as nothing is ever being written to the terminal -- less is writing to stdin of your program (which you are never reading).



If you increase the amount of data being written, you will see a deadlock -- as you are never reading stdin, once the fd2 pipe fills up, less will block writing, and then once fd1 also fills up, your program will block. The default pipe sizes on Linux are quite large, however, so this will take a lot of data.



Note that you could just as well use cat as less -- less essentially devolves to cat when stdout is not a terminal.



If what you want is to output data to your terminal, using less to mediate that (stopping after a page, etc), then you need to leave stdout of less pointing at your terminal. Simply delete fd2 and every line referring to fd2 from your above code, and it should work -- though it will still hang at the end if you don't close(STDOUT_FILENO)






share|improve this answer


























  • I added that line close(STDOUT_FILENO), but instead of reading even a little bit, it immediately ending. If 'less' is executed at all, I get no messages whatsoever. I do not want to increase the amount of data read, I want it to be unlimited data - at least send data in "chunks". Is that possible?

    – Farhan Yusufzai
    Nov 20 '18 at 4:50











  • You get no messages because you've redirected them to stdin of your program, which you never read.

    – Chris Dodd
    Nov 20 '18 at 5:41











  • To be clear, is that in reference to this line? dup2(fd2[INPUT_END], STDOUT_FILENO);?

    – Farhan Yusufzai
    Nov 20 '18 at 6:18











  • @FarhanYusufzai: yes, that is the line that redirects stdout of less to the fd2 pipe input

    – Chris Dodd
    Nov 21 '18 at 5:58
















0












0








0







Your program does exactly what you programmed it to do: It creates two pipes and a child running less, using the pipes to redirect stdout of the program to stdin of less AND stdout of less to stdin of the program. It then writes a bunch of data (which less will copy to its stdout -- stdin of the program) and the waits for less to exit. But that will never happen, as less is waiting for more input.



If you want things to stop, you'll need to close(STDOUT_FILENO) before the call to waitpid -- if you add this, less will exit, and the waitpid will return and your program will then proceed (and exit). You still won't see anything on your terminal, as nothing is ever being written to the terminal -- less is writing to stdin of your program (which you are never reading).



If you increase the amount of data being written, you will see a deadlock -- as you are never reading stdin, once the fd2 pipe fills up, less will block writing, and then once fd1 also fills up, your program will block. The default pipe sizes on Linux are quite large, however, so this will take a lot of data.



Note that you could just as well use cat as less -- less essentially devolves to cat when stdout is not a terminal.



If what you want is to output data to your terminal, using less to mediate that (stopping after a page, etc), then you need to leave stdout of less pointing at your terminal. Simply delete fd2 and every line referring to fd2 from your above code, and it should work -- though it will still hang at the end if you don't close(STDOUT_FILENO)






share|improve this answer















Your program does exactly what you programmed it to do: It creates two pipes and a child running less, using the pipes to redirect stdout of the program to stdin of less AND stdout of less to stdin of the program. It then writes a bunch of data (which less will copy to its stdout -- stdin of the program) and the waits for less to exit. But that will never happen, as less is waiting for more input.



If you want things to stop, you'll need to close(STDOUT_FILENO) before the call to waitpid -- if you add this, less will exit, and the waitpid will return and your program will then proceed (and exit). You still won't see anything on your terminal, as nothing is ever being written to the terminal -- less is writing to stdin of your program (which you are never reading).



If you increase the amount of data being written, you will see a deadlock -- as you are never reading stdin, once the fd2 pipe fills up, less will block writing, and then once fd1 also fills up, your program will block. The default pipe sizes on Linux are quite large, however, so this will take a lot of data.



Note that you could just as well use cat as less -- less essentially devolves to cat when stdout is not a terminal.



If what you want is to output data to your terminal, using less to mediate that (stopping after a page, etc), then you need to leave stdout of less pointing at your terminal. Simply delete fd2 and every line referring to fd2 from your above code, and it should work -- though it will still hang at the end if you don't close(STDOUT_FILENO)







share|improve this answer














share|improve this answer



share|improve this answer








edited Nov 20 '18 at 5:43

























answered Nov 20 '18 at 3:17









Chris DoddChris Dodd

81.4k681160




81.4k681160













  • I added that line close(STDOUT_FILENO), but instead of reading even a little bit, it immediately ending. If 'less' is executed at all, I get no messages whatsoever. I do not want to increase the amount of data read, I want it to be unlimited data - at least send data in "chunks". Is that possible?

    – Farhan Yusufzai
    Nov 20 '18 at 4:50











  • You get no messages because you've redirected them to stdin of your program, which you never read.

    – Chris Dodd
    Nov 20 '18 at 5:41











  • To be clear, is that in reference to this line? dup2(fd2[INPUT_END], STDOUT_FILENO);?

    – Farhan Yusufzai
    Nov 20 '18 at 6:18











  • @FarhanYusufzai: yes, that is the line that redirects stdout of less to the fd2 pipe input

    – Chris Dodd
    Nov 21 '18 at 5:58





















  • I added that line close(STDOUT_FILENO), but instead of reading even a little bit, it immediately ending. If 'less' is executed at all, I get no messages whatsoever. I do not want to increase the amount of data read, I want it to be unlimited data - at least send data in "chunks". Is that possible?

    – Farhan Yusufzai
    Nov 20 '18 at 4:50











  • You get no messages because you've redirected them to stdin of your program, which you never read.

    – Chris Dodd
    Nov 20 '18 at 5:41











  • To be clear, is that in reference to this line? dup2(fd2[INPUT_END], STDOUT_FILENO);?

    – Farhan Yusufzai
    Nov 20 '18 at 6:18











  • @FarhanYusufzai: yes, that is the line that redirects stdout of less to the fd2 pipe input

    – Chris Dodd
    Nov 21 '18 at 5:58



















I added that line close(STDOUT_FILENO), but instead of reading even a little bit, it immediately ending. If 'less' is executed at all, I get no messages whatsoever. I do not want to increase the amount of data read, I want it to be unlimited data - at least send data in "chunks". Is that possible?

– Farhan Yusufzai
Nov 20 '18 at 4:50





I added that line close(STDOUT_FILENO), but instead of reading even a little bit, it immediately ending. If 'less' is executed at all, I get no messages whatsoever. I do not want to increase the amount of data read, I want it to be unlimited data - at least send data in "chunks". Is that possible?

– Farhan Yusufzai
Nov 20 '18 at 4:50













You get no messages because you've redirected them to stdin of your program, which you never read.

– Chris Dodd
Nov 20 '18 at 5:41





You get no messages because you've redirected them to stdin of your program, which you never read.

– Chris Dodd
Nov 20 '18 at 5:41













To be clear, is that in reference to this line? dup2(fd2[INPUT_END], STDOUT_FILENO);?

– Farhan Yusufzai
Nov 20 '18 at 6:18





To be clear, is that in reference to this line? dup2(fd2[INPUT_END], STDOUT_FILENO);?

– Farhan Yusufzai
Nov 20 '18 at 6:18













@FarhanYusufzai: yes, that is the line that redirects stdout of less to the fd2 pipe input

– Chris Dodd
Nov 21 '18 at 5:58







@FarhanYusufzai: yes, that is the line that redirects stdout of less to the fd2 pipe input

– Chris Dodd
Nov 21 '18 at 5:58






















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53384838%2fredirect-printf-to-stdin-of-another-process%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







這個網誌中的熱門文章

Xamarin.form Move up view when keyboard appear

Post-Redirect-Get with Spring WebFlux and Thymeleaf

Anylogic : not able to use stopDelay()