This is probably because Eclipse is not providing a pseudoterminal to programs run under the IDE. Try this alternative which relies on nonblocking I/O rather than terminal controls.
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define perror_exit(msg) do { perror(msg); exit(1); } while(0)
#if defined EAGAIN && defined EWOULDBLOCK
#define retry_p(err) ((err) == EAGAIN || (err) == EWOULDBLOCK)
#elif defined EAGAIN
#define retry_p(err) ((err) == EAGAIN)
#elif defined EWOULDBLOCK
#define retry_p(err) ((err) == EWOULDBLOCK)
#else
#error "Don't know how to detect read-would-block condition."
#endif
int
main(void)
{
int flags = fcntl(0, F_GETFL);
if (flags == -1)
perror_exit("fcntl(F_GETFL)");
flags |= O_NONBLOCK;
if (fcntl(0, F_SETFL, flags))
perror_exit("fcntl(F_SETFL, O_NONBLOCK)");
for (;;)
{
char ch;
ssize_t n = read(0, &ch, 1);
if (n == 1)
{
putchar(ch);
if (ch == 'q')
break;
}
else if (n < 0 && !retry_p(errno))
perror_exit("read");
}
return 0;
}
If this still doesn't work, try modifying it to do both what this does and what your getch()
does, ignoring failure of tcsetattr
and tcgetattr
when errno == ENOTTY
.
Note that both this and your original code are busy-waiting for I/O, which is bad practice. What you really should be doing is using the ncurses library, which has a more sophisticated approach to simultaneous processing and waiting for input that fits better with a multitasking environment, and also deals with your lack-of-a-tty problem and any number of other low-level headaches that you don't want to waste effort on.