In usual case open()
return the new file descriptor, or -1 if an error occurred and in that case, errno
is set appropriately.
I am not understanding why this mechanism of errno
is used here? whats the purpose of here? why just we can not map all error with some negative return no?
like
fd = open("/dev/tty0", O_RDWR | O_SYNC);
if(fd == -1)
printf("this is EACCES error");
else if (fd == -2)
printf("this is EPERM error");
Is there any benifit of errno
mechanism.? if yes then i would like to know/understand then in other things i can also use this mechanism.
The main reason for using errno is to give more information about the error condition. This is especially useful in situations where most (or even all) possible return values of a function are actually valid return values.
The key difference between the fopen() and the open() function in the Linux operating system is that the open() function is a low-level call, where the fopen() when called simply calls the open() function in the background and it returns a Filepointer directly.
If O_EXCL and O_CREAT are set, and path names a symbolic link, open() shall fail and set errno to [EEXIST], regardless of the contents of the symbolic link. If O_EXCL is set and O_CREAT is not set, the result is undefined.
The normal return value from open is a non-negative integer file descriptor. In the case of an error, a value of -1 is returned instead. In addition to the usual file name errors (see File Name Errors), the following errno error conditions are defined for this function: EACCES.
Since fopen
returns a FILE*
you can't expect it to return an error code in that pointer: the only "special" value for pointers is 0
.
As you observe, for open
this restriction doesn't hold. In fact systems as linux do exactly what you propose in their lower levels. The system call under the hood returns the negative error code if things go wrong. That (negated) code is then plug into errno
by a shallow user space wrapper which then returns the -1
to indicate the error to the application.
The reason that this is done so is purely historical. In good old times there was no threading and errno
was still just a simple global variable. At that time the chosen strategy incurred not much overhead and probably seemed an acceptable way to communicate between OS and application. Since such interfaces basically can't be changed without breaking a lot of code, we will be stuck with errno
as a pseudo variable that is thread local.
This is not ideal, but the overhead is not as bad as it sounds, since these are clearly error indications that should occur only exceptionally.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With