lianergoist
Posts: 33
Joined: Sat Nov 08, 2014 12:38 pm
Location: Horsens, Denmark

Problem writing to /dev/tty

Mon Jul 09, 2018 4:11 pm

I have a little problem. I want to let the user redirect output from my program, but I still want to be able to write to write to the screen. The solution to that should be to use stdout to the text that should be redirected and /dev/tty to the text that should be printed on the screen (and not redirected).

But it is not really working for me - there is no text on screen when redirected. I have made a little demo program that show my problem. The program reads a file from stdin and print each word to stdout or, if redirected, to 'out' (/dev/tty).
[email protected]:~/c/ooo $ echo "this is a simple test " > test.txt
[email protected]:~/c/ooo $ ./test < test.txt
stdin redirected
Press 'a' to loop, or 'q' to quit
stdout: this a
stdout: is a
stdout: a a
stdout: simple a
stdout: test a
[email protected]:~/c/ooo $ ./test < test.txt > tzt
stdout redirected
stdin redirected
Press 'a' to loop, or 'q' to quit
a
a
a
a
a
out: this out: is out: a out: simple out: test [email protected]:~/c/ooo $
Note how the text is written at the end.

If I uncomment line 36 (string[numchars++] = '\n') the words are written to 'out', but I really don't want that line break. And it *should* be possible to work around it...

I think there maybe could be a solution in tcsetattr() (or stty from the command line), but I don't know how.

The code to the program is here:

Code: Select all

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

int main(int argc, char **argv) {
	FILE *in, *out;
	char string[100];
	char c;
	int numchars=0, selected;
	
	if (!isatty(fileno(stdout))) {
		fprintf(stderr, "stdout redirected\n");
	}
	
	if (!isatty(fileno(stdin))) {
		fprintf(stderr, "stdin redirected\n");
	}
	
	in = fopen("/dev/tty", "r");
	out = fopen("/dev/tty", "w");
	
	if (!in || !out) {
		fprintf(stderr, "error open tty\n");
		exit(EXIT_FAILURE);
	}
	
	fprintf(stderr, "Press 'a' to loop, or 'q' to quit\n");
	
	while ((c = fgetc(stdin)) != '\n') {
		if (c != ' ') {
			string[numchars++] = c;
		}
		else {
			//string[numchars++] = '\n';
			string[numchars] = '\0';
			numchars=0;
		
			//we have word!
			if (!isatty(fileno(stdout))) {	
				fprintf(out, "out: %s ", string);
			}
			else {
				fprintf(stdout, "stdout: %s ", string);
			}
			
			do {
				selected = fgetc(in);
			} while (selected == '\n');
			
			if (selected == 'a') {
				if (!isatty(fileno(stdout))) {	
					fprintf(stdout, "%s ", string);
				}
			}
			else if (selected == 'q') {
				break;
			}
		}
	}			
	exit(EXIT_SUCCESS);
}

Can someone explain to me what the problem is?

Well, hope someone can help me. Thanks!
Thomas Jensen

There are two types of people.
1) Those who can extrapolate from incomplete data

jahboater
Posts: 2913
Joined: Wed Feb 04, 2015 6:38 pm

Re: Problem writing to /dev/tty

Mon Jul 09, 2018 4:41 pm

I've not had a chance to look at you code, but I use this little function:-

Code: Select all

/*
 *  Ensure fd's 0 (read) and 1 (write) refer to a terminal.
 *  Return the original file for later use.
 */
static int 
tty( const int fd )
{
  const int new_fd = dup(fd);
  if( new_fd < 0 || close(fd) != 0 || open( "/dev/tty", fd == 0 ? O_RDONLY : O_WRONLY ) != fd )
    fatal( "Terminal file error" );
  return new_fd;
}

lianergoist
Posts: 33
Joined: Sat Nov 08, 2014 12:38 pm
Location: Horsens, Denmark

Re: Problem writing to /dev/tty

Mon Jul 09, 2018 5:29 pm

jahboater wrote:
Mon Jul 09, 2018 4:41 pm
I've not had a chance to look at you code, but I use this little function:-
My subject line may be a little misleading. I can write to both stdout and /dev/tty, but I have some problems with the newline character - or rather lack of newline character. Take a look at the code when you have the time - it's a rather simple demo of the issue.
Thomas Jensen

There are two types of people.
1) Those who can extrapolate from incomplete data

User avatar
joan
Posts: 13556
Joined: Thu Jul 05, 2012 5:09 pm
Location: UK

Re: Problem writing to /dev/tty

Mon Jul 09, 2018 5:42 pm

Output is buffered until a newline is seen.

lianergoist
Posts: 33
Joined: Sat Nov 08, 2014 12:38 pm
Location: Horsens, Denmark

Re: Problem writing to /dev/tty

Mon Jul 09, 2018 7:10 pm

joan wrote:
Mon Jul 09, 2018 5:42 pm
Output is buffered until a newline is seen.
I am just been told to use fflush()... I have spend hours trying to figure out what I was doing wrong, and then the answer is simply fflush()... Well, thank you.
Thomas Jensen

There are two types of people.
1) Those who can extrapolate from incomplete data

Return to “C/C++”

Who is online

Users browsing this forum: No registered users and 7 guests