How to read a char* string by fread function? - c

We called a library to read text, this library API only accepts a FILE* pointer. It actually reads file text by fread() call internally.
But we also need to use this library to read text from a char* string rather than a FILE*.
Of course we can write the char* string into a temp file but we're not allowed to do this for some reasons...
How to do ? Thanks !!

Check out fmemopen
The fmemopen() function shall associate the buffer given by the buf argument with a stream.
#include <stdio.h>
static char buffer[] = "foobar";
int main (void)
{
FILE *stream;
stream = fmemopen (buffer, strlen (buffer), "r");
/* You got a FILE* pointer, you can call your function here :-) */
}

It can be done, but it's not easy and quite complicated.
You can create a shared-memory file handle with shm_open, this file handle can the be used by mmap to make it point to the memory area of the string, then use fdopen to create a FILE pointer from the file descriptor.
Note: This will only work on POSIX (e.g. Linux or Mac OSX) systems. Windows systems should have similar functionality, but it still won't be easy.
Edit It's probably something similar to this that happens behind the scenes in the fmemopen call referenced in the answer by Massimo Fazzolari.

On various unix systems, you can create a pipe/socket or similar file descriptors, and use fdopen() to open the file descriptor and get a FILE* pointer. Then feed the string into the pipe/socket.
I suggest you check you program/library design when you run into strange problems like this. Strange problems/requirements are strong indications of bad designs.

Hmm, short of writing your own device driver to communicate back with the process somehow, this is a tricky one. By that, I mean you could create a character device which would, when read from, communicate via some sort of IPC (shared memory, named pipes, or other things) back to the process.
But this is (1) nasty, (2) UNIX-specific (non-portable) and (3) a very bad idea :-)
Without such low-level tricks (or with non-portable extensions that can treat memory like file handles), this cannot be done - fread expects a FILE* and will read from a file handle, that's it, really.

I don't think this can be done. fread can read only from a file stream i.e either FILE * or stdout.

Related

What is stdin in C language?

I want to build my own scanf function. Basic idea is data from a memory address and save it to another memory address.
What is stdin? Is it a memory-address like 000ffaa?
If it is a memory-address what is it so I can build my own scanf function. Thanks!.
No, stdin is not "a memory address".
It's an I/O stream, basically an operating-system level abstraction that allows data to be read (or written, in the case of stdout).
You need to use the proper stream-oriented I/O functions to read from the stream.
Of course you can read from RAM too, so it's best to write your own function to require a function that reads a character, then you can adapt that function to either read from RAM or from stdin.
Something like:
int my_scanf(int (*getchar_callback)(void *state), void *state, const char *fmt, ...);
Is usually reasonable. The state pointer is some user-defined state that is required by the getchar_callback() function, and passed to it by my_scanf().
stdin is an "input stream", which is an abstract term for something that takes input from the user or from a file. It is an abstraction layer sitting on top of the actual file handling and I/O. The purpose of streams is mainly to make your code portable between different systems.
Reading/writing to memory is much more low-level and has nothing to do with streams as such. In order to use a stream in a meaningful way, you would have to know how a certain compiler implements the stream internally, which may not be public information. In some cases, like in Windows, streams are defined by the OS itself and can get accessed through API calls.
If you are looking to build your own scanf function, you would have to look into specific API functions for a specific OS, then build your own abstraction layer on top of those.
On Unix everything is a file
https://en.wikipedia.org/wiki/Everything_is_a_file
Or like they notice
Everything is a file descriptor
You can find on unix system /dev/stdin who is a symbolic link to /dev/fd/0 who is a Character special file

Equivalent of fgetc with Unix file descriptors

