[C language] Close () It is dangerous to retry when it fails

Introduction

As a system call to close the file descriptor close()Is provided. Therefore, I will write about the pitfalls of the close system call, which is often overlooked.

#include <unistd.h>

int close(int fd);

EINTR invites you to a pitfall

For example, when calling a file I / O system call or library function eintrIs annoying, and there are cases where an error occurs when a function call is interrupted.

EINTR See function call interrupted (POSIX.1); signal (7).

Reference: Linux Programmer's Manual --ERRNO

In that case, even if it fails as follows, if it is EINTR, There is a workaround to provide a wrapper function to retry and prevent processing failure in EINTR.

/* wrapper function of send () */
ssize_t send_wrap(int sockfd, const void *buf, size_t len, int flags)
{
  int res = 0;
  do {
    res = send(sockfd, buf, len, flags);
  } while ((res == -1) && (errno == EINTR));
  return res;
}

There is also a failure due to ʻEINTR` in close (). However, retries on the ** close () system call are dangerous. ** **

Risk of retry when close () fails

So why is it dangerous to retry when close () fails? For example, in the case of multithreading, another thread may close the reused fd.

The Linux kernel releases the fd early in the process inside close (), The processing that can cause an error is located in the latter half of close ().

In other words, the process is returned as an error, but fd is ** released **, so If it is multithreaded, ** another thread may be reusing the fd **, There is a risk that ** the fd will be closed ** if it is retried.

Conclusion

From the above, it can be said that it is better not to retry the close () system call when it fails.

reference

http://man7.org/linux/man-pages/man2/close.2.html

Recommended Posts

[C language] Close () It is dangerous to retry when it fails
It is convenient to use Icecream instead of print when debugging.
Introduction to Protobuf-c (C language ⇔ Python)
When you want to use it as it is when using it with lambda memo
It is better to use Weight Initializer when initializing with HeNormal with Chainer
It was dangerous to specify a relative path when generating a symbolic link
What is a C language library? What is the information that is open to the public?
It is convenient to use Layers when putting a library on Lambda
Is it deprecated to use pip directly?
Behavior when SIGEV_THREAD is set in sigev_notify of sigevent with timer_create (C language)
It is more convenient to use csv-table when writing a table with python-sphinx
[OpenCV] When you want to check if it is read properly with imread