7

I'm on Ubuntu 10.04 using GCC and I want to use the macro TEMP_FAILURE_RETRY as described here:

http://www.gnu.org/s/hello/manual/libc/Interrupted-Primitives.html

However, when I compile I got the following error:

undefined reference to `TEMP_FAILURE_RETRY'

I looked in unistd.h where the macro is defined and it is preceded by:

#ifdef __USE_GNU

How do I get my code to compile and use this macro? Can I simply wrap it using the same #ifdef __USE_GNU in my code?

SlappyTheFish
  • 2,344
  • 3
  • 34
  • 41

2 Answers2

8

__USE_GNU is an internal macro, so you shouldn't define it yourself.

But you may define _GNU_SOURCE, either in your code, or when compiling (using the -D option).

I think defining this one will help to make TEMP_FAILURE_RETRY available.

Macmade
  • 52,708
  • 13
  • 106
  • 123
  • Ok, so I just need to define _GNU_SOURCE to a value? But that would make it dependent on GNU, is there any way to make my code use the macro if it's available at compile time but compile without it if not? – SlappyTheFish Nov 28 '11 at 21:34
  • If using Ubuntu, I guess you can be sure that GNU will be used, so you can safely define it... – Macmade Nov 28 '11 at 21:41
  • Ok, but ideally I'd like the code to be portable, at least to all flavours of Linux. – SlappyTheFish Nov 28 '11 at 21:43
  • 6
    `#define _GNU_SOURCE 1` is the canonical form. It needs to be above *all* system headers or it won't work. If you want portability, though, define your own wrapper macro; `TEMP_FAILURE_RETRY` is a GNU libc extension that AFAIK is not available from any other C library, including the common alternatives on Linux (uclibc, klibc, whatever Android has, ...) – zwol Nov 28 '11 at 21:54
  • Note that `#include ` is required to define `TEMP_FAILURE_RETRY` as well (after defining `_GNU_SOURCE`). – Robie Basak Apr 16 '15 at 05:50
1

Using _GNU_SOURCE may have implications for portability of the code, it brings in a lot of other stuff besides TEMP_FAILURE_RETRY. If you only need the functionality of TEMP_FAILURE_RETRY, you may as well define similar macro yourself, here's a standard C version that doesn't use any GNU extensions:

#define CALL_RETRY(retvar, expression) do { \
    retvar = (expression); \
} while (retvar == -1 && errno == EINTR);

where in retvar you pass the name of a variable where you want the return value stored.

kralyk
  • 4,249
  • 1
  • 32
  • 34