The fgetc(3) function takes a FILE * as its input stream. Must I reimplement character-at-a-time input with read(2), or is there a <unistd.h>-style equivalent taking an integer file descriptor instead?
No, there isn't such a thing, and please never do read(fd, &ch, sizeof(char)) (explanations below).
The function read(2) is usually implemented as a system call to the operating system kernel. Although the internal (and funky) details of such a thing shall not be discused here, the overall idea is that system calls are (usually) not something cheap.
It would be inefficient for both the userspace application and the kernel to do a system call just to get a single character from a file descriptor.
For instance, fgetc(3) usually ends up doing some buffering inside the structure of the FILE object. This means that the internal read(2) from fgetc(3) wouldn't just read a single character, but rather it'll try to get more for the sake of efficiency.
Anyway, it's not usually a good idea to mess up with such low-level stuff. You can get all the benefits of buffering (and of FILEs overall) by using fdopen(3) to create a FILE object from a file descriptor, as your question appears to imply that you have at hand just a raw file descriptor at the moment.
If you want to, you can open a file using open() -
int fh = open("abc.txt", O_RDONLY, S_IREAD); // there are different permissions you can provide (refer to link).
and then you can use fh in read() calls.

What is Opening a file in C?

In C when we open a file what happens?? As I know that the contents of the file is not loaded in the memory when we open a file. It just sets the file descriptor ? So what is this file descriptor then?? And if the contents of the file is not loaded in the memory then how a file is opened?
Typically, if you're opening a file with fopen or (on a POSIX system) open, the function, if successful, will "open the file" - it merely gives you a value (a FILE * or an int) to use in future calls to a read function.
Under the hood, the operating system might read some or all of the file in, it might not. You have to call some function to request data to be read anyways, and if it hasn't done it by the time you call fread/fgets/read/etc... then it will at that point.
A "file descriptor" typically refers to the integer returned by open in POSIX systems. It is used to identify an open file. If you get a value 3, somewhere, the operating system is keeping track that 3 refers to /home/user/dir/file.txt, or whatever. It's a short little value to indicate to the OS which file to read from. When you call open, and open say, foo.txt, the OS says, "ok, file open, calling it 3 from here on".
This question is not entirely related to the programming language. Although the library does have an impact on what happens when opening a file (using open or fopen, for example), the main behavior comes from the operating system.
Linux, and I assume other OSs perform read ahead in most cases. This means that the file is actually read from the physical storage even before you call read for the file. This is done as an optimization, reducing the time for the read when the file is actually read by the user. This behavior can be controlled partially by the programmer, using specific flag for the open functions. For example, the Win32 API CreateFile can specify FILE_FLAG_RANDOM_ACCESS or FILE_FLAG_SEQUENTIAL_SCAN to specify random access (in which case the file is not read ahead) or sequential access (in which case the OS will perform quite aggressive read ahead), respectively. Other OS APIs might give more or less control.
For the basic ANSI C API of open, read, write that use a file descriptor, the file descriptor is a simple integer that is passed onto the OS and signifies the file. In the OS itself this is most often translated to some structure that contains all the needed information for the file (name, path, seek offsets, size, read and write buffers, etc.). The OS will open the file - meaning find the specific file system entry (an inode under Linux) that correlates to the path you've given in the open method, creates the file structure and return an ID to the user - the file descriptor. From that point on the OS is free to read whatever data it seems fit, even if not requested by the user (reading more than was requested is often done, to at least work in the file system native size).
C has no primitives for file I/O, it all depends on what operating system
and what libraries you are using.
File descriptors are just abstracts. Everything is done on the operating system.
If the program uses fopen() then a buffering package will use an implementation-specific system call to get a file descriptor and it will store it in a FILE structure.
The system call (at least on Unix, Linux, and the Mac) will look around on (usually) a disk-based filesystem to find the file. It creates data structures in the kernel memory that collects the information needed to read or write the file.
It also creates a table for each process that links to the other kernel data structures necessary to access the file. The index into this table is a (usually) small number. This is the file descriptor that is returned from the system call to the user process, and then stored in the FILE struct.
As already mentioned it is OS functionality.
But for C file I/O most probably you need info on fopen function.
If you will check description for that function, it says :
Description:
Opens a stream.
fopen opens the file named by
filename and associates a stream with
it. fopen returns a pointer to be used
to identify the stream in subsequent
operations.
So on successful completion fopen just returns a pointer to the newly opened stream. And it returns NULL in case of any error.
When you open the file then the file pointer gets the base address(starting address)of that file.Then you use different functions to work on the file.
EDIT:
Thanks to Chris,here is the structure which is named FILE
typedef struct {
int level; /* fill/empty level of buffer */
unsigned flags; /* File status flags */
char fd; /* File descriptor */
unsigned char hold; /* Ungetc char if no buffer */
int bsize; /* Buffer size */
unsigned char *buffer; /* Data transfer buffer */
unsigned char *curp; /* Current active pointer */
unsigned istemp; /* Temporary file indicator */
short token; /* Used for validity checking */
} FILE;

