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

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.

Related

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);

read file using file descriptor

I need to read a file opened like this:
int outfile = open(*fileName, "w");
using the file descriptor, I'm doing that like this:
char txt[50];
int bytes;
bytes = read(outfile,txt, 50);
But I'm getting segmentation fault and the application abort, any ideas?
Note the second argument to open. It's "w" this seems like it should indicate that you're opening the file for writing. However, my man pages for open indicates that the second argument should be one of: O_RDONLY, O_WRONLY, or O_RDWR. (fopen uses strings like "w", "w+", "r", ... but that's fopen not open). You may be getting lucky that the value of "w" as an int sets you up for writing but you really want to check your return values and probably want to use
open(*filename, O_RDWR);
to set up the mode for reading and writing.

get address of Linux file descriptor

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");

C - fwrite() not outputting to file

Never used fwrite(), so I'm not sure exactly what I'm doing wrong. I'm just testing it now and all I want to do is try to write a single char out to a file until it reaches the end. The file I'm writing to is one I downloaded from my teacher's website. When I check the properties of it, the type is only listed as "file". It's supposed to just be an empty 2MB file for us to write our code to (file system lab if anyone's wondering). Here's my code:
#include <stdio.h>
#include <string.h>
int main()
{
char c;
FILE *fp;
char testing[2] = {'c'};
fp = fopen("Drive2MB", "rw");
fseek(fp, 0, SEEK_SET); //make sure pointers at beginning of file
while((c=fgetc(fp))!=EOF)
{
fwrite(testing, 1, sizeof(testing), fp);
fseek(fp, 1, SEEK_CUR); //increment pointer 1 byte
}
fclose(fp);
}
When I run this, an error message pops up saying "Debug Assertion Failed!...Expression:("Invalid file open mode",0) and prints "The program '[3896] filesystem.exe: Native' has exited with code 3 (0x3)."
You have opened the file for reading (that's what the r stands for in fopen("Drive2MB", "r");). You may not write to a file opened for reading.
You're opening it in read only mode
Use r+ for the fopen
fp = fopen("Drive2MB", "r")
your openning your file in read only
try
fp = fopen("Drive2MB", "r+");
You've opened the file for reading with the "r" part of fopen. To write to the file, you can open it in read/write mode or write mode.
// Read/write mode
fp = fopen("Drive2MB", "r+");
// Write only mode
fp = fopen("Drive2MB", "w");
I never like to use "rw" personally. When you open a file, it really should have one reason to be opened. You also do not need to call fseek to move to the start of the file and you do not need to use fseek to advance the file pointer. fopen will automatically open it to the start of the file and fwrite will automatically advance the pointer. fseek should only be used if you are "seek"ing inside of the file to get to a specific point.
In the case you've given, you would only need write ("w") mode since you are not ever reading from the file.
Use fopen r+ or w+ to open the file.
Use fflush to flush data to disk after fwrite is complete.
Use ferror to check if there is any problem with the file stream after fwrite is complete.
Check whether the disk has enough free space.
I solved the problem with 3, 4.

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.

Resources