X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=lib%2Fstdio.in.h;h=3ac4b69ad4bdf92ef1ec960c885b2d024f4d33cb;hb=107fb0e6719c49e35a6f4a3bdd0dabb19291efe0;hp=27cd30551260b067b9c6de6ac42689983d8d0451;hpb=c5c46dcc8e875485a2c5d27cce106491fb41400e;p=gnulib.git diff --git a/lib/stdio.in.h b/lib/stdio.in.h index 27cd30551..3ac4b69ad 100644 --- a/lib/stdio.in.h +++ b/lib/stdio.in.h @@ -1,6 +1,6 @@ /* A GNU-like . - Copyright (C) 2004, 2007-2009 Free Software Foundation, Inc. + Copyright (C) 2004, 2007-2010 Free Software Foundation, Inc. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -36,32 +36,30 @@ #ifndef _GL_STDIO_H #define _GL_STDIO_H +/* Get va_list. Needed on many systems, including glibc 2.8. */ #include + #include -#if (@GNULIB_FSEEKO@ && @REPLACE_FSEEKO@) \ - || (@GNULIB_FTELLO@ && @REPLACE_FTELLO@) \ - || (@GNULIB_GETDELIM@ && !@HAVE_DECL_GETDELIM@) \ - || (@GNULIB_GETLINE@ && (!@HAVE_DECL_GETLINE@ || @REPLACE_GETLINE@)) -/* Get off_t and ssize_t. */ -# include -#endif +/* Get off_t and ssize_t. Needed on many systems, including glibc 2.8. */ +#include #ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) -# define __attribute__(Spec) /* empty */ -# endif -/* The __-protected variants of `format' and `printf' attributes - are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ +/* The __attribute__ feature is available in gcc versions 2.5 and later. + The __-protected variants of the attributes 'format' and 'printf' are + accepted by gcc versions 2.6.4 (effectively 2.7) and later. + We enable __attribute__ only if these are supported too, because + gnulib and libintl do '#define printf __printf__' when they override + the 'printf' function. */ # if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -# define __format__ format -# define __printf__ printf +# define __attribute__(Spec) /* empty */ # endif #endif -/* The definition of GL_LINK_WARNING is copied here. */ +/* The definition of _GL_ARG_NONNULL is copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ #ifdef __cplusplus @@ -74,29 +72,27 @@ extern "C" { # endif # if @REPLACE_DPRINTF@ || !@HAVE_DPRINTF@ extern int dprintf (int fd, const char *format, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); + __attribute__ ((__format__ (__printf__, 2, 3))) _GL_ARG_NONNULL ((2)); # endif #elif defined GNULIB_POSIXCHECK # undef dprintf -# define dprintf(d,f,a) \ - (GL_LINK_WARNING ("dprintf is unportable - " \ - "use gnulib module dprintf for portability"), \ - dprintf (d, f, a)) +# if HAVE_RAW_DECL_DPRINTF +_GL_WARN_ON_USE (dprintf, "dprintf is unportable - " + "use gnulib module dprintf for portability"); +# endif #endif #if @GNULIB_FCLOSE@ # if @REPLACE_FCLOSE@ # define fclose rpl_fclose /* Close STREAM and its underlying file descriptor. */ -extern int fclose (FILE *stream); +extern int fclose (FILE *stream) _GL_ARG_NONNULL ((1)); # endif #elif defined GNULIB_POSIXCHECK # undef fclose -# define fclose(f) \ - (GL_LINK_WARNING ("fclose is not always POSIX compliant - " \ - "use gnulib module fclose for portable " \ - "POSIX compliance"), \ - fclose (f)) +/* Assume fclose is always declared. */ +_GL_WARN_ON_USE (fclose, "fclose is not always POSIX compliant - " + "use gnulib module fclose for portable POSIX compliance"); #endif #if @GNULIB_FFLUSH@ @@ -112,44 +108,49 @@ extern int fclose (FILE *stream); # endif #elif defined GNULIB_POSIXCHECK # undef fflush -# define fflush(f) \ - (GL_LINK_WARNING ("fflush is not always POSIX compliant - " \ - "use gnulib module fflush for portable " \ - "POSIX compliance"), \ - fflush (f)) +/* Assume fflush is always declared. */ +_GL_WARN_ON_USE (fflush, "fflush is not always POSIX compliant - " + "use gnulib module fflush for portable POSIX compliance"); #endif +/* It is very rare that the developer ever has full control of stdin, + so any use of gets warrants an unconditional warning. Assume it is + always declared, since it is required by C89. */ +#undef gets +_GL_WARN_ON_USE (gets, "gets is a security hole - use fgets instead"); + #if @GNULIB_FOPEN@ # if @REPLACE_FOPEN@ # undef fopen # define fopen rpl_fopen -extern FILE * fopen (const char *filename, const char *mode); +extern FILE * fopen (const char *filename, const char *mode) + _GL_ARG_NONNULL ((1, 2)); # endif #elif defined GNULIB_POSIXCHECK # undef fopen -# define fopen(f,m) \ - (GL_LINK_WARNING ("fopen on Win32 platforms is not POSIX compatible - " \ - "use gnulib module fopen for portability"), \ - fopen (f, m)) +/* Assume fopen is always declared. */ +_GL_WARN_ON_USE (fopen, "fopen on Win32 platforms is not POSIX compatible - " + "use gnulib module fopen for portability"); #endif #if @GNULIB_FPRINTF_POSIX@ # if @REPLACE_FPRINTF@ # define fprintf rpl_fprintf extern int fprintf (FILE *fp, const char *format, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); + __attribute__ ((__format__ (__printf__, 2, 3))) + _GL_ARG_NONNULL ((1, 2)); # endif #elif @GNULIB_FPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ # define fprintf rpl_fprintf extern int fprintf (FILE *fp, const char *format, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); + __attribute__ ((__format__ (__printf__, 2, 3))) + _GL_ARG_NONNULL ((1, 2)); #elif defined GNULIB_POSIXCHECK # undef fprintf -# define fprintf \ - (GL_LINK_WARNING ("fprintf is not always POSIX compliant - " \ - "use gnulib module fprintf-posix for portable " \ - "POSIX compliance"), \ - fprintf) +/* Assume fprintf is always declared. */ +_GL_WARN_ON_USE (fprintf, "fprintf is not always POSIX compliant - " + "use gnulib module fprintf-posix for portable " + "POSIX compliance"); #endif #if @GNULIB_FPURGE@ @@ -163,124 +164,187 @@ extern int fprintf (FILE *fp, const char *format, ...) was before the write calls. When discarding pending input, the file position is advanced to match the end of the previously read input. Return 0 if successful. Upon error, return -1 and set errno. */ - extern int fpurge (FILE *gl_stream); + extern int fpurge (FILE *gl_stream) _GL_ARG_NONNULL ((1)); # endif #elif defined GNULIB_POSIXCHECK # undef fpurge -# define fpurge(f) \ - (GL_LINK_WARNING ("fpurge is not always present - " \ - "use gnulib module fpurge for portability"), \ - fpurge (f)) +# if HAVE_RAW_DECL_FPURGE +_GL_WARN_ON_USE (fpurge, "fpurge is not always present - " + "use gnulib module fpurge for portability"); +# endif #endif #if @GNULIB_FPUTC@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ # undef fputc # define fputc rpl_fputc -extern int fputc (int c, FILE *stream); +extern int fputc (int c, FILE *stream) _GL_ARG_NONNULL ((2)); #endif #if @GNULIB_FPUTS@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ # undef fputs # define fputs rpl_fputs -extern int fputs (const char *string, FILE *stream); +extern int fputs (const char *string, FILE *stream) _GL_ARG_NONNULL ((1, 2)); #endif #if @GNULIB_FREOPEN@ # if @REPLACE_FREOPEN@ # undef freopen # define freopen rpl_freopen -extern FILE * freopen (const char *filename, const char *mode, FILE *stream); +extern FILE * freopen (const char *filename, const char *mode, FILE *stream) + _GL_ARG_NONNULL ((2, 3)); # endif #elif defined GNULIB_POSIXCHECK # undef freopen -# define freopen(f,m,s) \ - (GL_LINK_WARNING ("freopen on Win32 platforms is not POSIX compatible - " \ - "use gnulib module freopen for portability"), \ - freopen (f, m, s)) -#endif - -#if @GNULIB_FSEEK@ && @REPLACE_FSEEK@ -extern int rpl_fseek (FILE *fp, long offset, int whence); -# undef fseek -# if defined GNULIB_POSIXCHECK -# define fseek(f,o,w) \ - (GL_LINK_WARNING ("fseek cannot handle files larger than 4 GB " \ - "on 32-bit platforms - " \ - "use fseeko function for handling of large files"), \ - rpl_fseek (f, o, w)) -# else +/* Assume freopen is always declared. */ +_GL_WARN_ON_USE (freopen, "freopen on Win32 platforms is not POSIX compatible - " + "use gnulib module freopen for portability"); +#endif + +/* Set up the following warnings, based on which modules are in use. + GNU Coding Standards discourage the use of fseek, since it imposes + an arbitrary limitation on some 32-bit hosts. Remember that the + fseek module depends on the fseeko module, so we only have three + cases to consider: + + 1. The developer is not using either module. Issue a warning under + GNULIB_POSIXCHECK for both functions, to remind them that both + functions have bugs on some systems. _GL_NO_LARGE_FILES has no + impact on this warning. + + 2. The developer is using both modules. They may be unaware of the + arbitrary limitations of fseek, so issue a warning under + GNULIB_POSIXCHECK. On the other hand, they may be using both + modules intentionally, so the developer can define + _GL_NO_LARGE_FILES in the compilation units where the use of fseek + is safe, to silence the warning. + + 3. The developer is using the fseeko module, but not fseek. Gnulib + guarantees that fseek will still work around platform bugs in that + case, but we presume that the developer is aware of the pitfalls of + fseek and was trying to avoid it, so issue a warning even when + GNULIB_POSIXCHECK is undefined. Again, _GL_NO_LARGE_FILES can be + defined to silence the warning in particular compilation units. + + Most gnulib clients that perform stream operations should fall into + category three. */ + +#if @GNULIB_FSEEK@ +# if defined GNULIB_POSIXCHECK && !defined _GL_NO_LARGE_FILES +# define _GL_FSEEK_WARN /* Category 2, above. */ +# undef fseek +# endif +# if @REPLACE_FSEEK@ +# undef fseek # define fseek rpl_fseek -# endif -#elif defined GNULIB_POSIXCHECK -# ifndef fseek -# define fseek(f,o,w) \ - (GL_LINK_WARNING ("fseek cannot handle files larger than 4 GB " \ - "on 32-bit platforms - " \ - "use fseeko function for handling of large files"), \ - fseek (f, o, w)) +extern int fseek (FILE *fp, long offset, int whence) _GL_ARG_NONNULL ((1)); # endif #endif #if @GNULIB_FSEEKO@ +# if !@GNULIB_FSEEK@ && !defined _GL_NO_LARGE_FILES +# define _GL_FSEEK_WARN /* Category 3, above. */ +# undef fseek +# endif # if @REPLACE_FSEEKO@ /* Provide fseek, fseeko functions that are aware of a preceding fflush(), and which detect pipes. */ +# undef fseeko # define fseeko rpl_fseeko -extern int fseeko (FILE *fp, off_t offset, int whence); -# define fseek(fp, offset, whence) fseeko (fp, (off_t)(offset), whence) +extern int fseeko (FILE *fp, off_t offset, int whence) _GL_ARG_NONNULL ((1)); +# if !@GNULIB_FSEEK@ +# undef fseek +# define fseek rpl_fseek +static inline int _GL_ARG_NONNULL ((1)) +rpl_fseek (FILE *fp, long offset, int whence) +{ + return fseeko (fp, offset, whence); +} +# endif # endif #elif defined GNULIB_POSIXCHECK +# define _GL_FSEEK_WARN /* Category 1, above. */ +# undef fseek # undef fseeko -# define fseeko(f,o,w) \ - (GL_LINK_WARNING ("fseeko is unportable - " \ - "use gnulib module fseeko for portability"), \ - fseeko (f, o, w)) +# if HAVE_RAW_DECL_FSEEKO +_GL_WARN_ON_USE (fseeko, "fseeko is unportable - " + "use gnulib module fseeko for portability"); +# endif #endif -#if @GNULIB_FTELL@ && @REPLACE_FTELL@ -extern long rpl_ftell (FILE *fp); -# undef ftell -# if GNULIB_POSIXCHECK -# define ftell(f) \ - (GL_LINK_WARNING ("ftell cannot handle files larger than 4 GB " \ - "on 32-bit platforms - " \ - "use ftello function for handling of large files"), \ - rpl_ftell (f)) -# else -# define ftell rpl_ftell +#ifdef _GL_FSEEK_WARN +# undef _GL_FSEEK_WARN +/* Here, either fseek is undefined (but C89 guarantees that it is + declared), or it is defined as rpl_fseek (declared above). */ +_GL_WARN_ON_USE (fseek, "fseek cannot handle files larger than 4 GB " + "on 32-bit platforms - " + "use fseeko function for handling of large files"); +#endif + +/* See the comments on fseek/fseeko. */ + +#if @GNULIB_FTELL@ +# if defined GNULIB_POSIXCHECK && !defined _GL_NO_LARGE_FILES +# define _GL_FTELL_WARN /* Category 2, above. */ +# undef ftell # endif -#elif defined GNULIB_POSIXCHECK -# ifndef ftell -# define ftell(f) \ - (GL_LINK_WARNING ("ftell cannot handle files larger than 4 GB " \ - "on 32-bit platforms - " \ - "use ftello function for handling of large files"), \ - ftell (f)) +# if @REPLACE_FTELL@ +# undef ftell +# define ftell rpl_ftell +extern long ftell (FILE *fp) _GL_ARG_NONNULL ((1)); # endif #endif #if @GNULIB_FTELLO@ +# if !@GNULIB_FTELL@ && !defined _GL_NO_LARGE_FILES +# define _GL_FTELL_WARN /* Category 3, above. */ +# undef ftell +# endif # if @REPLACE_FTELLO@ +# undef ftello # define ftello rpl_ftello -extern off_t ftello (FILE *fp); -# define ftell(fp) ftello (fp) +extern off_t ftello (FILE *fp) _GL_ARG_NONNULL ((1)); +# if !@GNULIB_FTELL@ +# undef ftell +# define ftell rpl_ftell +static inline long _GL_ARG_NONNULL ((1)) +rpl_ftell (FILE *f) +{ + return ftello (f); +} +# endif # endif #elif defined GNULIB_POSIXCHECK +# define _GL_FTELL_WARN /* Category 1, above. */ +# undef ftell # undef ftello -# define ftello(f) \ - (GL_LINK_WARNING ("ftello is unportable - " \ - "use gnulib module ftello for portability"), \ - ftello (f)) +# if HAVE_RAW_DECL_FTELLO +_GL_WARN_ON_USE (ftello, "ftello is unportable - " + "use gnulib module ftello for portability"); +# endif +#endif + +#ifdef _GL_FTELL_WARN +# undef _GL_FTELL_WARN +/* Here, either ftell is undefined (but C89 guarantees that it is + declared), or it is defined as rpl_ftell (declared above). */ +_GL_WARN_ON_USE (ftell, "ftell cannot handle files larger than 4 GB " + "on 32-bit platforms - " + "use ftello function for handling of large files"); #endif #if @GNULIB_FWRITE@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ # undef fwrite # define fwrite rpl_fwrite -extern size_t fwrite (const void *ptr, size_t s, size_t n, FILE *stream); +extern size_t fwrite (const void *ptr, size_t s, size_t n, FILE *stream) + _GL_ARG_NONNULL ((1, 4)); #endif #if @GNULIB_GETDELIM@ -# if !@HAVE_DECL_GETDELIM@ +# if @REPLACE_GETDELIM@ +# undef getdelim +# define getdelim rpl_getdelim +# endif +# if !@HAVE_DECL_GETDELIM@ || @REPLACE_GETDELIM@ /* Read input, up to (and including) the next occurrence of DELIMITER, from STREAM, store it in *LINEPTR (and NUL-terminate it). *LINEPTR is a pointer returned from malloc (or NULL), pointing to *LINESIZE @@ -288,14 +352,15 @@ extern size_t fwrite (const void *ptr, size_t s, size_t n, FILE *stream); Return the number of bytes read and stored at *LINEPTR (not including the NUL terminator), or -1 on error or EOF. */ extern ssize_t getdelim (char **lineptr, size_t *linesize, int delimiter, - FILE *stream); + FILE *stream) + _GL_ARG_NONNULL ((1, 2, 4)); # endif #elif defined GNULIB_POSIXCHECK # undef getdelim -# define getdelim(l, s, d, f) \ - (GL_LINK_WARNING ("getdelim is unportable - " \ - "use gnulib module getdelim for portability"), \ - getdelim (l, s, d, f)) +# if HAVE_RAW_DECL_GETDELIM +_GL_WARN_ON_USE (getdelim, "getdelim is unportable - " + "use gnulib module getdelim for portability"); +# endif #endif #if @GNULIB_GETLINE@ @@ -310,14 +375,15 @@ extern ssize_t getdelim (char **lineptr, size_t *linesize, int delimiter, bytes of space. It is realloc'd as necessary. Return the number of bytes read and stored at *LINEPTR (not including the NUL terminator), or -1 on error or EOF. */ -extern ssize_t getline (char **lineptr, size_t *linesize, FILE *stream); +extern ssize_t getline (char **lineptr, size_t *linesize, FILE *stream) + _GL_ARG_NONNULL ((1, 2, 3)); # endif #elif defined GNULIB_POSIXCHECK # undef getline -# define getline(l, s, f) \ - (GL_LINK_WARNING ("getline is unportable - " \ - "use gnulib module getline for portability"), \ - getline (l, s, f)) +# if HAVE_RAW_DECL_GETLINE +_GL_WARN_ON_USE (getline, "getline is unportable - " + "use gnulib module getline for portability"); +# endif #endif #if @GNULIB_OBSTACK_PRINTF@ @@ -333,10 +399,10 @@ extern ssize_t getline (char **lineptr, size_t *linesize, FILE *stream); memory allocation error, call obstack_alloc_failed_handler. Upon other error, return -1. */ extern int obstack_printf (struct obstack *obs, const char *format, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); + __attribute__ ((__format__ (__printf__, 2, 3))) _GL_ARG_NONNULL ((1, 2)); extern int obstack_vprintf (struct obstack *obs, const char *format, - va_list args) - __attribute__ ((__format__ (__printf__, 2, 0))); + va_list args) + __attribute__ ((__format__ (__printf__, 2, 0))) _GL_ARG_NONNULL ((1, 2)); # endif #endif @@ -350,24 +416,24 @@ extern void perror (const char *string); # endif #elif defined GNULIB_POSIXCHECK # undef perror -# define perror(s) \ - (GL_LINK_WARNING ("perror is not always POSIX compliant - " \ - "use gnulib module perror for portability"), \ - perror (s)) +/* Assume perror is always declared. */ +_GL_WARN_ON_USE (perror, "perror is not always POSIX compliant - " + "use gnulib module perror for portability"); #endif #if @GNULIB_POPEN@ # if @REPLACE_POPEN@ # undef popen # define popen rpl_popen -extern FILE *popen (const char *cmd, const char *mode); +extern FILE *popen (const char *cmd, const char *mode) + _GL_ARG_NONNULL ((1, 2)); # endif #elif defined GNULIB_POSIXCHECK # undef popen -# define popen(c,m) \ - (GL_LINK_WARNING ("popen is buggy on some platforms - " \ - "use gnulib module popen or pipe for more portability"), \ - popen (c, m)) +# if HAVE_RAW_DECL_POPEN +_GL_WARN_ON_USE (popen, "popen is buggy on some platforms - " + "use gnulib module popen or pipe for more portability"); +# endif #endif #if @GNULIB_PRINTF_POSIX@ @@ -375,33 +441,25 @@ extern FILE *popen (const char *cmd, const char *mode); /* Don't break __attribute__((format(printf,M,N))). */ # define printf __printf__ extern int printf (const char *format, ...) - __attribute__ ((__format__ (__printf__, 1, 2))); + __attribute__ ((__format__ (__printf__, 1, 2))) _GL_ARG_NONNULL ((1)); # endif #elif @GNULIB_PRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ /* Don't break __attribute__((format(printf,M,N))). */ # define printf __printf__ extern int printf (const char *format, ...) - __attribute__ ((__format__ (__printf__, 1, 2))); + __attribute__ ((__format__ (__printf__, 1, 2))) _GL_ARG_NONNULL ((1)); #elif defined GNULIB_POSIXCHECK # undef printf -# define printf \ - (GL_LINK_WARNING ("printf is not always POSIX compliant - " \ - "use gnulib module printf-posix for portable " \ - "POSIX compliance"), \ - printf) -/* Don't break __attribute__((format(printf,M,N))). */ -# define format(kind,m,n) format (__##kind##__, m, n) -# define __format__(kind,m,n) __format__ (__##kind##__, m, n) -# define ____printf____ __printf__ -# define ____scanf____ __scanf__ -# define ____strftime____ __strftime__ -# define ____strfmon____ __strfmon__ +/* Assume printf is always declared. */ +_GL_WARN_ON_USE (printf, "printf is not always POSIX compliant - " + "use gnulib module printf-posix for portable " + "POSIX compliance"); #endif #if @GNULIB_PUTC@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ # undef putc # define putc rpl_fputc -extern int putc (int c, FILE *stream); +extern int putc (int c, FILE *stream) _GL_ARG_NONNULL ((2)); #endif #if @GNULIB_PUTCHAR@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ @@ -413,21 +471,51 @@ extern int putchar (int c); #if @GNULIB_PUTS@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ # undef puts # define puts rpl_puts -extern int puts (const char *string); +extern int puts (const char *string) _GL_ARG_NONNULL ((1)); +#endif + +#if @GNULIB_REMOVE@ +# if @REPLACE_REMOVE@ +# undef remove +# define remove rpl_remove +extern int remove (const char *name) _GL_ARG_NONNULL ((1)); +# endif +#elif defined GNULIB_POSIXCHECK +# undef remove +/* Assume remove is always declared. */ +_GL_WARN_ON_USE (remove, "remove cannot handle directories on some platforms - " + "use gnulib module remove for more portability"); #endif #if @GNULIB_RENAME@ # if @REPLACE_RENAME@ # undef rename # define rename rpl_rename -extern int rename (const char *old, const char *new); +extern int rename (const char *old_filename, const char *new_filename) + _GL_ARG_NONNULL ((1, 2)); # endif #elif defined GNULIB_POSIXCHECK # undef rename -# define rename(o,n) \ - (GL_LINK_WARNING ("rename is buggy on some platforms - " \ - "use gnulib module rename for more portability"), \ - rename (o, n)) +/* Assume rename is always declared. */ +_GL_WARN_ON_USE (rename, "rename is buggy on some platforms - " + "use gnulib module rename for more portability"); +#endif + +#if @GNULIB_RENAMEAT@ +# if @REPLACE_RENAMEAT@ +# undef renameat +# define renameat rpl_renameat +# endif +# if !@HAVE_RENAMEAT@ || @REPLACE_RENAMEAT@ +extern int renameat (int fd1, char const *file1, int fd2, char const *file2) + _GL_ARG_NONNULL ((2, 4)); +# endif +#elif defined GNULIB_POSIXCHECK +# undef renameat +# if HAVE_RAW_DECL_RENAMEAT +_GL_WARN_ON_USE (renameat, "renameat is not portable - " + "use gnulib module renameat for portability"); +# endif #endif #if @GNULIB_SNPRINTF@ @@ -436,29 +524,39 @@ extern int rename (const char *old, const char *new); # endif # if @REPLACE_SNPRINTF@ || !@HAVE_DECL_SNPRINTF@ extern int snprintf (char *str, size_t size, const char *format, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); + __attribute__ ((__format__ (__printf__, 3, 4))) + _GL_ARG_NONNULL ((3)); # endif #elif defined GNULIB_POSIXCHECK # undef snprintf -# define snprintf \ - (GL_LINK_WARNING ("snprintf is unportable - " \ - "use gnulib module snprintf for portability"), \ - snprintf) +# if HAVE_RAW_DECL_SNPRINTF +_GL_WARN_ON_USE (snprintf, "snprintf is unportable - " + "use gnulib module snprintf for portability"); +# endif #endif +/* Some people would argue that sprintf should be handled like gets + (for example, OpenBSD issues a link warning for both functions), + since both can cause security holes due to buffer overruns. + However, we believe that sprintf can be used safely, and is more + efficient than snprintf in those safe cases; and as proof of our + belief, we use sprintf in several gnulib modules. So this header + intentionally avoids adding a warning to sprintf except when + GNULIB_POSIXCHECK is defined. */ + #if @GNULIB_SPRINTF_POSIX@ # if @REPLACE_SPRINTF@ # define sprintf rpl_sprintf extern int sprintf (char *str, const char *format, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); + __attribute__ ((__format__ (__printf__, 2, 3))) + _GL_ARG_NONNULL ((1, 2)); # endif #elif defined GNULIB_POSIXCHECK # undef sprintf -# define sprintf \ - (GL_LINK_WARNING ("sprintf is not always POSIX compliant - " \ - "use gnulib module sprintf-posix for portable " \ - "POSIX compliance"), \ - sprintf) +/* Assume sprintf is always declared. */ +_GL_WARN_ON_USE (sprintf, "sprintf is not always POSIX compliant - " + "use gnulib module sprintf-posix for portable " + "POSIX compliance"); #endif #if @GNULIB_VASPRINTF@ @@ -472,9 +570,9 @@ extern int sprintf (char *str, const char *format, ...) *RESULT and return the number of resulting bytes, excluding the trailing NUL. Upon memory allocation error, or some other error, return -1. */ extern int asprintf (char **result, const char *format, ...) - __attribute__ ((__format__ (__printf__, 2, 3))); + __attribute__ ((__format__ (__printf__, 2, 3))) _GL_ARG_NONNULL ((1, 2)); extern int vasprintf (char **result, const char *format, va_list args) - __attribute__ ((__format__ (__printf__, 2, 0))); + __attribute__ ((__format__ (__printf__, 2, 0))) _GL_ARG_NONNULL ((1, 2)); # endif #endif @@ -484,52 +582,52 @@ extern int sprintf (char *str, const char *format, ...) # endif # if @REPLACE_VDPRINTF@ || !@HAVE_VDPRINTF@ extern int vdprintf (int fd, const char *format, va_list args) - __attribute__ ((__format__ (__printf__, 2, 0))); + __attribute__ ((__format__ (__printf__, 2, 0))) _GL_ARG_NONNULL ((2)); # endif #elif defined GNULIB_POSIXCHECK # undef vdprintf -# define vdprintf(d,f,a) \ - (GL_LINK_WARNING ("vdprintf is unportable - " \ - "use gnulib module vdprintf for portability"), \ - vdprintf (d, f, a)) +# if HAVE_RAW_DECL_VDPRINTF +_GL_WARN_ON_USE (vdprintf, "vdprintf is unportable - " + "use gnulib module vdprintf for portability"); +# endif #endif #if @GNULIB_VFPRINTF_POSIX@ # if @REPLACE_VFPRINTF@ # define vfprintf rpl_vfprintf extern int vfprintf (FILE *fp, const char *format, va_list args) - __attribute__ ((__format__ (__printf__, 2, 0))); + __attribute__ ((__format__ (__printf__, 2, 0))) + _GL_ARG_NONNULL ((1, 2)); # endif #elif @GNULIB_VFPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ # define vfprintf rpl_vfprintf extern int vfprintf (FILE *fp, const char *format, va_list args) - __attribute__ ((__format__ (__printf__, 2, 0))); + __attribute__ ((__format__ (__printf__, 2, 0))) + _GL_ARG_NONNULL ((1, 2)); #elif defined GNULIB_POSIXCHECK # undef vfprintf -# define vfprintf(s,f,a) \ - (GL_LINK_WARNING ("vfprintf is not always POSIX compliant - " \ - "use gnulib module vfprintf-posix for portable " \ - "POSIX compliance"), \ - vfprintf (s, f, a)) +/* Assume vfprintf is always declared. */ +_GL_WARN_ON_USE (vfprintf, "vfprintf is not always POSIX compliant - " + "use gnulib module vfprintf-posix for portable " + "POSIX compliance"); #endif #if @GNULIB_VPRINTF_POSIX@ # if @REPLACE_VPRINTF@ # define vprintf rpl_vprintf extern int vprintf (const char *format, va_list args) - __attribute__ ((__format__ (__printf__, 1, 0))); + __attribute__ ((__format__ (__printf__, 1, 0))) _GL_ARG_NONNULL ((1)); # endif #elif @GNULIB_VPRINTF@ && @REPLACE_STDIO_WRITE_FUNCS@ && @GNULIB_STDIO_H_SIGPIPE@ # define vprintf rpl_vprintf extern int vprintf (const char *format, va_list args) - __attribute__ ((__format__ (__printf__, 1, 0))); + __attribute__ ((__format__ (__printf__, 1, 0))) _GL_ARG_NONNULL ((1)); #elif defined GNULIB_POSIXCHECK # undef vprintf -# define vprintf(f,a) \ - (GL_LINK_WARNING ("vprintf is not always POSIX compliant - " \ - "use gnulib module vprintf-posix for portable " \ - "POSIX compliance"), \ - vprintf (f, a)) +/* Assume vprintf is always declared. */ +_GL_WARN_ON_USE (vprintf, "vprintf is not always POSIX compliant - " + "use gnulib module vprintf-posix for portable " + "POSIX compliance"); #endif #if @GNULIB_VSNPRINTF@ @@ -538,29 +636,30 @@ extern int vprintf (const char *format, va_list args) # endif # if @REPLACE_VSNPRINTF@ || !@HAVE_DECL_VSNPRINTF@ extern int vsnprintf (char *str, size_t size, const char *format, va_list args) - __attribute__ ((__format__ (__printf__, 3, 0))); + __attribute__ ((__format__ (__printf__, 3, 0))) + _GL_ARG_NONNULL ((3)); # endif #elif defined GNULIB_POSIXCHECK # undef vsnprintf -# define vsnprintf(b,s,f,a) \ - (GL_LINK_WARNING ("vsnprintf is unportable - " \ - "use gnulib module vsnprintf for portability"), \ - vsnprintf (b, s, f, a)) +# if HAVE_RAW_DECL_VSNPRINTF +_GL_WARN_ON_USE (vsnprintf, "vsnprintf is unportable - " + "use gnulib module vsnprintf for portability"); +# endif #endif #if @GNULIB_VSPRINTF_POSIX@ # if @REPLACE_VSPRINTF@ # define vsprintf rpl_vsprintf extern int vsprintf (char *str, const char *format, va_list args) - __attribute__ ((__format__ (__printf__, 2, 0))); + __attribute__ ((__format__ (__printf__, 2, 0))) + _GL_ARG_NONNULL ((1, 2)); # endif #elif defined GNULIB_POSIXCHECK # undef vsprintf -# define vsprintf(b,f,a) \ - (GL_LINK_WARNING ("vsprintf is not always POSIX compliant - " \ - "use gnulib module vsprintf-posix for portable " \ - "POSIX compliance"), \ - vsprintf (b, f, a)) +/* Assume vsprintf is always declared. */ +_GL_WARN_ON_USE (vsprintf, "vsprintf is not always POSIX compliant - " + "use gnulib module vsprintf-posix for portable " + "POSIX compliance"); #endif #ifdef __cplusplus