C fopen vs open

Is there any reason (other than syntactic ones) that you'd want to use
FILE *fdopen(int fd, const char *mode);
or
FILE *fopen(const char *path, const char *mode);
instead of
int open(const char *pathname, int flags, mode_t mode);
when using C in a Linux environment?
First, there is no particularly good reason to use fdopen if fopen is an option and open is the other possible choice. You shouldn't have used open to open the file in the first place if you want a FILE *. So including fdopen in that list is incorrect and confusing because it isn't very much like the others. I will now proceed to ignore it because the important distinction here is between a C standard FILE * and an OS-specific file descriptor.
There are four main reasons to use fopen instead of open.
fopen provides you with buffering IO that may turn out to be a lot faster than what you're doing with open.
fopen does line ending translation if the file is not opened in binary mode, which can be very helpful if your program is ever ported to a non-Unix environment (though the world appears to be converging on LF-only (except IETF text-based networking protocols like SMTP and HTTP and such)).
A FILE * gives you the ability to use fscanf and other stdio functions.
Your code may someday need to be ported to some other platform that only supports ANSI C and does not support the open function.
In my opinion the line ending translation more often gets in your way than helps you, and the parsing of fscanf is so weak that you inevitably end up tossing it out in favor of something more useful.
And most platforms that support C have an open function.
That leaves the buffering question. In places where you are mainly reading or writing a file sequentially, the buffering support is really helpful and a big speed improvement. But it can lead to some interesting problems in which data does not end up in the file when you expect it to be there. You have to remember to fclose or fflush at the appropriate times.
If you're doing seeks (aka fsetpos or fseek the second of which is slightly trickier to use in a standards compliant way), the usefulness of buffering quickly goes down.
Of course, my bias is that I tend to work with sockets a whole lot, and there the fact that you really want to be doing non-blocking IO (which FILE * totally fails to support in any reasonable way) with no buffering at all and often have complex parsing requirements really color my perceptions.
open() is a low-level os call. fdopen() converts an os-level file descriptor to the higher-level FILE-abstraction of the C language. fopen() calls open() in the background and gives you a FILE-pointer directly.
There are several advantages to using FILE-objects rather raw file descriptors, which includes greater ease of usage but also other technical advantages such as built-in buffering. Especially the buffering generally results in a sizeable performance advantage.
fopen vs open in C
1) fopen is a library function while open is a system call.
2) fopen provides buffered IO which is faster compare to open which is non buffered.
3) fopen is portable while open not portable (open is environment specific).
4) fopen returns a pointer to a FILE structure(FILE *); open returns an integer that identifies the file.
5) A FILE * gives you the ability to use fscanf and other stdio functions.
Unless you're part of the 0.1% of applications where using open is an actual performance benefit, there really is no good reason not to use fopen. As far as fdopen is concerned, if you aren't playing with file descriptors, you don't need that call.
Stick with fopen and its family of methods (fwrite, fread, fprintf, et al) and you'll be very satisfied. Just as importantly, other programmers will be satisfied with your code.
If you have a FILE *, you can use functions like fscanf, fprintf and fgets etc. If you have just the file descriptor, you have limited (but likely faster) input and output routines read, write etc.
open() is a system call and specific to Unix-based systems and it returns a file descriptor. You can write to a file descriptor using write() which is another system call.
fopen() is an ANSI C function call which returns a file pointer and it is portable to other OSes. We can write to a file pointer using fprintf.
In Unix:
You can get a file pointer from the file descriptor using:
fP = fdopen(fD, "a");
You can get a file descriptor from the file pointer using:
fD = fileno (fP);
Using open, read, write means you have to worry about signal interaptions.
If the call was interrupted by a signal handler the functions will return -1
and set errno to EINTR.
So the proper way to close a file would be
while (retval = close(fd), retval == -1 && ernno == EINTR) ;
I changed to open() from fopen() for my application, because fopen was causing double reads every time I ran fopen fgetc . Double reads were disruptive of what I was trying to accomplish. open() just seems to do what you ask of it.
open() will be called at the end of each of the fopen() family functions. open() is a system call and fopen() are provided by libraries as a wrapper functions for user easy of use
Depends also on what flags are required to open. With respect to usage for writing and reading (and portability) f* should be used, as argued above.
But if basically want to specify more than standard flags (like rw and append flags), you will have to use a platform specific API (like POSIX open) or a library that abstracts these details. The C-standard does not have any such flags.
For example you might want to open a file, only if it exits. If you don't specify the create flag the file must exist. If you add exclusive to create, it will only create the file if it does not exist. There are many more.
For example on Linux systems there is a LED interface exposed through sysfs. It exposes the brightness of the led through a file. Writing or reading a number as a string ranging from 0-255. Of course you don't want to create that file and only write to it if it exists. The cool thing now: Use fdopen to read/write this file using the standard calls.
opening a file using fopen
before we can read(or write) information from (to) a file on a disk we must open the file. to open the file we have called the function fopen.
1.firstly it searches on the disk the file to be opened.
2.then it loads the file from the disk into a place in memory called buffer.
3.it sets up a character pointer that points to the first character of the buffer.
this the way of behaviour of fopen function
there are some causes while buffering process,it may timedout. so while comparing fopen(high level i/o) to open (low level i/o) system call , and it is a faster more appropriate than fopen.

