Close (system call)

Last updated

A close system call is a system call used to close a file descriptor by the kernel. For most file systems, a program terminates access to a file in a filesystem using the close system call. This flushes file buffers, updates file metadata, which may include and end-of-file indicator in the data; de-allocates resources associated with the file (including the file descriptor) and updates the system wide table of files in use. Some programming languages maintain a data structure of files opened by their runtime library and may close when the program terminates. This practice is known as resource acquisition is initialization (RAII). Some operating systems will invoke close on files held by a program if it terminates. Some operating systems will invoke the close syscall as part of an operating system recovery as a result of a system failure.

Contents

C interfaces

Standard library

The C standard library provides the fclose function with the signature [1]

intfclose(FILE*stream);

The file is represented by the file pointer stream, which is typically an abstraction over a platform-dependent handle to the underlying file object. As such, fclose is almost always implemented as a library call which in turn closes the file with the corresponding system call. This additional layer of abstraction allows the function to remain portable across different environments while providing the same functionality. A successful call to fclose returns zero, but if an error occurs the function instead returns EOF (commonly defined as -1). In both cases, the file pointer is guaranteed to be disassociated from the file and should not be further used by an application.

POSIX

The POSIX standard includes the close system call, declared as [2]

intclose(intfildes);

The function takes the file descriptor fildes, an integer identifier for the open file, as a parameter. It allows the value of fildes to be reused for later opened files, and if no other file descriptor currently refers to the same file, any resources associated with the open file are freed. On success, close returns zero. Otherwise if an error occurs, the function returns -1 and assigns a relevant error code to the global variable errno. In this situation, the value of errno and the state of fildes are partially dependent on the version of POSIX the system adheres to.

In all versions of POSIX, errno is set to EBADF if fildes is an invalid file descriptor, and to EIO if a platform-dependent IO error occurs. Up to and including POSIX.1-2017, if a signal is sent to the process and interrupts the call to close, the call fails with EINTR and the state of the file descriptor is explicitly unspecified by the standard. So depending on the implementation, the file descriptor may have been closed, in which case close should not be called again. Or the file descriptor may still remain open, meaning close should be called again.

This behaviour was argued by developers to be unsafe for portable applications. In particular, it can cause race conditions in multithreaded environments, where a file descriptor may be reused in a different thread prior to retrying close. [3] [4] To address this, POSIX.1-2024 instead requires that in the event of an interrupted call to close, the function can either succeed, fail with EINTR and leave the file descriptor open, or fail with EINPROGRESS and close the file descriptor. [5]

References

  1. "The fclose function". ISO/IEC 9899:2011 Information technology — Programming languages — C. Geneva, Switzerland: ISO. 2011-12-15. §7.21.5.1. Retrieved 2025-12-12.
  2. "close()". IEEE Std 1003.1-2008 Standard for Information Technology — Portable Operating System Interface (POSIX®). New York City, United States: IEEE. 2008-12-01. pp. 676–679. doi:10.1109/IEEESTD.2008.4694976. ISBN   978-0-7381-4048-3 . Retrieved 2025-10-28.
  3. Edge, Jake (2013-12-11). "Returning EINTR from close()". LWN.net. Archived from the original on 2025-08-31. Retrieved 2025-12-12.
  4. Percival, Colin (2011-12-17). "POSIX close(2) is broken". Daemonic Dispatches. Archived from the original on 2025-09-13. Retrieved 2025-12-12.
  5. "close()". IEEE Std 1003.1-2024 Standard for Information Technology — Portable Operating System Interface (POSIX®). New York City, United States: IEEE. 2024-06-14. pp. 745–750. doi:10.1109/IEEESTD.2024.10555529. ISBN   979-8-8557-0793-9 . Retrieved 2025-10-28.