get address of Linux file descriptor - c

There is fileno to get the file descriptor of a FILE*.
How do you get the address for the FILE* given a file descriptor number, e.g. as returned from pipe?
fileno
pipe

You want to use the fdopen() function:
FILE * file = fdopen(fd, "r");
so you could use it in combination with pipe like this:
FILE * file = fdopen(pipe(..,..), "r");

Related

How read remember the last offset of file?

How read function know the next position to read from a file.
or How can I manage to made a function that can remember last offset of file even after open another file a changing it's file descriptor.
Is there is a way to know that a file descriptor is already opened and pointed to a file?
like this:
int main()
{
int fd;
char *file;
file = (char *)malloc(sizeof(char) * 32);
fd = open("file.txt", O_RDONLY);
read_file(fd, *file); /* reading the first line from file.txt */
fd = open("file1.txt", O_RDONLY);
read_file(fd, *file); /* reading the first line from file1.txt */
fd = open("file.txt", O_RDONLY);
read_file(fd, *file); /* Now it should read the second line from file file.txt, how can I manage to do that*/
close(fd);
return (0);
}
The current location in the file is maintained by the kernel I think, the file descriptor serves as the key to all the information associated with the open file.
If you need to open and read from two files at the same time, they should of course not share the file descriptor. Just use two, one per file.
const int fd1 = open("file.txt", O_RDONLY);
const int fd2 = open("file1.txt", O_RDONLY);
The treatment of char *file in your code makes no sense, but at this point you can mix accesses to fd1 and fd2.
Remember to close the files when you're done:
close(fd2);
close(fd1);
In real code you would also check that the open-calls succeeded, before trying to do I/O from the file(s), of course.
Is there a way to know that a file descriptor is already opened and
pointed to a file?
If you can lseek(fd, 0, SEEK_CUR) successfully, that means that fd is opened and seekable (so probably a file, but remember that "file" includes directories and device files as well as regular files).
If it returns (off_t)-1 and errno==EBADF then the descriptor is not open; if returns (off_t)-1 and errno==ESPIPE, then it's a pipe, socket, or FIFO.

Selection output file using dup()

So I'm trying to redirect standard output to a file using dup().
int save_fd;
save_fd=dup(1); //saves the current stdout
close(1); //closes stdout
dup2(file.txt, 1);//redirect output to file.txt
//output goes to file.txt
dup2(save_fd, 1); restore stdout
close(1);
I know I can open a file using fopen. Since dup2 takes int, how do I specify the file descriptor for file.txt?
Use open which returns an fd instead of fopen.
Well, you have two possibilities to get a file descriptor:
open()
fopen() and then call fileno() on the opened stream
So, in the case of open() the return value in case of success is the file descriptor you're looking for:
int fd = open("some_path", ...);
while in the case you want to use fopen(), you can still retrieve the file descriptor associated with the open stream but you need to call the function fileno():
FILE *stream = fopen(some_file, "w");
int fd = fileno(stream);

Duplicating file pointers?

Just a quick question: Is there a way to duplicate a file pointer (those returned by fopen()), similar to how dup() duplicates a file handlers returned by functions like open()?
Basically, I want to be able to do something like this:
FILE *fp = fopen("some_file", "r");
FILE *fp2 = /* do something to duplicate the file pointer */;
fclose(fp); // fp2 is still open
/* do something with fp2 */
fclose(fp2);
FILE *fp2 = fdopen (dup (fileno (fp)), "r");
You could use fileno to get a descriptor for a FILE*, dup that, and then use fdopen to get a new FILE* from the new descriptor.
I opened twice the same file and assigned two pointers and in the end closed both separately. In my case I had to show the content in a text window using one pointer and process the data in file using the other pointer.
e.g.
//define global variables
FILE *fp1 = fopen("some_file", "r");
//fp1 used in functioncall to display textbuffer
fclose(fp1);
//fp2 used in functioncall to process data
fclose(fp2);

C : how can I change from file descriptor to FILE struct and vice versa?

Is there any way to change an int file descriptor to a FILE struct pointer or/and change FILE* to a file descriptor in C?
The function fdopen() returns a new (FILE *) associated with an open file descriptor.
The function fileno() returns the file descriptor associated with an open FILE *.
Use "fileno()" for FILE->int.
Use "fdopen()" for int->FILE.

How to get a FILE* stream from a file descriptor?

We can get a file descriptor from a FILE* stream by using the fileno() function. Is there a function for getting a FILE* stream from the file descriptor without reopening the file?
FILE *fdopen(int fd, const char *mode);
See fdopen(3), but it should be on the same page as fopen(3):
The fdopen() function associates a stream with the existing
file descriptor, fd. The mode of the stream (one of the values
"r", "r+", "w", "w+", "a", "a+") must be compatible
with the mode of the file descriptor. The file position indicator
of the new stream is set to that belonging to fd, and the error and
end-of-file indicators are cleared. Modes "w" or "w+" do not
cause truncation of the file. The file descriptor is not dup’ed,
and will be closed when the stream created by fdopen() is
closed. The result of applying fdopen() to a shared memory object
is undefined.

Resources