# Using errno with Ada

**URL:** https://forum.ada-lang.io/t/using-errno-with-ada/1490
**Category:** General
**Created:** [November 20, 2024, 5:49am UTC](https://forum.ada-lang.io/t/using-errno-with-ada/1490 "2024-11-20T05:49:14Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![nerd\_type](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/nerd_type/32/530_2.png) [@nerd\_type](https://forum.ada-lang.io/u/nerd_type)
#### Post date: [November 20, 2024, 5:49am UTC](https://forum.ada-lang.io/t/using-errno-with-ada/1490/1 "2024-11-20T05:49:14Z")

</div>

I there a good way to read ‘errno’ in Ada?

I am trying to import it using this:

```ada
Error_Number : Integer
with Import => True,
     Convention => C,
     External_Name => "errno";

```

However, I get a cryptic linker error when I try to use it:

```ada
x86_64-linux-gnu-gnatlink-12 test_ioctl.ali            
/usr/bin/ld: errno: TLS definition in /lib/x86_64-linux-gnu/libc.so.6 section .tbss mismatches non-TLS reference in ./test_ioctl.o      
/usr/bin/ld: /lib/x86_64-linux-gnu/libc.so.6: error adding symbols: bad value
collect2: error: ld returned 1 exit status
x86_64-linux-gnu-gnatlink-12: error when calling /usr/bin/x86_64-linux-gnu-gcc-12
gnatmake: *** link failed.

```

Any ideas?

Thanks,  
N

---

<div class="post-metadata">

### Author: ![Irvise](https://forum.ada-lang.io/letter_avatar_proxy/v4/letter/i/7ba0ec/32.png) [@Irvise](https://forum.ada-lang.io/u/Irvise)
#### Post date: [November 20, 2024, 8:18am UTC](https://forum.ada-lang.io/t/using-errno-with-ada/1490/2 "2024-11-20T08:18:38Z")

</div>

This is a good question and I saw that quite a few people had had this exact same issue (related to `errno`) when working with C codebases: [https://www.linuxquestions.org/questions/programming-9/errno-tls-definition-in-lib64-libc-so-6-section-tbss-mismatches-non-tls-reference-528681/](https://www.linuxquestions.org/questions/programming-9/errno-tls-definition-in-lib64-libc-so-6-section-tbss-mismatches-non-tls-reference-528681/) and [https://www.linuxquestions.org/questions/linux-general-1/ld-errno-tbss-mismatches-non-tls-reference-588894/](https://www.linuxquestions.org/questions/linux-general-1/ld-errno-tbss-mismatches-non-tls-reference-588894/) and [Fixing /usr/bin/ld: errno: TLS definition in /lib/libc.so.6 section .tbss mismatches](https://www.taygeta.com/misc/nonTLS.html)

It seems that `errno` is not a normal symbol and even in C applications the C header needs to be imported so that this issue does not happen, it is not enough to declare it as `extern`…

I cannot help you much further though 😕

Best regards,  
Fer

---

<div class="post-metadata">

### Author: ![simonjwright](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/simonjwright/32/11_2.png) [@simonjwright](https://forum.ada-lang.io/u/simonjwright)
#### Post date: [November 20, 2024, 8:19am UTC](https://forum.ada-lang.io/t/using-errno-with-ada/1490/3 "2024-11-20T08:19:15Z")

</div>

Oh, the magic of C preprocessing!

Under the hood, `errno` may be a function call to collect a thread-local value; so `errno` looks global, but in fact may not be.

I tried this, in `errno.c`:

```ada
#include <sys/errno.h>
#include <stdio.h>

int main()
{
  int current_errno = errno;
  printf("errno: %d\n", current_errno);
  return 0;
}

```

and `cpp errno.c` tells me at the end

```ada
# 4 "errno.c"
int main()
{
  int current_errno = 
# 6 "errno.c" 3 4
                     (*__error())
# 6 "errno.c"
                          ;
  printf("errno: %d\n", current_errno);
  return 0;
}

```

so, _on a Mac_, `errno` is in fact a function call to whatever `__error` is pointing to (or maybe, my C isn’t that great, `__error()` returns a pointer to the appropriate actual `errno`? otherwise, how could you say e.g. `errno = EINVAL;` ?).

For portability, you’d have to write a C function to pick up `errno` and return that, and then import that function.

---

<div class="post-metadata">

### Author: ![dmitry-kazakov](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/dmitry-kazakov/32/522_2.png) [@dmitry-kazakov](https://forum.ada-lang.io/u/dmitry-kazakov)
#### Post date: [November 20, 2024, 8:21am UTC](https://forum.ada-lang.io/t/using-errno-with-ada/1490/4 "2024-11-20T08:21:12Z")

</div>

First of all it is int.  
Second, a along story, but its short version is that you cannot link to an object. Linux provides a function that returns the address of errno. Use it:

```ada
   function errno return int is
      function errno_location return access int;
      pragma Import (C, errno_location, "__errno_location");
   begin
      return errno_location.all;
   end errno;

```

---

<div class="post-metadata">

### Author: ![Fabien.C](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/fabien.c/32/46_2.png) [@Fabien.C](https://forum.ada-lang.io/u/Fabien.C)
#### Post date: [November 20, 2024, 5:17pm UTC](https://forum.ada-lang.io/t/using-errno-with-ada/1490/5 "2024-11-20T17:17:15Z")

</div>

> [@nerd\_type](#):
>
> I there a good way to read ‘errno’ in Ada?

Use `GNAT.OS_Lib.Errno` and `GNAT.OSLib.Errno_Message`:

```ada
   function Errno return Integer;

   function Errno_Message
     (Err : Integer := Errno;
      Default : String := "") return String;
   -- Return a message describing the given Errno value. If none is provided
   -- by the system, return Default if not empty, else return a generic
   -- message indicating the numeric errno value.

```

---

<div class="post-metadata">

### Author: ![nerd\_type](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/nerd_type/32/530_2.png) [@nerd\_type](https://forum.ada-lang.io/u/nerd_type)
#### Post date: [November 20, 2024, 5:26pm UTC](https://forum.ada-lang.io/t/using-errno-with-ada/1490/6 "2024-11-20T17:26:52Z")

</div>

Thanks for the replies guys!

---

<div class="post-metadata">

### Author: ![mosteo](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/mosteo/32/8_2.png) [@mosteo](https://forum.ada-lang.io/u/mosteo)
#### Post date: [November 22, 2024, 12:46pm UTC](https://forum.ada-lang.io/t/using-errno-with-ada/1490/7 "2024-11-22T12:46:24Z")

</div>

In this case Fabien’s is the simplest, but for the general C case what I do in these cases is to have a simple wrapper function in C that calls whatever complex magic/macro/C++ element is there, so I can safely bind to my C wrapper.

---

<div class="post-metadata">

### Author: ![mgrojo](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/mgrojo/32/15_2.png) [@mgrojo](https://forum.ada-lang.io/u/mgrojo)
#### Post date: [November 22, 2024, 5:58pm UTC](https://forum.ada-lang.io/t/using-errno-with-ada/1490/8 "2024-11-22T17:58:56Z")

</div>

It would be nice to have a tool that detects those macros and generates those simple wrapper functions. That could complement `gcc -fdump-ada-spec` for easily generating bindings to C libraries. In fact, I don’t know why `gcc` couldn’t do that by itself.

---

<div class="post-metadata">

### Author: ![pyj](https://forum.ada-lang.io/user_avatar/forum.ada-lang.io/pyj/32/5_2.png) [@pyj](https://forum.ada-lang.io/u/pyj)
#### Post date: [November 23, 2024, 3:11am UTC](https://forum.ada-lang.io/t/using-errno-with-ada/1490/9 "2024-11-23T03:11:07Z")

</div>

Per [cppreference](https://en.cppreference.com/w/c/error), errno is:

> macro which expands to POSIX-compatible thread-local error number variable

The `errno` in `libc.so.6` here is in thread local storage (TLS):

> [@nerd\_type](#):
>
> ```ada
> /usr/bin/ld: errno: TLS definition in /lib/x86_64-linux-gnu/libc.so.6 section .tbss 
> 
> ```

and your import attempts to find a non-thread local storage version:

> [@nerd\_type](#):
>
> ```ada
> mismatches non-TLS reference in ./test_ioctl.o   
> 
> ```

---

<div class="post-metadata">

### Author: ![Blady](https://forum.ada-lang.io/letter_avatar_proxy/v4/letter/b/e9bcb4/32.png) [@Blady](https://forum.ada-lang.io/u/Blady)
#### Post date: [November 24, 2024, 10:34am UTC](https://forum.ada-lang.io/t/using-errno-with-ada/1490/10 "2024-11-24T10:34:11Z")

</div>

You may also consider POSIX Ada with [Florist](https://github.com/Blady-Com/florist):  
function Get\_Error\_Code return Error\_Code;  
(in generated posix.ads)
