Cross platform compatibility dprintf

Linux has this nice feature dprintf:

The functions dprintf()and vdprintf()(as indicated in the glibc2 library) are exact counterparts fprintf()and vfprintf(), except that they are output to the file descriptor fd instead of the specified stream.

however, as the same source indicates:

These functions are extensions to GNU, not C or POSIX. It is understood that the names were poorly chosen. Many systems (e.g. MacOS) have incompatible functions called dprintf(), usually some debug versions printf(), possibly with a prototype like

void dprintf (int level, const char *format, ...);

where the first parameter is the debugging level (and the output is - stderr). Moreover, dprintf()(or dprintf) is also a popular macro name for debugging printf. Therefore, it is probably best to avoid this feature in programs designed for portability.

My question

How can I make a setting that will safely call dprintfwhich I want if it exists, or not compile with some reasonable reasonable error message if this function does not exist? I think I would do something like this:

#ifdef SOMETHING
    #define Dprintf dprintf
#else
    #error "no dprintf"
#endif

but I do not know what should be SOMETHING. I think I could limit it to Linux only, but can I make it more free?

+3
source share
4

, dprintf() POSIX.1-2008 ( , ), :

#if !defined(__GLIBC__) && _POSIX_C_SOURCE < 200809
#error "dprintf may not exist, or may be wrong"
#endif

__GLIBC__ , gnu. , , .

+9

autoconf, autotools .

AC_LANG([C])
AC_USE_SYSTEM_EXTENSIONS
AC_ARG_WITH([dprintf],
  [AS_HELP_STRING([--with-dprintf],
    [Assume that dprintf prints to a specified file descriptor])],
  [], [with_dprintf=check])
AS_IF([test "x$with_dprintf" = xcheck],
  [AC_RUN_IFELSE(
    [AC_LANG_PROGRAM([[
        #include <stdio.h>
        #include <string.h>
        int debug_level;
      ]], [[
        char msg[] = "Hello, world!\n";
        char rcv[sizeof(msg)] = "";
        FILE *f = tmpfile();
        int fd = fileno(f);
        debug_level = fd - 1;
        dprintf(fd, "%s", msg);
        fseek(f, 0, SEEK_SET);
        fread(rcv, 1, sizeof(msg), f);
        return strcmp(msg, rcv);
      ]]
    )], [with_dprintf=yes])])
AS_IF([test "x$with_dprintf" = xyes],
  [AC_DEFINE([HAVE_DPRINTF], [1],
    [dprintf prints to a specified file descriptor])])

( --with-dprintf --without-dprintf -, AC_RUN_IFELSE .)


fdopen C, POSIX.2 . - UNIX-, - , Windows .

int fdprintf(int fd, char *fmt, ...) {
    va_list ap;
    FILE *f = fdopen(fd);
    int rc;

    va_start(ap, &fmt);
    rc = vfprintf(f, fmt, ap);
    fclose(f);
    va_end(ap);
    return rc;
}

, , , FILE*.

+3

Autoconf , dprintf(1, "blablabla") stdout stderr, dprintf(-1, "blablabla") stderr.

libc dprintf(), snprintf() ( asprintf()) write(). dprintf.o , libc's.

, fdprintf().

+2

dmcer, , .

0

Source: https://habr.com/ru/post/1729473/


All Articles