Proper way of handling EINTR in libraries

What is the recommended etiquette when it comes to EINTR in libraries?

I’m currently writing a function that does some file system tasks with the POSIX API, but a lot of the calls I use can potentially return EINTR. Additionally, the function can block under some circumstances. (For those interested, it implements a locking mechanism.)

In the interests of making this as general as possible, I would like to know what is the proper way to deal with an interrupted system call.

  • From most sources I’ve read, people typically retry the call and continue on with their business. However, I’m not sure that’s the right thing to do here, since there may be legitimate reasons to interrupt my function given that it can take a significant amount of time. Furthermore, it means the EINTR would simply get swallowed by the function and the caller would lose any indication that it occurred.

  • My current strategy is to immediately abort the operation if I receive EINTR and notify the caller about it. This way, the caller can decide if they want to retry my function, right? (Or perhaps my understanding of signals is flawed?)

2

Always leave the decision of how to handle EINTR to the user, and make it easy to resume the operation as appropriate.

Usually the best way to do that is to return from your library function to the caller upon EINTR, but in some cases a callback or some other implemention might be better – which way is best depends on other factors, but always let the user control retry and resume.

This means that if your library code can partially succeed before getting an EINTR, then you should think carefully what the user might need to know about that partial success, or if the user might need to resume the operation from where it failed. You might need to return additional information or provide an interface for resuming from any place where it might be appropriate to.

This is why system calls like read and write nowadays return partial success – because it is very frustrating as a user to be told:

You tried to write "foo" and we successfully wrote either nothing, or "f", or "fo", and you don’t get to know which. Have fun! Hope your system can handle restarting the whole write after any of those!

Of course, in some cases, we should write systems to handle situations exactly like that – for example, perhaps after a partial write you always recreate the file, or reopen the network connection, or you use some byte to mean “starting over” – so it depends on what use cases your library targets.

If a library function does several operations, and there is no way to know at which of them it failed, and those operations are not all safely and efficiently idempotent, that basically makes a library unusable for code that needs to be robust.

If all steps in a library function are safely and efficiently idempotent, or the whole thing is atomic – like acquiring a lock – then just letting the user know that an EINTR happened is enough.

Also, if we retry on EINTR, then we might break signal handling. At the low level, signal handlers can only safely use a limited set of features, and so in many cases a signal handler will just set a boolean indicating that the signal was received, and then return, expecting that when the code resumes, it will exit out of whatever it was doing. If we get an EINTR and then we retry instead of returning control to the user, we might be keeping the code from doing that.

What to do after an EINTR is a whole program decision – the right answer cannot be known without knowing what the program is doing and how the program is meant to respond to a signal, and it has effects on the rest of the program.

Knowing how or if the user might need to resume, and helping the user do so if it is needed, is a library responsibility – the right answer cannot be known without knowing what the library is doing.

4

Signals in Unix

when some other process sends your process Signal, your program will stop what it’s doing…

1) Run the handler code you wrote. You have no idea what your program might be doing when the signal arrives. That’s the idea with signals, they can be completely asynchronous.

2) When the signal handler is done, it typically just does a return, and your program continues where it left off, as if nothing had happened.

Found some useful info in Richard Stevens

A characteristic of earlier UNIX systems is that if a process caught a signal while the process was blocked in a “slow” system call, the system call was interrupted. The system call returned an error and errno was set to EINTR. This was done under the assumption that since a signal occurred and the process caught it, there is a good chance that something has happened that should wake up the blocked system call.

POSIX.1 semantics for interrupted reads and writes changed with the 2001 version of the standard. Earlier versions gave implementations a choice for how to deal with reads and writes that have processed partial amounts of data. If read has received and transferred data to an application’s buffer, but has not yet received all that the application requested and is then interrupted, the operating system could either fail the system call with errno set to EINTR or allow the system call to succeed, returning the partial amount of data received. Similarly, if write is interrupted after transferring some of the data in an application’s buffer, the operation system could either fail the system call with errno set to EINTR or allow the system call to succeed, returning the partial amount of data written. Historically, implementations derived from System V fail the system call, whereas BSD-derived implementations return partial success. With the 2001 version of the POSIX.1 standard, the BSD-style semantics are required.

The problem with interrupted system calls is that we now have to handle the error return explicitly. The typical code sequence (assuming a read operation and assuming that we want to restart the read even if it’s interrupted) would be

again:
    if ((n = read(fd, buf, BUFFSIZE)) < 0) {
        if (errno == EINTR)
            goto again;     /* just an interrupted system call */
        /* handle other errors */
    }

To prevent applications from having to handle interrupted system calls, 4.2BSD introduced the automatic restarting of certain interrupted system calls.

1

Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa Dịch vụ tổ chức sự kiện 5 sao Thông tin về chúng tôi Dịch vụ sinh nhật bé trai Dịch vụ sinh nhật bé gái Sự kiện trọn gói Các tiết mục giải trí Dịch vụ bổ trợ Tiệc cưới sang trọng Dịch vụ khai trương Tư vấn tổ chức sự kiện Hình ảnh sự kiện Cập nhật tin tức Liên hệ ngay Thuê chú hề chuyên nghiệp Tiệc tất niên cho công ty Trang trí tiệc cuối năm Tiệc tất niên độc đáo Sinh nhật bé Hải Đăng Sinh nhật đáng yêu bé Khánh Vân Sinh nhật sang trọng Bích Ngân Tiệc sinh nhật bé Thanh Trang Dịch vụ ông già Noel Xiếc thú vui nhộn Biểu diễn xiếc quay đĩa Dịch vụ tổ chức tiệc uy tín Khám phá dịch vụ của chúng tôi Tiệc sinh nhật cho bé trai Trang trí tiệc cho bé gái Gói sự kiện chuyên nghiệp Chương trình giải trí hấp dẫn Dịch vụ hỗ trợ sự kiện Trang trí tiệc cưới đẹp Khởi đầu thành công với khai trương Chuyên gia tư vấn sự kiện Xem ảnh các sự kiện đẹp Tin mới về sự kiện Kết nối với đội ngũ chuyên gia Chú hề vui nhộn cho tiệc sinh nhật Ý tưởng tiệc cuối năm Tất niên độc đáo Trang trí tiệc hiện đại Tổ chức sinh nhật cho Hải Đăng Sinh nhật độc quyền Khánh Vân Phong cách tiệc Bích Ngân Trang trí tiệc bé Thanh Trang Thuê dịch vụ ông già Noel chuyên nghiệp Xem xiếc khỉ đặc sắc Xiếc quay đĩa thú vị
Trang chủ Giới thiệu Sinh nhật bé trai Sinh nhật bé gái Tổ chức sự kiện Biểu diễn giải trí Dịch vụ khác Trang trí tiệc cưới Tổ chức khai trương Tư vấn dịch vụ Thư viện ảnh Tin tức - sự kiện Liên hệ Chú hề sinh nhật Trang trí YEAR END PARTY công ty Trang trí tất niên cuối năm Trang trí tất niên xu hướng mới nhất Trang trí sinh nhật bé trai Hải Đăng Trang trí sinh nhật bé Khánh Vân Trang trí sinh nhật Bích Ngân Trang trí sinh nhật bé Thanh Trang Thuê ông già Noel phát quà Biểu diễn xiếc khỉ Xiếc quay đĩa
Thiết kế website Thiết kế website Thiết kế website Cách kháng tài khoản quảng cáo Mua bán Fanpage Facebook Dịch vụ SEO Tổ chức sinh nhật