Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

send up down arrow keys to process through pipe in linux using c language

Tags:

c

linux

bash

I have created two processes using fork. Created a pipe. Parent will write keys at write end of pipe and child stdin(0) will be duplicated by read end of pipe. Up to know its working very well and good for alphabets. But i want to send up and down arrow keys also, please help me.

int main()
{
   int fd[2];
   char enter = 10;
   char *exit = "exit";
   char up = 193;//what i have to use here
   char down = 194;//what i have to use here
   pipe(p);
   if(fork())
   {
    write(p[1],&up,1);              //not working
    write(p[1],&down,1);            //not working
    write(p[1],exit,strlen(exit));  //working 
    write(p[1],&enter,1);           //working
    wait(NULL);
   }
   else
   {
    close(0);
    dup(p[0]);
    execl("/bin/sh","sh",NULL);
   }
}

Please help me,

like image 784
subrahmanyeswara swamy murala Avatar asked Feb 04 '26 01:02

subrahmanyeswara swamy murala


1 Answers

There are several points:

1.) You have to invoke a shell which supports terminal editing with arrows. On a usual Linux this may be /bin/bash instead of /bin/sh.

2.) bash is checking whether it's input is coming from a terminal device or not. Depending on this, it behaves like an interactive shell or not. It seems that you want to use it in interactive mode. However pipe is not a terminal device. To get it into interactive mode you can use bash option "-i" on its invocation.

3.) As pointed by commentaries, on a usual Linux X-terminal codes for arrow up and down are multi character strings like "\033[A" and "\033[B". It depends on the device and environment you are using, maybe your values are correct for your system.

The following code works on a usual Linux environment:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main()
{
   int p[2];
   char enter = 10;
   char *exit = "exit";
   char *up = "\033[A";
   char *down = "\033[B";
   pipe(p);
   if(fork())
   {
    write(p[1],up,3);
    write(p[1],down,3);
    write(p[1],exit,strlen(exit));
    write(p[1],&enter,1);
    wait(NULL);
   }
   else
   {
    close(0);
    dup(p[0]);
    execl("/bin/bash","bash","-i",NULL);
   }
}

Also, you shall test return values of pipe and fork. Personally I'd write it like:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>

int main()
{
   int p[2];
   int r;
   char command[] = "\033[A\033[Bexit\n";

   r = pipe(p);
   if (r < 0) {
       perror("Can't create pipe");
       return(-1);
   }
   r = fork();
   if (r < 0) {
       perror("Can't fork");
       return(-1);
   } else if (r > 0) {
       close(p[0]);
       write(p[1], command, sizeof(command)-1);
       close(p[1]);
       wait(NULL);
   } else {
       close(p[1]);
       dup2(p[0], 0);
       close(p[0]);
       execl("/bin/bash","bash","-i",NULL);
   }
}
like image 193
Marian Avatar answered Feb 05 '26 16:02

Marian



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!