From: pjdm@chmeee.enet.dec.com (Peter Mayne)
Newsgroups: comp.arch
Subject: Re: <None> (Should be Open Systems, bloody NEWS system...)
Date: 29 Dec 92 01:22:15 GMT
Reply-To: Peter.Mayne@cao.mts.dec.com
Organization: Digital Equipment Corporation


In article <id.SQ3W.IB6@ferranti.com>, peter@ferranti.com (peter da silva) writes:
>> Now, much of the run-time stuff in UNIX is non-reentrant.
>
>Much of the *C* run-time in *any* language is non-reentrant, and I would
>be surprised if the VMS library was any better. If I get an AST while I'm
>in the runtime (say, in the Fortran library in the middle of a formatted
>I/O statement) I would expect dire consequences from calling the language
>runtime. I have never written an asyncronous signal handler under any
>operating system (out of UNIX, RMX, AmigaOS, and RSX-11) where I didn't
>have to watch for that sort of thing. In RSX all you can do from an AST,
>pretty much, is access memory.
>
>> In particular, the 
>> use of errno springs to mind. If the AST (or APC) was introduced into the
>> UNIX model,
>
>It's in there.
>
>> how can I use these non-reentrant routines safely in an AST
>> routine without screwing things up?
>
>You can't. Can you really do
>
>	WRITE (*,10) AA
> 10	FORMAT (1X,80A1)
>
>in an AST under VMS?
>

The following is from the tempnam thread in comp.unix.ultrix. (Is open(2)
considered part of the C run-time library, or the UNIX kernel?) Note that
in the example given below, it doesn't even matter if open(2) is reentrant
or not: you still have problems looking up the error. (See the sentence
marked **.)

>> Begin quote >>

aaa@pixar.com (Tony Apodaca) writes:

>	The point is that a smart programmer
>checks errno after every system call.

	The *wise* programmer checks the approriate return value of the
system call, and if it returns a value indicating an error, then the errno
value is used.

	Consider the following:

	int	fd;
	fd = open("foo",O_RDWR|O_CREAT,0600);
	if(errno != 0)
		perror("foo");

	Versus:

	int	fd;
	if((fd = open("foo",O_RDWR|O_CREAT,0600)) < 0)
		perror("foo");

	Now, the manual page on open(2) states explicitly:

RETURN VALUE
     The value -1 is returned if an error  occurs,  and  external
     variable  errno  is  set to indicate the cause of the error.

	There's a good reason for writing your code this way. You are
using the return value from the function, rather than a global value
which can get stepped on by something unusual you don't know about.
This means that your code doesn't have to care about what is a system
call versus what is a library routine. Do you care? I don't. I just
want to know if it didn't work right. Then I want to know why.

** I believe that you can also run into problems if you have
** a signal handler that gets invoked, and resets errno in the period
** between your successful system call and your test for success. It's
easier to just treat the system calls like a function call, and
look at its return value. If you somehow think that using errno
rather than having to declare a local to capture the return value is
an optimization, you're mistaken.

mjr.

>> End Quote >>

Fixing this kind of problem would involve changing the model of "returning
an error flag and a static errno". You could:

- return an error status rather than an error flag
- signal on errors
- call a "callback" routine on errors
- fill in a program-provided "status block" (non-static "errno" equivalent)

Any one of these would probably be considered incompatible by a large number
of UNIX style programmers (including DOS programmers and a lot of VMS
programmers).

>-- 
>Peter da Silva                                            `-_-'
>Ferranti International Controls Corporation                'U` 
>Sugar Land, TX  77487-5012 USA
>+1 713 274 5180                            "Zure otsoa besarkatu al duzu gaur?"

PJDM
--
Peter Mayne                     | My statements, not Digital's.
Digital Equipment Corporation   |
Canberra, ACT, Australia        | "AXP!": Bill the Cat