Code Comments
Programming Forum and web based access to our favorite programming groups.Hello All, Say that we take the set of system calls or built in procedures provided by a UNIX, which could include libraries and the like in POSIX and others. Then, say that we consider the subset of these calls that can or could potentially be interruptable. Ones that come to mind immediately are things like WAIT, functions that return EINTR, &c. For this set of functions, I will have some that take input or output parameters, such as pointers to structures or variables that are going to either be read for input or used to store output values, such as a pointer to an integer that stores the count of what was read or stored. Say then, that a function like the above is interrupted. What kind of Gurantee on a UNIX system do I have on the integrity of these I/O Parameters? That is, is there any guarantee that I will not have to reinitialize these parameters when I restart the call? I'm looking both for the normal case as well as fringe cases like Cygwin or the like. For example, if a call to a funtion that has a count pointer into which is stored the amount of data transferred or something of the like, is interrupted, can I be absolutely sure, from a conservative point of view, that the count variable is reliable and does not need to be reinitialized before restarting the call? Thanks for your time! -- Aaron Hsu <arcfide@sacrideo.us> | Jabber: arcfide@jabber.org ``Government is the great fiction through which everybody endeavors to live at the expense of everybody else.'' - Frederic Bastiat
Post Follow-up to this messageIn article < 1P2dnb4LrZWMsXbanZ2dnUVZ_sOrnZ2d@giganew s.com>, Aaron Hsu <arcfide@sacrideo.us> wrote: > Hello All, > > Say that we take the set of system calls or built in procedures provided > by a UNIX, which could include libraries and the like in POSIX and > others. Then, say that we consider the subset of these calls that can or > could potentially be interruptable. Ones that come to mind immediately > are things like WAIT, functions that return EINTR, &c. > > For this set of functions, I will have some that take input or output > parameters, such as pointers to structures or variables that are going > to either be read for input or used to store output values, such as a > pointer to an integer that stores the count of what was read or stored. > > Say then, that a function like the above is interrupted. What kind of > Gurantee on a UNIX system do I have on the integrity of these I/O > Parameters? That is, is there any guarantee that I will not have to > reinitialize these parameters when I restart the call? I'm looking both > for the normal case as well as fringe cases like Cygwin or the like. For > example, if a call to a funtion that has a count pointer into which is > stored the amount of data transferred or something of the like, is > interrupted, can I be absolutely sure, from a conservative point of > view, that the count variable is reliable and does not need to be > reinitialized before restarting the call? > > Thanks for your time! I'm having trouble understanding what you're asking about. Are you asking from the perspective of a USER of the system calls, or as an IMPLEMENTOR? -- Barry Margolin, barmar@alum.mit.edu Arlington, MA *** PLEASE don't copy me on replies, I'll read them in the group ***
Post Follow-up to this messageAaron Hsu <arcfide@sacrideo.us> writes: > Say that we take the set of system calls or built in procedures provided > by a UNIX, which could include libraries and the like in POSIX and > others. Then, say that we consider the subset of these calls that can or > could potentially be interruptable. Ones that come to mind immediately > are things like WAIT, functions that return EINTR, &c. > > For this set of functions, I will have some that take input or output > parameters, such as pointers to structures or variables that are going > to either be read for input or used to store output values, such as a > pointer to an integer that stores the count of what was read or stored. > > Say then, that a function like the above is interrupted. What kind of > Gurantee on a UNIX system do I have on the integrity of these I/O > Parameters? This depends on your "philosophical standpoint": If you believe that not specifically forbidding something constitutes a permit to do something, no matter how useless or dangerous something may be, then you will always have to reinitialize everything after passing a pointer to some other routine. If you think that a routine causing undocumented side effects would be broken, and if you are additionally willing to trust the common sense of system implementors enough to assume that they understand why 'the principle of least astonishment' is reasonable, then you will likely write code to work around buggy implementations of something after having encountered them and will otherwise ignore the possibility.
Post Follow-up to this messageBarry Margolin <barmar@alum.mit.edu> writes: >In article < 1P2dnb4LrZWMsXbanZ2dnUVZ_sOrnZ2d@giganew s.com>, > Aaron Hsu <arcfide@sacrideo.us> wrote: >I'm having trouble understanding what you're asking about. Are you >asking from the perspective of a USER of the system calls, or as an >IMPLEMENTOR? I am asking as an user of the system calls. I want to ensure that the code I write is ``well-behaved'' over all the UNIX platforms, and this is one issue I would like to ensure I am doing right. -- Aaron Hsu <arcfide@sacrideo.us> | Jabber: arcfide@jabber.org ``Government is the great fiction through which everybody endeavors to live at the expense of everybody else.'' - Frederic Bastiat
Post Follow-up to this messageAaron Hsu <arcfide@sacrideo.us> writes: [...] > I am asking as an user of the system calls. I want to ensure that the > code I write is ``well-behaved'' over all the UNIX platforms, and this > is one issue I would like to ensure I am doing right. This still depends on the answer to the question if you think that code should be written to take possibly undocumented side effects of system (and library) calls into account or if you think it shouldn't. Of course, for any UNIX(*)-interface in question, the actual documentation would need to be checked, too. Insofar you are actually interested in the practical explanation: Kernel code isn't "interrupted" by signals the way it is interrupted by interrupts and interrupt-induced processing (eg softirqs on Linux). Inside a blocking system call which could return EINTR, there will usually be a loop working rougly like the pseudocode below[*]: while (!(can_work || signal_pending)) sleep(); if (!can_work) return -EINTR /* do some work */ If a signal is posted for a particular process (or thread), the fact that it was will be recorded in some data structure (for non-RT-signals probably a bitfield) and the process will be woken up if it is presently sleeping. The kernel code the process is executing then checks for 'signal pending' as one of the conditions which should terminate the sleep and 'does something' to react to it [**]. Because this completely synchronous wrt to the process itself, all data structures are always in 'well-defined' states. [*] This is true for Linux. In traditional UNIX(*) [V7], the sleep routine would check for the signal and anything else would be done by the caller. [**] Linux returns with a special error code along the normal return path, the V7-UNIX available from TUHS executed 'a long jump' to some signal handling code. There is no 'guarantee' whatsoever that a specific actual implementation works in an even remotely similar way. But 'breaking a lot of software' is usually considered unwise (except if you are a C++-programmer getting paid to 'update' C++-source code to the "current C++-fashion" ...)
Post Follow-up to this messageOn Thu, 27 Mar 2008 01:16:12 -0400, Barry Margolin wrote: > In article < 1P2dnb4LrZWMsXbanZ2dnUVZ_sOrnZ2d@giganew s.com>, > Aaron Hsu <arcfide@sacrideo.us> wrote: > > > I'm having trouble understanding what you're asking about. Are you > asking from the perspective of a USER of the system calls, or as an > IMPLEMENTOR? My guess is that he means "restartable system calls". In that case googling for "Unix SA_RESTART" should help him, at least to rephrase the question. Another possibility is the arguments that are passed _by reference_ to the syscall, such as the struct timeval pointer that is passed to select (), and which is (sometimes) altered by linux. (Or the fd_sets, which are _intended_ to be altered.) AvK
Post Follow-up to this messagemoi <root@invalid.address.org> writes: > On Thu, 27 Mar 2008 01:16:12 -0400, Barry Margolin wrote: > > > My guess is that he means "restartable system calls". In that case > googling for "Unix SA_RESTART" should help him, at least to rephrase the > question. A simple example of what he is writing about would be: Assume there is a loop calling poll with some vector of pollfd structures initialized once before the loop. If a poll (which is not restartable) returns EINTR, will the elements of the pollfd array still have the values they had before the call or is it possible that some of them have been overwritten with inconsistent garbage data because of the interrupted system call? Another example: Are the fdsets passed to a select still intact after select returned EINTR? The same question can be asked for any interruptible system taking result or value-result-arguments. AFAIK, the question cannot be answered from usual documentation, including SUS, which doesn't specify anything for 'system call error returns'. As I had pointed out in another posting, the way 'interrupted system calls' actually work ensures that reinitializations are not necessary and I would regard different behaviour of 'some calls' (not entirely improbable for random device drivers) as erronous. > Another possibility is the arguments that are passed _by reference_ to > the syscall, such as the struct timeval pointer that is passed to select > (), and which is (sometimes) altered by linux. (Or the fd_sets, which are > _intended_ to be altered.) Arguments to C-subroutines are always passed as values, not as references (which don't even exist in C). Some system calls take pointer arguments which shall point at areas in process memory intended to store output data into. Stephen's calls these 'result arguments' (only written to) or 'value-result arguments' (both read and written) [IIRC].
Post Follow-up to this messagemoi <root@invalid.address.org> writes: >On Thu, 27 Mar 2008 01:16:12 -0400, Barry Margolin wrote: > > > >My guess is that he means "restartable system calls". In that case >googling for "Unix SA_RESTART" should help him, at least to rephrase the >question. > >Another possibility is the arguments that are passed _by reference_ to >the syscall, such as the struct timeval pointer that is passed to select >(), and which is (sometimes) altered by linux. (Or the fd_sets, which are >_intended_ to be altered.) > The rule is simple. If EINTR is returned, no application visible side effects have occured, including modification of reference arguments. If ERESTART is returned (usually not visible to the application anyway), the system call has guaranteed that it can be restarted without ill effect. In neither case does the application have to do anything other than retry an EINTR if desired. scott
Post Follow-up to this message
Show a Printable Version
Email This Page to Someone!
Receive updates to this thread
Powered by vBulletin
Copyright 2000-2006 Jelsoft Enterprises Limited.