In the C standard library, is there a similar function to `fcntl()`? - c

In Linux API, fcntl() can be very useful to get or set file descriptor flags, file status flags, and other properties.
In the C standard library, is there a similar function to fcntl() which can get or set the properties of a FILE object, and its underlying file descriptor flags, file status flags, and other properties?

No. That's because, in the ISO C standard, FILE-based processing is the lowest level API specified. It's not necessary that file descriptors (and the other things you mention) even exist.
How it's handled "under the covers" is totally dependent on the implementation, so you have to revert to implemntation-specific stuff if you want access to its information.
The POSIX standard actually mandates the underlying mechanisms and many C implementations also support POSIX but it's by no means required by ISO C, the one true C standard :-)

If you have fcntl in the first place, then you should also have two other functions which let you go back and forth between bare file descriptors and FILE objects: fileno and fdopen. None of these functions are specified by ISO C (hence they are not part of the standard C library) but they are all included in the POSIX standard (which defines most of what it means to be a "Unix"), so if you have one of them you can expect to have all three. The header fcntl.h is also part of that standard.

Related

Is stdio.h a library?

The C Programming Language calls stdio.h a library. However, I am being told that it's a header file only meant for the compiler, which is true, and therefore it's not a library.
Other programming sites on the Internet call it a library. Is the definition of library different now?
Some C programs start with #include <stdio.h> because the C language does not include file manipulation functions.
Update with quote from The C Programming Language by Brian Kernighan and Dennis Ritchie, Second Edition, page 3 (Introduction):
A second significant contribution of the standard [ refers to "the ANSI standard, or "ANSI C", completed in 1988] is the definition of a library of accompany C. It specifies functions for accessing the operating system (for instance to read and write files), formatted input and output, memory allocation, string manipulation, and the like. ... Programs that use this library to interact with a host system are assured of compatible behavior. Most of the library is clostly modeled on the "standard I/O library" of the UNIX system. This library was described in the first edition ...
It would seem a logical conclusion that the definition of library has evolved/changed/updated...
No, stdio.h is not a library, it's a header file. A common mistake when approaching C is to call every header file a library, that's just wrong.
The C standard library is a collection of functions, which are declared in header files, and stdio.h is one of them. The name stands for "Standard Input Output", so in that file you can find all the declarations of functions that deal with input, output and files. You can find a list of the header files included in the C standard library here.
A library is a compiled binary file (or in general, a collection of binary files), which can be linked when compiling a program to take advantage of the functions made available by the library (i.e. exported). Header files are then used to identify the names and the signatures of those functions, so that the compiler knows how to call them.
Commonly, for small libraries, a single header file is enough, so that's easy for beginners to confuse an header file with the library itself. The C standard library however is very complex and has a lot of functions, so they are declared in different header files.
C programs start with #include <stdio.h> because the C language does not include file manipulation functions.
Yes, that's right. The C specification only concerns the language itself (syntax, types, etc), and does not define any "standard" function.
My book, "The C Programming Language" calls stdio.h a library. Now, I am being told that it's a "header file" only meant for the compiler, which is true, and therefore it's not a library.
I have a copy of that book (the first edition, and also the ANSI edition), and I don't remember there being any confusion about the difference between a header file and a library. Can you point us to where you're looking? On page 152, for example, I see:
Each source file that refers to an input/output library function must
contain the line
#include <stdio.h>
And that's true enough... it's not saying that stdio.h is a library, but rather that you have to include the header file if you want to use the library. Similarly on page 176:
The data structure that describes a file is contained in ,
which must be included (by #include) in any source file that uses
routines from the standard input/output library. It is also included
by functions in that library...
In this paragraph that library refers to "the standard input/output library," not stdio.h itself. I could see how someone might misread that, but in context the book really isn't calling stdio.h a library here.
If you can point us to the particular passage that you're looking at, perhaps we can explain better.
Update:
The passage you quote from the book is from the introduction to the second edition, and it's talking about the history of the language up to that point (the second edition came out in 1988). In particular, the paragraph is talking about the C standard library:
A second significant contribution of the standard is the definition of a library to accompany C...
It looks like the part that inspired your question is this:
...Most of the library is closely modeled on the "standard 1/0 library" of the UNIX system. This library was described in the first edition, and has been widely used on other systems as well...
In all cases, when the text says library it really means that, not header file. Every C library has one or more associated header files that provide the interface to the associated library; without the header(s), you (and your compiler) wouldn't know how to access the functions that are defined in the library. For example, the fopen() function is declared in the stdio.h with a function prototype:
FILE *
fopen(const char * restrict path, const char * restrict mode);
Once you have the declaration of fopen() available, the compiler knows how to generate instructions to call that function, and the linker will connect your code to the actual function definition in the library file itself. So when the text says standard I/O library, it's really talking about the library, and the header file of the same name is just an ancillary file that lets you access the library.
It would seem a logical conclusion that the definition of library has evolved/changed/updated...
No, that's not what's happened; header files and libraries are and have always been distinct but related things, and the meaning really hasn't changed since the book was written, at least with respect to C.

What is included in C Standard library?

I will give an example from The GNU C Library documentation:
13.1 Opening and Closing Files
This section describes the primitives for opening and closing files
using file descriptors. The open and creat functions are declared in
the header file fcntl.h, while close is declared in unistd.h.
My question is:
Can unistd.h and fcntl.h be considered as Standard C? As far as I know, they should be part of the Posix standard?
Can we say C Standard Library = Posix functions + C API? I am confused because Wikipedia page for C Standard Library does not include unistd.h but the GNU C Library documentation includes it?
No, unistd.h, fcntl.h, etc, are not standard C.
In general, standard C doesn't include functions that deal with low level file manipulation. For example, fopen, fread, and fwrite are part of standard C library. While POSIX open, read, write functions are not standard C.
As far as I can see, in C11 standard, there is no unistd.h and fcntl.h. So, strictly speaking, they are not part of the C standard.
When it comes to the implementation part, the GNU C library (glibc) is one of them. From the wiki page
glibc provides the functionality required by the Single UNIX Specification, POSIX (1c, 1d, and 1j) and some of the functionality required by ISO C11, ISO C99, Berkeley Unix (BSD) interfaces, the System V Interface Definition (SVID) and the X/Open Portability Guide (XPG), Issue 4.2, with all extensions common to XSI (X/Open System Interface) compliant systems along with all X/Open UNIX extensions.
In addition, glibc also provides extensions that have been deemed useful or necessary while developing GNU.
So, as a part of the POSIX standard, they are available in glibc.
Reference: Check the C11 standard draft version here.

Which platforms implement flock?

I'm looking at the Ruby MRI code for File#flock. The documentation states that it's "Not available on all platforms.", but doesn't state which. If I should venture a guess, old FAT file systems might not have locking, but I would like to not be guessing.
Digging a bit into the implementation takes me to rb_file_flock(VALUE obj, VALUE operation), which in turn calls rb_thread_flock(void *data). This simply wraps a call to flock from sys/file.h. However, it seems that this implementation may or may not be available:
#ifdef HAVE_SYS_FILE_H
# include <sys/file.h>
#else
int flock(int, int);
#endif
However, I can't figure out where HAVE_SYS_FILE_H is defined (In a build-script perhaps?), so I don't know which platforms would enable it.
So, for my question(s): Which platforms could I expect HAVE_SYS_FILE_H to be defined for. And provided that it is defined and thus sys/file.h available, can I expect file locking to work?
flock is a BSD and Linux extension function:
CONFORMING TO
4.4BSD (the flock() call first appeared in 4.2BSD). A version of flock(), possibly implemented in terms of fcntl(2), appears on most UNIX systems.
Unix specification does require advisory file locking to be implemented in terms of fcntl(F_SETLK):
Record locking shall be supported for regular files, and may be supported for other files.

open and fopen function [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
C fopen vs open
What is the difference between open() and fopen() in C language?
One is part of the standard c library (fopen) so you can expect it to be present on all hosted c compiler setups. This function returns a FILE* which can be operated on by the functions in <stdio.h>.
The other (open) is a system call/function not specified by the c standard (however, i believe it is part of the POSIX standard) and therefore only guaranteed to exist on select platforms which claim to support it. This returns an int which represents a file, this can be operated on using read/write and other similar functions.
open() is a standardised system call provided by a POSIX compliant operating system (most POSIX-like operating systems also have the open() system call). fopen() is a C library function provided by the C implementation and/or runtime library.
fopen() allows for buffered and/or formatted input/output, whereas open() is generally used for more straightforward IO. It is possible for the fopen() function to be implemented using the open() system call.
As others said open() is a system call through POSIX standard, mostly supported by UNIX family of operating systems. It returns 'int' indicating the file descriptor being opened.
While on the other hand fopen() is provided by C-library and it returns a FILE* pointing to the file being opened.

No O_BINARY and O_TEXT flags in Linux?

When using system-level IO in Linux, I noticed that the compiler recognized the O_RDONLY and O_RDWR flags, but it had no clue whatsoever as to the meaning of the O_BINARY and O_TEXT flags.
Is this a Linux thing?
Linux, and just about every flavor of Unix for that matter, doesn't differentiate between binary and text files. Thus, there are no standard constants with that name. You can manually define the constants to be zero in Linux if you want to include them in your code for portability purposes.
http://unix.derkeiler.com/Newsgroups/comp.unix.programmer/2007-03/msg00147.html
It's a *nix thing. *nix operating systems don't do automatic linefeed conversion for I/O on "text" files so O_TEXT and O_BINARY flags wouldn't make sense.
At the level of C language and its standard library, there's no such thing as O_BINARY and O_TEXT flags. The binary or text mode is selected by adding the b specifier of the mode parameter of fopen function. The specifier itself is, of course, supported by all C implementations, but on POSIX platforms this specifier has no effect: per POSIX specification the text mode is the same as the binary mode.
Not suprisingly, if you dig deeper into the level of non-standard platform-specific Unix I/O functions, you'll discover that they have no knowledge of that text/binary distinction whatsoever.
Windows uses \r\n for line endings, Linux (and other Unix-alikes) use just \n. In Windows, reading O_BINARY gives you the raw data, possibly odd line endings and all, while O_TEXT normalises the line endings, so your C code only sees a single character.
Under Linux et al, there's no point distinguishing between text and binary, because the data only has a single character anyway, so the flags are unnecessary.
There isn't a difference at the OS level between binary and text file under Unix. Text file have just a restricted content. That's also true for Windows, but the conventions used by C for the end of lines are the same as the one used by Unix, while Windows use CR/LF pair (and an explicit end of file marker in some contexts, but the handling of that was not consistent even in the system programs last time I checked), so a mapping is needed to respect the conventions mandated by C.

Resources