Writing to stdin of another program / reading from stdout of another program in c

This is a homework question. I have 3 programs A, B and C, they are not father / child processes, but separate programs. B should write a message ("Hello") to stdin from A and read another message ("Hello") from stdout C. What concept should I use to implement it? I've looked around for a while, but I couldn't find anything suitable. I thought I should be using FIFO, but I couldn't redirect the channels. Can I use dup2 with FIFO? if so, how? This isn't homework, it's just the way it should work. Then I will implement other things on it. (I can post my basic fifo code, if so, just don't do it now because I'm not sure)

+3


source to share


2 answers


Let me know if I miss the question.

Let's say you create programs A

, B

and C

. You can use man 1 mkfifo

or programmatically man 3 mkfifo

to create named pipes.

Then each of your processes will open(2)

use them dup2(2)

according to their needs.

For example, a program A

might redirect it stdout

like this:



int fifo = open("fifo_1", O_WRONLY);
dup2(fifo, 1);

      

or the program B

can redirect both of it stdin

and stdout

like this:

int fifo_in = open("fifo_1", O_RDONLY);
int fifo_out = open("fifo_2", O_WRONLY);

dup2(fifo_in, 0);
dup2(fifo_out, 1);

      

or whatever you need.

+2


source


I changed this code as @chrk explained. This is an example of a FIFO from the book "Advanced Unix Programming". A simple server-client example. The client sends three lines with lower lines to the server, the server makes them top and sends back to the client via a FIFO ("fifo # clientpid" is the client's fifo name). The client prints them out at their level. So I changed it so that after receiving a message from the client, the server writes the top-level strings to the client's STDINT. And the client reads them from STDINT and prints to his stdout. It works as I expected. Thanks for the help. At first I did the wrong way. With chrk code I wrote it again. Here is the code:

client withdrawal

client 2941 started
client 2941: applesauce --> APPLESAUCE
client 2941: tiger --> TIGER
client 2941: mountain --> MOUNTAIN
Client 2941 done

      

Server:



#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <ctype.h>

#define ec_neg1(s,m) if((s) == -1) {perror(m); exit(errno);}

#define SERVER_FIFO_NAME "fifo_server"
#define PERM_FILE        0664

struct simple_message {
pid_t sm_clientpid;
char sm_data[200];
};


int main()
{
  int fd_server, fd_client, i;
  ssize_t nread;
  struct simple_message msg;
  char fifo_name[100];
  printf("server started\n");

  if (mkfifo(SERVER_FIFO_NAME, PERM_FILE) == -1 && errno != EEXIST)
  {perror("can't make fifo"); exit(errno); }

  ec_neg1( fd_server = open(SERVER_FIFO_NAME, O_RDWR), "cant open fd_server" )

  while (1) 
  {
     ec_neg1( nread = read(fd_server, &msg, sizeof(msg)), "can't read from fd_server")

     if (nread == 0) {
       errno = ENETDOWN;
       perror("nread == 0"); exit(errno);
      }

     for (i = 0; msg.sm_data[i] != '\0'; i++)
       msg.sm_data[i] = toupper(msg.sm_data[i]);

     make_fifo_name(msg.sm_clientpid, fifo_name, sizeof(fifo_name));

     ec_neg1( fd_client = open(fifo_name, O_WRONLY), "can't open fifo_name" )

     ec_neg1( write(fd_client, &msg, sizeof(msg)), "can't write to fd_client" )

     ec_neg1( close(fd_client), "can't close fd_client" )
   }

/* never actually get here */
 ec_neg1( close(fd_server), "can't close fd_server" )
 exit(EXIT_SUCCESS);

 return 0;

 }


int make_fifo_name(pid_t pid, char *name, size_t name_max)
{
 snprintf(name, name_max, "fifo%ld", (long)pid);
 return 0;
}

      

customer

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

#define ec_neg1(s,m) if((s) == -1) {perror(m); exit(errno);}

#define SERVER_FIFO_NAME "fifo_server"
#define PERM_FILE        0664

struct simple_message {
pid_t sm_clientpid;
char sm_data[200];
};


int make_fifo_name(pid_t pid, char *name, size_t name_max)
{
 snprintf(name, name_max, "fifo%ld", (long)pid);
 return 0;
}

int main()
{
 int fd_server, fd_client = -1, i;
 ssize_t nread;
 struct simple_message msg;
 char fifo_name[100];
 char *work[] = {
   "applesauce",
   "tiger",
   "mountain",
   NULL
 };

 printf("client %ld started\n", (long)getpid());

 msg.sm_clientpid = getpid();

 make_fifo_name(msg.sm_clientpid, fifo_name,
       sizeof(fifo_name));

 if (mkfifo(fifo_name, PERM_FILE) == -1 && errno != EEXIST)
   {perror("can't make fifo"); exit(errno); }

 ec_neg1( fd_server = open(SERVER_FIFO_NAME, O_WRONLY), "can't open fd_server" )

 for (i = 0; work[i] != NULL; i++) 
 {
   strcpy(msg.sm_data, work[i]);

   ec_neg1( write(fd_server, &msg, sizeof(msg)),"can't write to fd_server" )

   if (fd_client == -1){
     ec_neg1( fd_client = open(fifo_name, O_RDWR), "can't open fifo_name"  )
     ec_neg1(dup2(fd_client, 0), "can't duplicate stdin")
   }
     ec_neg1( nread = read(0, &msg, sizeof(msg)), "can't read from fd_client" )
   if (nread == 0) {
       errno = ENETDOWN;
       perror("nread == 0"); exit(errno);
   }
   printf("client %ld: %s --> %s\n", (long)getpid(),
             work[i], msg.sm_data);
 }

 ec_neg1( close(fd_server), "can't close fd_server" )
 ec_neg1( close(fd_client), "can't close fd_client" )
 ec_neg1( unlink(fifo_name), "can't unlink fifo_name" )

 printf("Client %ld done\n", (long)getpid());
 exit(EXIT_SUCCESS);

}

      

+1


source







All Articles