How do I handle EINTR status

Posted on 1998-07-16
Last Modified: 2013-12-26
Hi guys, gals and any others :-) out there, I have a 'C' based routine writing records to a pipe. This routine is part of a dynalink library linked in at run time to a "host utility program". The "host utility program" reads records from a data base and passes each record to my routine one at a time for some processing (i.e. writing them to the pipe). I have no access to the internals or the source code of the "host utility". The host utility is a database export utility (called fastexport) for the Teradata RDBMS my dynalink library is refered to as an OUTMOD in Teradata parlance.

My problem is that every now and then (maybe once in a million records processed) I get the EINTR result back from the write system call. The call fails (because of the EINTR) but if i simply retry the call then no problem for another million records or so (figures are highly variable it could go 10 million records or more without error smallest # of records was about 100K before EINTR). The record format is always the same.  For what it is worth the pipe is a named pipe opened with the open system call and the O_WRONLY flag. The reader process opens the pipe with the O_RDONLY flag set on the open system call.

I have some basic understanding of what an EINTR means from my University days but can't find any doco on it in any of the unix man pages (other than the really helpful :-) #define statement in errno.h). So, my questions are:
* when I get the EITNR, how do i handle it (I assume it is unwise to simply ignore it without at least understanding why it is occuring)?
* Is it possible to determine what the interrupt was that occured during the system call (to help understand why it is happening)?
* Is the interrupt it is referring to a signal (again can you determine which one)?
* If i determine that the interrupt is something that the host utility is trying to handle is there a way to "raise" the signal from my dynalink routine back to the host utility?
* If none of the above questions hints at this one, what is Unix trying to tell me? i.e. is it trying to tell me that a system wide interrupt occured (eg a timer tick) during my system call and Unix is trying to tell me that it dealt with it - i find this unlikely? Or is unix trying to tell me that a signal i (or the host utility) has requested to handle had fired whilst stuck in the system call and as a result, Unix couldn't invoke my handler because it was in the middle of the system call?

Question by:firefox032697
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
  • 2
  • 2
  • +3
LVL 51

Expert Comment

ID: 1294930
My write man-page says:

  EINTR  The call was interrupted by a signal before any
         data was written.

So it just tells you that somthing with a higher priority happend *and* rejected to continue in write().

Expert Comment

ID: 1294931
If you do get EINTR, there's little you can do except retrying.
The signal is probably one of those that the host utility handles. If you find out which one, you can specify the SA_RESTART option in a sigaction call. Or, you can mask signal(s)
before write and unmask afterwards.

Expert Comment

ID: 1294932
This is interesting...I have an app that forks, and the sibling processes communicate through a pipe created by socketpair() before the fork().  Very occasionally, one end gets an EINTR while reading the pipe.  I've written a signal collector that I hope will tell me what signal is causing the EINTR, but I haven't put it in place yet.  (Although, as mlev points out, in your case it may be a signal that has meaning only to the host application, but that happens to strike when you're read()ing or write()ing.)

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.


Expert Comment

ID: 1294933
If a process caught a signal while process was blocked in a slow system call, the system call is interrupted and return an error and the error number is set to EINTR. The places where it may happen are

1. Reads from and writes to pipes, terminal and N/W devices
2. IPC
3. some ioctl calls,
4. pause etc.

 In your case, as the signal is for the host application and not for you. But as a result of which your system call (read?) failed.

There are two ways to tackle it.

1. An example code is given below.

loop: if ((n = read(pipeid,buf, BUFSIZE)) < 0) {
            if (errno == EINTR)
                  goto loop;

Change the code to something without the goto ;-)

2. Some of the Unix systems offer the option of restarting the system call. Please note that all systems do not support this. In SVR4 systems, you have to specify SA_RESTART in the sigaction call.Once this is specified, kernel will restart the interrupted system call.

Author Comment

ID: 1294934
We already retry the system call and as stated in the question if we retry it is fine for another million records or so.

The other, important, questions for which we need the answers are:
* how do we tell what the signal was that occured during the system call?
* Can we raise the signal (eg. with the kill system call) that did occur so that we can notify the host program?

If we can figure out what the signal was then we could certainly raise it to the parent process. This means that the most important thing is how can i determine what the signal was?

Expert Comment

ID: 1294935
You don't need to raise the signal, the host program has already handled it at that point.
As a rule, if a process receives a signal while in kernel mode,
the signal is processed right after the system call.
It works like this:
1. You call write.
2. Before it is completed, the kernel decides (for whatever reason)
that your process should get SIGXXXX.
3. write is aborted with errno=EINTR
4. The signal handler for SIGXXXX is called.
5. Execution resumes after the call to write.

Expert Comment

ID: 1294936
Since the host program has already caught the signal, there is no need to catch the signal(I don't know if you can catch this, since the signal may not even be delivered to you).

And you have pointed out that you have no control ovet the server process & program.

Accepted Solution

elfie earned 100 total points
ID: 1294937
if you read the man page of sigaction, you will notice that for each interrupt you can either enable or disable it, and if you enabled it, you can write write your own catch routine. (you even can handle SEGV or BUS signals).

Inside your own catch routine you can determine which signal/interrupt occured. (It is passed as a parameter)

You can find an example (one of many) at:

If you want to raise signals , use the kill command, or the sigsend function.

Need more info? reject the answer and wait for better/more info


Author Comment

ID: 1294938
Thanks to all those who contributed (especially mlev)

Featured Post

Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Exception Handling is in the core of any application that is able to dignify its name. In this article, I'll guide you through the process of writing a DRY (Don't Repeat Yourself) Exception Handling mechanism, using Aspect Oriented Programming.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…

626 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question