How can you flush a write using a file descriptor?

It turns out this whole misunderstanding of the open() versus fopen() stems from a buggy I2C driver in the Linux 2.6.14 kernel on an ARM. Backporting a working bit bashed driver solved the root cause of the problem I was trying to address here.
I'm trying to figure out an issue with a serial device driver in Linux (I2C). It appears that by adding timed OS pauses (sleeps) between writes and reads on the device things work ... (much) better.
Aside: The nature of I2C is that each byte read or written by the master is acknowledged by the device on the other end of the wire (slave) - the pauses improving things encourage me to think of the driver as working asynchronously - something that I can't reconcile with how the bus works. Anyhoo ...
I'd either like to flush the write to be sure (rather than using fixed duration pause), or somehow test that the write/read transaction has completed in an multi-threaded friendly way.
The trouble with using fflush(fd); is that it requires 'fd' to be stream pointer (not a file descriptor) i.e.
FILE * fd = fopen("filename","r+");
... // do read and writes
fflush(fd);
My problem is that I require the use of the ioctl(), which doesn't use a stream pointer. i.e.
int fd = open("filename",O_RDWR);
ioctl(fd,...);
Suggestions?
I think what you are looking for may be
int fsync(int fd);
or
int fdatasync(int fd);
fsync will flush the file from kernel buffer to the disk. fdatasync will also do except for the meta data.
You have two choices:
Use fileno() to obtain the file descriptor associated with the stdio stream pointer
Don't use <stdio.h> at all, that way you don't need to worry about flush either - all writes will go to the device immediately, and for character devices the write() call won't even return until the lower-level IO has completed (in theory).
For device-level IO I'd say it's pretty unusual to use stdio. I'd strongly recommend using the lower-level open(), read() and write() functions instead (based on your later reply):
int fd = open("/dev/i2c", O_RDWR);
ioctl(fd, IOCTL_COMMAND, args);
write(fd, buf, length);
fflush() only flushes the buffering added by the stdio fopen() layer, as managed by the FILE * object. The underlying file itself, as seen by the kernel, is not buffered at this level. This means that writes that bypass the FILE * layer, using fileno() and a raw write(), are also not buffered in a way that fflush() would flush.
As others have pointed out, try not mixing the two. If you need to use "raw" I/O functions such as ioctl(), then open() the file yourself directly, without using fopen<() and friends from stdio.
Have you tried disabling buffering?
setvbuf(fd, NULL, _IONBF, 0);
It sounds like what you are looking for is the fsync() function (or fdatasync()?), or you could use the O_SYNC flag in your open() call.
If you want to go the other way round (associate FILE* with existing file descriptor), use fdopen() :
FDOPEN(P)
NAME
fdopen - associate a stream with a file descriptor
SYNOPSIS
#include <stdio.h>
FILE *fdopen(int fildes, const char *mode);

Resources