Solved

How do I handle EINTR status

Posted on 1998-07-16
9
321 Views
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?

TIA
0
Comment
Question by:firefox032697
  • 2
  • 2
  • 2
  • +3
9 Comments
 
LVL 51

Expert Comment

by:ahoffmann
Comment Utility
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().
0
 
LVL 2

Expert Comment

by:mlev
Comment Utility
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.
0
 
LVL 3

Expert Comment

by:dhm
Comment Utility
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.)
0
 

Expert Comment

by:marar
Comment Utility
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.
0
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 

Author Comment

by:firefox032697
Comment Utility
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?
0
 
LVL 2

Expert Comment

by:mlev
Comment Utility
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.
0
 

Expert Comment

by:marar
Comment Utility
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.
0
 
LVL 3

Accepted Solution

by:
elfie earned 100 total points
Comment Utility
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:
http://www.nr.no/lava/kjerne/docs/api/example1.html


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

0
 

Author Comment

by:firefox032697
Comment Utility
Thanks to all those who contributed (especially mlev)
0

Featured Post

What Is Threat Intelligence?

Threat intelligence is often discussed, but rarely understood. Starting with a precise definition, along with clear business goals, is essential.

Join & Write a Comment

Suggested Solutions

Introduction: The undo support, implementing a stack. Continuing from the eigth article about sudoku.   We need a mechanism to keep track of the digits entered so as to implement an undo mechanism.  This should be a ‘Last In First Out’ collec…
Introduction: Dialogs (1) modal - maintaining the database. Continuing from the ninth article about sudoku.   You might have heard of modal and modeless dialogs.  Here with this Sudoku application will we use one of each type: a modal dialog …
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.
This video discusses moving either the default database or any database to a new volume.

763 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

Need Help in Real-Time?

Connect with top rated Experts

6 Experts available now in Live!

Get 1:1 Help Now