1

I have a c program It uses tcgetattr and tcsetattr, which stop echo of user input.

#include <stdio.h>
#include <stdlib.h>
#include <termios.h>

int
main(int argc, char **argv)
{
    struct termios oflags, nflags;
    char password[64];

    /* disabling echo */
    tcgetattr(fileno(stdin), &oflags);
    nflags = oflags;
    nflags.c_lflag &= ~ECHO;
    nflags.c_lflag |= ECHONL;

    if (tcsetattr(fileno(stdin), TCSANOW, &nflags) != 0) {
        perror("tcsetattr");
        return EXIT_FAILURE;
    }

    printf("password: ");
    fgets(password, sizeof(password), stdin);
    password[strlen(password) - 1] = 0;
    printf("you typed '%s'\n", password);

    /* restore terminal */
    if (tcsetattr(fileno(stdin), TCSANOW, &oflags) != 0) {
        perror("tcsetattr");
        return EXIT_FAILURE;
    }

    return 0;
}

I want to execute this program using shell script and give some input to it. Following steps from here I tried

$ ./test <<EOF
> hello
> EOF

and

$ ./test <<<'hello'

and

$ ./test <input 

and

$ cat input | ./test 

but all above method gave me tcsetattr: Inappropriate ioctl for device error

What is the appropriate way to run such program adding it to shell script? Or can we run it from python? If yes, how to pass inputs from python to c program?

Community
  • 1
  • 1
hiabcwelcome
  • 115
  • 1
  • 12
  • @andlrc The duplicate question asks for "way of checking to see if stdin exists". In my program stdin is present, I just have turned echo off using tcgetattr and tcsetattr. – hiabcwelcome May 25 '16 at 11:55
  • 1
    `#include int isatty(int fd); ` – wildplasser May 25 '16 at 11:56
  • @wildplasser Can you please explain? I'm not understanding what you are saying – hiabcwelcome May 25 '16 at 14:33
  • [please read the manpage for isatty() first] `stdin` is a file. But not all files have the same properties; your ioctls are only valid for some kind of files (TTYs) This applies to a lot of file operations, you cannot seek or mount a tty, and you cannot set the baudrate for a pipe or disk file, for instance. – wildplasser May 25 '16 at 14:38

1 Answers1

0

Following Expect script worked for me.

#!/usr/bin/expect
spawn ./test
expect "password:"
send "hello word\r"
interact

I got output as follows:

$ ./test.sh 
spawn ./test
password: 
you typed 'hello word'

I don't know why this worked and other won't. Please feel free to edit this answer if anyone has more explanation.

hiabcwelcome
  • 115
  • 1
  • 12