Open() Function in C Language
Knowledge of the open, read, and write functions is essential because we always need them to store or dispose of the information that is stored in files. The C language has two basic functions which you can use to open the files, using the open() and fopen() functions, each with different calling methods.
In this Linux Hint article, you will learn how to use the open() function. We will explain everything about this function, its syntax, the method call, the input and output arguments, the type of data that it accepts in each case, and how to declare it properly.
Then, we’ll apply what we learned by implementing the use of this function in practical examples that we prepared for you with code snippets and images that show the use of the open() function in the C language.
In order for you to have a comprehensive knowledge, we add a special section that describes all the errors that can occur when using this function, as well as their detection and identification, so that in case they occur, you have the necessary techniques for a quick solution.
Syntax of the Open() Function in C Language
Description of the Open() Function in C Language
The open() function opens a file for reading or writing. This function opens the file that is specified in the pathname input argument. This input must specify the absolute or relative path and the name of the file in string format or a pointer to it.
The flags input argument specifies the attributes that the file must have. The following is a list of the flags that this input argument accepts, and a brief description of the attribute that each one sets:
Flag | Description |
O_RDONLY | Open file for reading only. |
O_WRONLY | Open file for writing only. |
O_RDWR | Open file for reading and writing. |
O_CREAT | Creates a file in the path and name specified in pathname argument. |
O_ APPEND | Opens the file and places the cursor at the end of the contents. |
O_ASYNC | Enable input and output control by signal. |
O_CLOEXEC | Enable close-on-exec mode on the open file. |
O_NONBLOCK | Disables blocking of the file opened. |
O_TMPFILE | Create an unnamed temporary file at the specified path. |
In cases where more than one flag is used, a logical “OR” operation must be performed between them. This can be done within the input argument flags in the same line of code as the function call.
The attributes and modes can be changed or consulted once the file is opened with the fcntl() function.
The open() function returns an integer which contains the descriptor of the opened file. This descriptor is used as an input argument for file processing functions like read(), write(), etc., to refer to the file.
This function is defined in the “unistd.h” header. The flags that define the attributes and mode to open the file are defined in “fcntl.h”. To use the open() function, you must include these headers in your code as follows:
How to Open a File Using the Open() Function in C Language
In this example, we will use the open() function to open a file in read and write mode. In this case, it is a previously created file called “example.txt” which is stored in “Documents”.
Step 1: The first step is to include the required headers and declare that it exits empty and return in the main() function.
Step 2: The next step is to declare the variables that serve as input and output arguments to the open() function. As output argument, we declare the “fd” integer which is the file descriptor. As input argument, we declare the buffer character array which contains the string with the path and name of the file to be opened.
We also declare an array of 512 characters called “text” where we store the text that we want to write to the file which, in this case, is the first paragraph of this article.
Step 3: Once the variables are declared, we call the open() function and pass the “fd” integer as the output argument, the string path as the first input argument, and the O_WRONLY flag as the second argument.
Step 4: When open() returns from the call, it returns the descriptor of the file which is opened in “fd”. Then, we write with the write() function, passing the “fd” descriptor as the first input argument, the string text as the second input argument, and finally the size of the text which is obtained with the strlen() function. After the write operation, we close the file with the close() function.
Here is the complete code for this example:
//Step 2
intfd ;
char buffer [ ] = «Documents/example.txt» ;
char text [ 512 ] = «Knowledge of the various open, read, and write functions is essential because we will always need them to store or dispose of information stored in files.
The C language has two basic functions you can use to open files, open() and fopen(), each with different calling methods.» ;
//Step 3
fd = open ( buffer , O_WRONLY ) ;
The following figure shows the compilation and execution of this code along with the file that we just wrote. As we can see, the open() function opens the file correctly. We then use the write() function to write the contents of the text. In this case, it contains the first paragraph of this article:
Errors that Can Occur When Using the Open() Function: How to Detect and Identify Them
Using the open() function can lead to various errors. If this is the case, it returns a result that is equal to -1.
The easiest way to determine if an error has occurred is to use an “if” condition where the condition is the -1 value which is returned in “fd”. Now, let us look at how you can use this method to determine if an error has occurred:
fd = open ( «path/filename» , flags ) ;
printf ( «An error occurred while trying to open file.» ) ;
If the open() function returns with an error, it goes to the “if” statement and prints the message, “An error occurred while trying to open file“.
When open() returns a result that is equal to -1, it automatically stores a numeric code in the errno global variable which is defined in the “errno.h” header. This numeric code can be used to identify the error that occurred.
The following is an excerpt of the errors that the open() function can generate, along with a brief description of each error and the associated integer value:
Definition | Value in errno | Error |
EPERM | 1 | Operation not permitted |
ENOENT | 2 | No such file or directory |
EINTR | 4 | Interrupted system call |
ENXIO | 6 | No such device or address |
ENOMEM | 12 | Out of memory |
EACCES | 13 | Permission denied |
EFAULT | 14 | Bad address |
EBUSY | 16 | Device or resource busy |
EEXIST | 17 | File exists |
ENODEV | 19 | No such device |
ENOTDIR | 20 | Not a directory |
EISDIR | 21 | Is a directory |
EINVAL | 22 | Invalid argument |
EFILE | 23 | File table overflow |
EMFILE | 24 | Too many open files |
ETXTBSY | 26 | Text file busy |
ENOSPC | 28 | No space left on device |
EROFS | 30 | Read-only file system |
ENAMETOOLONG | 36 | File name too long |
ELOOP | 40 | Too many symbolic links encountered |
EOVERFLOW | 75 | Value too large for defined data type |
EDQUOT | 122 | Quota exceeded |
The easiest way to identify an error is to open a switch where the errno variable is the jump condition and each case is an error definition.
Next, consider an example where we open a file that does not exist, resulting in an error. To detect an error, we use the “if” condition that we saw in the previous snippet. To identify it, we open a switch with the three most common errors that this function can produce:
void main ( )
intfd ;
char buffer [ 1024 ] ;
fd = open ( «Documents/No existe.txt» , O_APPEND
case ENOENT : {
printf ( «No such file/directory. Error:%i \n » , errno ) ;
break ; }
case ENOTDIR : {
printf ( «Not a directory. Error: %i \n » , errno ) ;
break ; }
}
}
}
The following image shows the compilation and execution of this code. In it, we see how the generated error is detected in the “if” condition and how the errors are identified in the switch conditional to display the message and specific value:
Conclusion
In this Linux Hint article, we explained how to use the open() function to open the files.
We showed you the syntax of this function and the theoretical description of how it works, the call method, the input arguments, and the data type that is used in each case.
We then implemented the use of the open() function in a practical example using code snippets and images. We showed you how to declare the required variables, call this function to open a file, and write to it.
We also included a section where we list all the errors that this function can generate. We showed you the techniques to detect and classify them so that you have the necessary means to quickly fix them when they occur.
About the author
Julio Cesar
Julio Cesar is a 42 years old programmer with 8 years of experience in embedded systems development, 6 years developing firmware for user interfaces in C and C++. Additionally he has 2 years of experience developing scripts for network devices and 3 years as developer of high frequency PCB (Printed Circuit Board).
POSIX Open Function in C
Although there are a lot of libraries in C, the POSIX library is very well-known among the developers due to its wide range of system call functions, especially the system function calls for “files”. POSIX library for Linux operating system provides you with a variety of functions. There is an open() function that is purposely used to open a specific file from a system in one of those POSIX calls. It utilizes many options to create, open, read, write, and do many things on the Linux files.
Example 1:
Let’s take a look at the first example to use the open() function of POSIX to simply create and open the files in a read-only mode. For this, use the touch query in your shell to create a C file. It can be saved into the current working folder.
Open your newly generated file, i.e. open.c, in the editor to add some code snippet within it just like in the presented image. Start your code with the use of C standard headers like stdio.h, fcntl.h, and errno.h that are purposely included for standard input/output, use of filing, and display the errors, respectively. There is a main() function to perform the execution. We create an integer variable “f” that is used as a file descriptor to get the returned value from the “open()” function call. The open() function uses the text file name along with two options – the “O_RDONLY” option to read the already existing file and the “O_CREAT” option to create a file if it does not exist.
The printf() statement displays the returned value using the descriptor “f”. The value of “f” is equal to “-1”. It throws an error that we failed to open or create a file along with an error message via the perror() function. Otherwise, the printf() statement displays the success message on our screen. The code is completed using the return 0 statement.
#include
#include
#include
int main ( )
int f = open ( «new.txt» , O_RDONLY
Now, we need to create the same name text file “file.txt” in the same folder and add some text data into it as presented using the “Cat” instruction of Linux. We compile and execute our “open.c” file and get the first 12 characters from the “file.txt” are displayed on the shell.
Example 3:
You can use the open() function call to copy the text data from one file to another with a slight change in the code. We cast off the same example code snippet and make some changes to a few of its lines. The size of character buffer “A” is updated to 50 and the f1 descriptor opens the file “file.txt” in a “read-only” mode using the “O_RDONLY” in an open() function. The read() function uses the “f1” descriptor to read 25 characters from the “file.txt” file and save them to buffer array “A”. The returned success/failure value is saved to variable “n”.
Another file descriptor “f2” is used here to create a new file named “source.txt” within the same folder using the “0_CREAT” option in an “open” method and with a “write-only” mode (O_WRONLY) with the 0642 value to write. The write() function call uses the value “n” to get the data from the character buffer “A” and parse it to the second file “source.txt” using its descriptor “f2”. Now, let’s run the following code to see what we get in the output:
#include
#include
int main ( )
char A [ 50 ] ;
int f1 = open ( «file.txt» , O_RDONLY ) ;
int n = read ( f1, A, 25 ) ;
int f2 = open ( «source.txt» , O_CREAT
Now, we have a “file.txt” and “open.c” file in the current folder. You can see the data within the “file.txt”. In the “open.c” file execution, the source.txt file is generated and the 25 characters from the “file.txt” file are copied to the “source.txt” file as well.
Conclusion
This guide is simple yet full of C examples to utilize and learn the POSIX “open()” function call. Using all the given examples, you will never fail while using the files in C.