From owner-freebsd-hackers@freebsd.org Mon May 21 13:43:22 2018 Return-Path: Delivered-To: freebsd-hackers@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id D555CEF1574 for ; Mon, 21 May 2018 13:43:21 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from kib.kiev.ua (kib.kiev.ua [IPv6:2001:470:d5e7:1::1]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client did not present a certificate) by mx1.freebsd.org (Postfix) with ESMTPS id 521867E366; Mon, 21 May 2018 13:43:21 +0000 (UTC) (envelope-from kostikbel@gmail.com) Received: from tom.home (kib@localhost [127.0.0.1]) by kib.kiev.ua (8.15.2/8.15.2) with ESMTPS id w4LDh68r063214 (version=TLSv1.2 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO); Mon, 21 May 2018 16:43:09 +0300 (EEST) (envelope-from kostikbel@gmail.com) DKIM-Filter: OpenDKIM Filter v2.10.3 kib.kiev.ua w4LDh68r063214 Received: (from kostik@localhost) by tom.home (8.15.2/8.15.2/Submit) id w4LDh6iC063213; Mon, 21 May 2018 16:43:06 +0300 (EEST) (envelope-from kostikbel@gmail.com) X-Authentication-Warning: tom.home: kostik set sender to kostikbel@gmail.com using -f Date: Mon, 21 May 2018 16:43:06 +0300 From: Konstantin Belousov To: Dimitry Andric Cc: Thomas Munro , freebsd-hackers@freebsd.org Subject: Re: printf("%m") doesn't generate a warning -- shouldn't it? Message-ID: <20180521134306.GT6887@kib.kiev.ua> References: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.9.5 (2018-04-13) X-Spam-Status: No, score=-2.0 required=5.0 tests=ALL_TRUSTED,BAYES_00, DKIM_ADSP_CUSTOM_MED,FREEMAIL_FROM,NML_ADSP_CUSTOM_MED autolearn=no autolearn_force=no version=3.4.1 X-Spam-Checker-Version: SpamAssassin 3.4.1 (2015-04-28) on tom.home X-BeenThere: freebsd-hackers@freebsd.org X-Mailman-Version: 2.1.26 Precedence: list List-Id: Technical Discussions relating to FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 21 May 2018 13:43:22 -0000 On Mon, May 21, 2018 at 01:19:01PM +0200, Dimitry Andric wrote: > On 21 May 2018, at 04:38, Thomas Munro wrote: > > > > As discussed on the PostgreSQL[1] and NetBSD mailing lists[2][3], > > syslog-like printf("%m") is a GNU extension that doesn't generate a > > warning from Clang or GCC on other operating systems even though when > > it doesn't actually work. That's because the __printf__ attribute > > that our __printflike macro in /usr/include/stdio.h expands to > > effectively means "like printf in glibc, allowing %m", not like POSIX > > or our actual libc which just prints out "m" when it sees it. > > > > It'd sure be nice to get a compiler warning on FreeBSD when porting > > software that uses that if it doesn't actually work (or ... to support > > it). > > Please submit upstream bug(s) for clang and gcc. It turns out clang has > a -Wformat-non-iso warning flag which should warn about this, but I > can't get it to emit it: > > $ cat printf-m.c > #include > > int main(void) > { > printf("error: %m\n"); > return 0; > } > > $ clang -std=c99 -Wformat-non-iso -c printf-m.c > Why not add %m instead ? It is very easy and several people did it in round-about ways. diff --git a/lib/libc/stdio/vfprintf.c b/lib/libc/stdio/vfprintf.c index 29fbd95b399..70f5074e2f7 100644 --- a/lib/libc/stdio/vfprintf.c +++ b/lib/libc/stdio/vfprintf.c @@ -317,6 +317,7 @@ __vfprintf(FILE *fp, locale_t locale, const char *fmt0, va_list ap) int ret; /* return value accumulator */ int width; /* width from format (%8d), or 0 */ int prec; /* precision from format; <0 for N/A */ + int saved_errno; char sign; /* sign prefix (' ', '+', '-', or \0) */ struct grouping_state gs; /* thousands' grouping info */ @@ -466,6 +467,7 @@ __vfprintf(FILE *fp, locale_t locale, const char *fmt0, va_list ap) savserr = fp->_flags & __SERR; fp->_flags &= ~__SERR; + saved_errno = errno; convbuf = NULL; fmt = (char *)fmt0; argtable = NULL; @@ -776,6 +778,11 @@ reswitch: switch (ch) { } break; #endif /* !NO_FLOATING_POINT */ + case 'm': + cp = strerror(saved_errno); + size = (prec >= 0) ? strnlen(cp, prec) : strlen(cp); + sign = '\0'; + break; case 'n': /* * Assignment-like behavior is specified if the