Re: When/how is global "errno" variable from reent.c to be used?

Grant Edwards via Newlib <[email protected]>
Newsgroups gmane.comp.lib.newlib
Message-ID <[email protected]>
On 2020-10-16, Richard Damon <[email protected]> wrote:

> First, newlib considers itself as part of 'the implementation', as its
> purpose is to provide the 'standard library' for an implementation, thus
> it can do what it wants here (as long as the net result meets the
> specifications).

Right. I didn't mean to imply that newlib having a globally visible
integer variable named 'errno' was wrong. I was just asking what it
was for.

> I would have to dig into the actual implementation details to tell
> for sure, but first check if when the statement int errno; is
> compiled, is errno currently a macro, and after replacing that macro
> with its definition what the statement actually defines, it might be
> creating the pointer that is used to access the effective errno.

Sorry, I don't really understand that sentence. The file
newlib/libc/reent/reent.c defines a globally visible integer variable
named 'errno'. I was asking what that globally visible 'int errno' was
for. I've done some additional code browsing, and it appears to be
used by other files in newlib/libc/reent/ to provide fake "reentrant"
<whatever>_r() versions of system calls for which there aren't actual
_r() versions.

Except I don't see how those _r() functions could actaully _be_
rentrant, since they all use a single shared, global, errno variable.
The description/comments claiming they are rentrant seems to be
deceptive.  For example from readr.c (edited for time and to fit your
screen):

    /* Reentrant versions of read system call. */
    [...]
    /* We use the errno variable used by the system dependent layer.  */
    #undef errno
    extern int errno;
    /*
    [...]
    DESCRIPTION
    	This is a reentrant version of <<read>>.  It
    	takes a pointer to the global data block, which holds
    	<<errno>>.
    */
    
    _ssize_t _read_r (struct _reent *ptr, int fd, void *buf, size_t cnt)
    {
      _ssize_t ret;
    
      errno = 0;
      if ((ret = (_ssize_t)_read (fd, buf, cnt)) == -1 && errno != 0)
        ptr->_errno = errno;
      return ret;
    }

I just don't see how that function can be called reentrant.

> It could also be creating a global variable just to limit the breakage
> that programs that do it wrong incur

I don't think so. It appears to actually be used when making calls to
the system-dependent layer.

> (though, I might prefer getting the link error errno not defined
> rather than code that ends up checking the wrong errno).

Agreed.
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.