Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7086299
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 28, 20262026-05-28T07:31:57+00:00 2026-05-28T07:31:57+00:00

I have been stuck on this for some time. Let’s say I have a

  • 0

I have been stuck on this for some time.
Let’s say I have a C program like the following. I want to be able to send this program some string and get the control after that.
If I do:

–> cat myfile | myprogram

or

–> echo “0123” | myprogram

or

–> myprogram < myfile

I get the ouput (myfile contains “0123”)

30 31 32 33

Using the -n option raises a segfault

–> echo -n mystring | ./test

zsh: done echo -n “0123” |

zsh: segmentation fault ./test

I also tried with a named pipe, but it didn’t work either.

I would like to be able to do something like
cat myfile | myprogram
and get back the control so that I can type other characters.

  1 #include  <stdlib.h>
  2 #include  <stdio.h>
  3 
  4 int main (int argc, char *argv[]) {
  6   int i = 0, j;
  7   unsigned char buf[512];
  8   unsigned char x;
  9 
 10   while ((x = getchar()) != '\n') {
 11     buf[i] = x;
 12     i++;
 13   }
 14 
 16   for (j = 0; j < i; j++) {
 17     printf("%x ", buf[j]);
 18   }
 19   printf ( "\n" );
 20 
 21   return EXIT_SUCCESS;
 22 }  // end of function main

EDIT:

Below is the wrapper I have come up with.
It does everything I want, except that the output of the child exec-ed file is not properly displayed.

Without the wrapper:

$ bc
bc 1.06.95
Copyright 1991-1994, 1997, 1998, 2000, 2004, 2006 Free Software Foundation, Inc.
This is free software with ABSOLUTELY NO WARRANTY.
For details type `warranty'. 
2+2
4

With the wrapper:

$ ./wrapper bc
2+2
enter
4

Deleting the line

dup2(pipefd[0], 0);  // Set the read end of the pipe as stdin.

makes the child stdout display correctly, but of course breaks the wrapper.

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <sys/wait.h>
#include <fcntl.h>
#include <assert.h>

int main(int argc, char const *argv[]) {

  int cpid;
  int pipefd[2];


  if (pipe(pipefd) == -1) { perror("pipe.\n"); exit(errno); }


  cpid = fork();
  if (cpid == -1) { perror("fork."); exit(errno); }


  if (cpid) {
    // Parent --------------------------------------------------------

    int buf_size = 8192;
    char buf[buf_size];
    size_t file;

    // Close the unused read end of the pipe.
    close(pipefd[0]);

    // Leave a bit of time to the child to display its initial input.
    sleep(2);

    while (1) {
      gets(buf);

      if (strcmp("enter", buf) == 0) {
        write(pipefd[1], "\n", 1);

      } else if (-1 != (file = open(buf, O_RDONLY))) {
        // Dump the output of the file to the child's stdin.
        char c;
        while(read(file, &c, 1) != 0) {
          switch(c) {
            case '\n':
              printf("(skipped \\n)");
              break;
            default:
              printf("%c", c);
              write(pipefd[1], &c, 1);
          }; 
        }
        printf("\n");

      } else {
        // Dump input to the child's stdin, without trailing '\n'.
        for (int i = 0; (buf[i] != 0); i++) {
          write(pipefd[1], buf + i, 1);
        }
      }
    }

    // Wait for the child to exit.
    printf("Waiting for child to exit.\n");
    wait(NULL);

  } else {
    // Child ---------------------------------------------------------

    // Close the unused write end of the pipe.
    close(pipefd[1]);
    // Set the read end of the pipe as stdin.
    dup2(pipefd[0], 0);  // Set the read end of the pipe as stdin.

    char** program_arguments = (char**)(argv + 1);
    if (execvp(argv[1], program_arguments) < 0) {
      perror("execvp.\n");
      exit(errno);
    }
  }
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-28T07:31:57+00:00Added an answer on May 28, 2026 at 7:31 am

    I do not think it is possible to achieve this using named pipes if you can not modify the behavior of the program. Since in essence named pipes are no different then giving the output from standard input with redirection.

    I also do not think it is possible if you use pipe or redirection properties of the shell, since always an EOF is sent to your program in this case and you can not ignore EOF since you can not modify the program.

    A possible solution is to use a wrapper. The wrapper will first read the prepared input, send them to your program, after the prepared input finishes the wrapper switches to standard input. Actual program just keeps consuming input, it is not aware of the actual source of the data.

    Only drawback is, you can not provide prepared input with pipes or redirection, you have to supply a filename. (I’m not sure a named pipe will work or not.) The reason is obvious, if you provide the prepared input to wrapper from standard input then the same problem exists for wrapper. By this way you are just delegating the problem to wrapper, which you can design any way you want.

    A possible implementation in C (modified from a similar wrapper I’ve used, not tested extensively):

    #include <unistd.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <fcntl.h>
    
    int main(int argc, char * argv[]) {
        char c;
        char **pargs ;
    
        char buf[20];
        int n;
    
        int pipe_fd[2];
        int pid;
    
        pargs = argv+2;
        if (pipe(pipe_fd) < 0) {
                perror("pipe failed");
                exit(errno);
        }
        if ((pid=fork()) < 0) {
                perror ("Fork failed");
                exit(errno);
        }
        if (! pid) {
                close(pipe_fd[1]);
                dup2(pipe_fd[0],0);
                close(pipe_fd[0]);
                if (execvp(argv[2],pargs) < 0) {
                        perror("Exec failed");
                        exit(errno);
                }
        } else {
                size_t filedesc = open(argv[1],O_RDONLY);
                while((n = read(filedesc, buf, 100)) > 0)
                        write (pipe_fd[1], buf, n);
                while((n = read(0, buf, 100)) > 0)
                        write (pipe_fd[1], buf, n);
        }
    }
    

    You can run your program with this wrapper as :

    ./wrapper input.txt myprog possible command line arguments
    

    You can put your initial input into input.txt.

    A simpler solution is to reopen the standard input. However if you simply try to open it as if you are opening a file, it does not work. You should open the terminal stream and copy it to standard input of your application. You can do it (again by using a wrapper) with something like:

    size_t tty = open("/dev/tty",O_RDONLY);
    dup2(tty,0);
    

    Not to mention this second solution is for Linux and not portable.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I have been stuck on this for quite some time. I have searched and
I've been stuck at this for quite some time. I've looked at many other
I have been stuck on this for days, and was wondering if anyone had
Hope to get solution to this problem. I have been stuck on it since
I've been stuck with this for weeks now and have no idea where I'm
The rails books and web pages I've been following have all stuck to very
I've been using repositories for data access for some time now but have never
i've been stuck in this loop for a while. Basically i have a slider
I've been getting stuck into some linq queries for the first time today and
I really have no idea how to approach this. I've been reading for like

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.