Subject: [clisp-list] linux FFI: What/where is _IO_stdin/out/err_? -- errno

From: "Hoehle, Joerg-Cyril" <[email-masked]>
Date: Fri Apr 4 07:29:41 2003

Hi,

could somebody with recent Linux/UNIX knowledge help me with the following:

is it legal to assign to errno?
E.g. errno = 0; in C application code?

Shall CLISP Linux FFI support assignment to errno?

On a (Suse)Linux box, I found
/usr/include/errno.h
/* Declare the `errno' variable, unless it's defined as a macro by
   bits/errno.h.  This is the case in GNU, where it is a per-thread
   variable.  This redeclaration using the macro still works, but it

And in /usr/include/bits/errno.h
/* Function to get address of global `errno' variable.  */
extern int *__errno_location (void) __THROW __attribute__ ((__const__));

#  if !defined _LIBC || defined _LIBC_REENTRANT
/* When using threads, errno is a per-thread value.  */
#   define errno (*__errno_location ())

Thus, printf("%d",errno); works.
But such a #define does not work with errno=x;

bits/errno.h goes on:
#  if defined _LIBC
/* We wouldn't need a special macro anymore but it is history.  */
#   define __set_errno(val) (*__errno_location ()) = (val)

Is there some C compiler magic to expand errno=x into __set_errno(x)?

Given this, could somebody explain to me how bindings/linux.lisp
(def-c-var errno (:type ffi:int))
can possibly work, since this expands to
  register_foreign_variable(&errno,"errno",0,sizeof(errno));
Is &errno (i.e. the address of a value returned by a function!) well-defined? I'd say: no. Is that just some more C compiler errno hacks?

BTW, in order not to have to revisit this area the day CLISP would have threads, linux:errno has to become a symbol-macro which expands to a FFI call.
(def-call-out __errno_location (:arguments) (:return-type (c-ptr int)))
(define-symbol-macro errno (linux:__errno_location))
But that does not support (setf linux:errno x).

Thanks,
	Jorg Hohle.

---

From: Sam Steingold <[email-masked]>
Date: Fri Apr 4 08:31:55 2003

> * In message <[email-masked]>
> * On the subject of "[clisp-list] linux FFI: What/where is _IO_stdin/out/err_? -- errno"
> * Sent on Fri, 4 Apr 2003 15:54:30 +0200
> * Honorable "Hoehle, Joerg-Cyril" <[email-masked]> writes:
>

yes, absolutely.

> Shall CLISP Linux FFI support assignment to errno?

yes, absolutely.

> But such a #define does not work with errno=x;

why not?!

 (*foo()) = 10;

will write 10 into the memory area pointed to by the return value of
foo().

> BTW, in order not to have to revisit this area the day CLISP would
> have threads, linux:errno has to become a symbol-macro which expands
> to a FFI call. 

se we should add a (setf linux:errno) macro or function.

-- 
Sam Steingold (http://www.podval.org/~sds) running RedHat8 GNU/Linux
<http://www.camera.org> <http://www.iris.org.il> <http://www.memri.org/>
<http://www.mideasttruth.com/> <http://www.palestine-central.com/links.html>
I want Tamagochi! -- What for?  Your pet hamster is still alive!

---

From: Kaz Kylheku <[email-masked]>
Date: Fri Apr 4 08:38:27 2003

> E.g. errno = 0; in C application code?

Yes. In fact, it is unavoidable in certain correct, portble programming
practices. Some ANSI C library functions indicate failure, and may set
errno. The only way to know whether they had any effect on errno is to
assign zero to it before, and then checking for a nonzero value after
failure in the function is detected.

ANSI C only defines the errors EDOM and ERANGE; so the above trick is
needed in conjunction with, for instance, <stdio.h> streams.

> Shall CLISP Linux FFI support assignment to errno?

In Meta-CVS, errno is a symbol macro that expands to (get-errno).
(setf (get-errno)) works via a set-errno function.  The accessors
get-errno and set-errno are foreign functions that do the work in C.

> But such a #define does not work with errno=x;

Yes it does. It's deliberately designed that way.

  (*_errno_location()) = x; /* no problem */

you are dereferencing the pointer returned by the function to create an
lvalue (assignable place) that designates the location. It's like a
setf-able place in Lisp.