Reopening stdin, stdout or stderr in c - c

I've seen this Question.
It says that we could make a copy of both the file descriptors of stdin and stdout, in order for us to reopen them at a later stage in the program.
My questions:
Could we open the file "/dev/tty" in O_WRONLY mode in order to reopen stdout?
Is this the correct method of doing it?
Is there any similar method to reopen stdin and stderr??

No, the method you posit is not the correct method. The /dev/tty "device" is your terminal device and it doesn't necessarily hold that that's where your standard output is going.
For example, if you run your program as:
yourprog >output.txt
then opening /dev/tty will not get you your starting standard output (which is the output.txt file).

Related

Explaining the use of "stdin" in the end of fgets() function [duplicate]

I was tasked with creating a test program in C that reads the contents of the standard input and then prints them.
But I have a little doubt: what is exactly standard input?
Is it what I type in the keyboard? Is it a file I have to read?
Both of them?
And the same goes for standard output: is it the console? a file?
The C standard (e.g. C99 or C11) defines what should be expected from the standard <stdio.h> header (after having suitably #include-d it). See stdio(3) man page.
Then you have the stdin and stdout and stderr file handles (pointers to some FILE which is an abstract data type).
The fact that stdin is related to some device (e.g. a keyboard) is implementation specific.
You could (but that would be unethical and/or inefficient) implement the C standard with e.g. a room of human slaves (that is unethical, if you use paid workers that would be just inefficient), instead of using a computer. Often, computers gives your some implementation of the C standard thru the help of some operating system.
You may want to know, inside your C program, if stdin is a "keyboard" or redirected from some "file". Unfortunately, AFAIK, there is no C99-standard way to know that.
As you mention, stdin, stdout and stderr should be available in your program at startup (i.e. after entering main ....). Hence, unless you fclose the stdin stream, you can read it (with getchar, scanf, getline, fgets, fscanf ... and friends) without any prior care (so you don't need to fopen it yourself).
On Linux or most Posix systems, you might use as an approximation isatty(STDIN_FILENO) - see isatty(3) for more - to test if stdin "is" the "keyboard" (by testing if it is some tty). See also this & that.
Yes, standard input (stdin) is input exepected from the keyboard. So, could be in the form of user input from a basic program or from a command line argument. Standard output (stdout) is the output of the code, usually to the terminal window. You could output your code almost anywhere, i.e. to a file, to a textbox, browser, but the standard is the stdout which is the terminal.
Hope that helps.
Normally, the standard input is the keyboard and the standard output the screen. However, you can redirect this in the command line using the "<" and ">" symbols. A command line like
dir /s > "Tree.txt"
will change the standard output for the dir command to be the specified file. So all output goes to that file. The called application or command itself doesn't normally even notice the difference.
stdin is file descriptor 0, you can get a file to stdin by:
cat file |yourprog
#or
yourprog <file
likewise for stdout (file descriptor 1)
yourprog | someotherprog #pipe your stdout to the stdin of another program
yourprog > somefile #save stdout to a file
yourprog >> somefile #append stdout to a file
and stderr (fd 2)
yourprog 2> errlogfile
if you have a program that takes a file but doesn't handle stdin, you can use the above formats by doing this (assuming -f if the input file argument)
myprog -f /dev/stdin
//and a horrible example of how not to read from stdin and write to stdout
char buf[4096];
while(write(1,buf,read(0,buf,4096)));
standard output (or stdout) refers to the standardized streams of data that are produced by command line programs (i.e., all-text mode programs) in Linux and other Unix-like operating systems.

Input from a file (using command line) and then normal stdin keyboard input (C)

Is there a possible way to use a *.txt file as an input for certain things using command below -
a.out<input.txt
And then use normal inputs from the user?
One option is to use:
$ ./a.out input.txt # No shell I/O redirection
You then open (each of) the command line argument(s) for reading, read it, and close it. When you're done, you can read from stdin until EOF.
On a Unix-like system, you could also support:
$ ./a.out < input.txt # Shell I/O redirection
and read from standard input to EOF, and then do one of a number of things to read from the keyboard:
Open /dev/tty and read from that.
Open /dev/tty and duplicate it to stdin (freopen()).
There are some less kosher possibilities too; one is to use the standard output or standard error file descriptor as an input file descriptor, using fdopen(). This will often work if the streams are connected to a terminal. The classic way to start a shell is to open /dev/tty for reading and writing, and then duplicate the read/write descriptor to standard input, output and error. If the output is piped to another program, or redirected to a file, this won't work, of course. You could use isatty() to check whether the file descriptors are associated with a terminal or not.
There are probably other ways to do it too — different ones if you're on Windows.
Personally, I'd go with the 'read command line arguments as files, then read standard input' option, but YMMV.

What is “standard input”?

I was tasked with creating a test program in C that reads the contents of the standard input and then prints them.
But I have a little doubt: what is exactly standard input?
Is it what I type in the keyboard? Is it a file I have to read?
Both of them?
And the same goes for standard output: is it the console? a file?
The C standard (e.g. C99 or C11) defines what should be expected from the standard <stdio.h> header (after having suitably #include-d it). See stdio(3) man page.
Then you have the stdin and stdout and stderr file handles (pointers to some FILE which is an abstract data type).
The fact that stdin is related to some device (e.g. a keyboard) is implementation specific.
You could (but that would be unethical and/or inefficient) implement the C standard with e.g. a room of human slaves (that is unethical, if you use paid workers that would be just inefficient), instead of using a computer. Often, computers gives your some implementation of the C standard thru the help of some operating system.
You may want to know, inside your C program, if stdin is a "keyboard" or redirected from some "file". Unfortunately, AFAIK, there is no C99-standard way to know that.
As you mention, stdin, stdout and stderr should be available in your program at startup (i.e. after entering main ....). Hence, unless you fclose the stdin stream, you can read it (with getchar, scanf, getline, fgets, fscanf ... and friends) without any prior care (so you don't need to fopen it yourself).
On Linux or most Posix systems, you might use as an approximation isatty(STDIN_FILENO) - see isatty(3) for more - to test if stdin "is" the "keyboard" (by testing if it is some tty). See also this & that.
Yes, standard input (stdin) is input exepected from the keyboard. So, could be in the form of user input from a basic program or from a command line argument. Standard output (stdout) is the output of the code, usually to the terminal window. You could output your code almost anywhere, i.e. to a file, to a textbox, browser, but the standard is the stdout which is the terminal.
Hope that helps.
Normally, the standard input is the keyboard and the standard output the screen. However, you can redirect this in the command line using the "<" and ">" symbols. A command line like
dir /s > "Tree.txt"
will change the standard output for the dir command to be the specified file. So all output goes to that file. The called application or command itself doesn't normally even notice the difference.
stdin is file descriptor 0, you can get a file to stdin by:
cat file |yourprog
#or
yourprog <file
likewise for stdout (file descriptor 1)
yourprog | someotherprog #pipe your stdout to the stdin of another program
yourprog > somefile #save stdout to a file
yourprog >> somefile #append stdout to a file
and stderr (fd 2)
yourprog 2> errlogfile
if you have a program that takes a file but doesn't handle stdin, you can use the above formats by doing this (assuming -f if the input file argument)
myprog -f /dev/stdin
//and a horrible example of how not to read from stdin and write to stdout
char buf[4096];
while(write(1,buf,read(0,buf,4096)));
standard output (or stdout) refers to the standardized streams of data that are produced by command line programs (i.e., all-text mode programs) in Linux and other Unix-like operating systems.

Does every process have its stdin stdout stderr defined as Keyboard, Terminal etc?

Does every process have stdin, stdout and stderr associated to it to the Keyboard and Terminal?
I have a small program. I want to replace the keyboard input to a file called new.txt. How do I go about it?
FILE *file1
fopen("new.txt", "r")
close(0); // close the stdio
dup2(file1, 0);
Would this work? Now my stdio is redirected to the FILE?
No, not every process. But on operating systems that give you a command-line window to type in, a program started from that command line will have stdin connected to the keyboard, and stdout and stderr both going to the terminal.
If one program starts another, then often the second program's standard streams are connected to the first program in some way; for example, the first program may have an open descriptor through which it can send text and pretend that it's the "keyboard" for the second process. The details vary by operating system, of course.
In response to your question:
Would this work ?
No. dup2() takes two file descriptors (ints) while you're passing it a FILE * and an int. You can't mix file handles (FILE *s) and file descriptors (ints) like that.
You could use open instead of fopen to open your file as a file descriptor instead of a file handle, or you could use fileno to get the file descriptor from a file handle. Or you could use freopen to reopen the stdin file handle to a new file.
Note that file descriptors (ints) are part of POSIX operating systems and are only portable to other POSIX systems, while file handles (FILE *s) are part of the C standard and are portable everywhere. If you use file descriptors, you'll have to rewrite your code to make it work on Windows.

How to redirect the output of a c program to a file?

I am trying to redirect the output of a c program to file, even when it generates some errors because of problems with the input data. I can send the output but the error messages to a file.
Does somebody know how to do it?
From within C source code, you can redirect outputs using freopen():
General outputs:
freopen("myfile.txt", "w", stdout);
Errors:
freopen("myfile_err.txt", "w", stderr);
(This answer applies to bash shell, and similar flavors. You didn't specify your environment and this sort of question needs that detail.)
I assume you know about basic redirection with ">". To also capture STDERR in addition to STDOUT, use the following syntax:
command > file-name 2>&1
For some more background on standard streams and numbers:
http://en.wikipedia.org/wiki/Standard_streams#Standard_input_.28stdin.29
This depends on what you mean and what platform you are using. Very often you can accomplish this from the command line, which has been covered in another answer. If you use this method to accomplish this you should be aware that FILE * stderr is typically written immediately (unbuffered) while FILE * stdout may be buffered (usually line buffered) so you could end up with some of your error messages appearing to have been printed earlier than some other messages, but actually the other messages are just being printed late.
From within a C program you can also do something similar within the stdio system using freopen, which will effect the FILE *, so you could make fprintf(stderr, "fungus"); print to something besides what stderr normally would print to.
But if you want to know how to make a program redirect the actual file descriptors under a unix like system you need to learn about the dup and dup2 system calls. They allow you to duplicate a file descriptor.
int fd = open("some_file", O_WRONLY);
dup2(2,fd);
close(fd);
This code will make "some_file" the new stderr at the OS level. The dup2 call will close and replace file descriptor 2 (stderr, which is usually used by FILE * stderr but not necessarily if you call freopen(x,y,stderr) since that may make FILE *stderr use a different file descriptor).
This is how shell programs redirect input and output of programs. The open all of the files that the new program will need, fork, then the child uses dup2 to set up the files descriptors for the new program, then it closes any files that the new program won't need (usually just leaving 0, 1, and 2 open), and then uses one of the exec functions to become the program that the shell was told to run. (some of this isn't entirely accurate because some shells may rely on close on exe flags)
Using a simple linux command you can save the output into the file. here is a simple linux terminal command.
ls > file.txt
The output of this command will be stored into the file.
same as you can store the output of the program like this suppose, object file name is a, run the following command to save output in a file:
./a > file.txt

Resources