From owner-freebsd-current@FreeBSD.ORG Mon Jan 24 18:04:22 2005 Return-Path: Delivered-To: freebsd-current@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id DBC0916A4CE; Mon, 24 Jan 2005 18:04:21 +0000 (GMT) Received: from mail.dt.e-technik.uni-dortmund.de (mail.dt.e-technik.Uni-Dortmund.DE [129.217.163.1]) by mx1.FreeBSD.org (Postfix) with ESMTP id B105A43D49; Mon, 24 Jan 2005 18:04:20 +0000 (GMT) (envelope-from matthias.andree@gmx.de) Received: from localhost (localhost [127.0.0.1])C8B7144234; Mon, 24 Jan 2005 19:04:19 +0100 (CET) Received: from mail.dt.e-technik.uni-dortmund.de ([127.0.0.1]) by localhost (krusty [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 19276-04; Mon, 24 Jan 2005 19:04:15 +0100 (CET) Received: from m2a2.dyndns.org (pD9FFB2CD.dip.t-dialin.net [217.255.178.205]) BAC0F44232; Mon, 24 Jan 2005 19:04:14 +0100 (CET) Received: from localhost (localhost [127.0.0.1]) by merlin.emma.line.org (Postfix) with ESMTP id B7CC477E21; Mon, 24 Jan 2005 19:04:13 +0100 (CET) Received: from merlin.emma.line.org ([127.0.0.1]) by localhost (m2a2.dyndns.org [127.0.0.1]) (amavisd-new, port 10024) with LMTP id 12555-04; Mon, 24 Jan 2005 19:04:12 +0100 (CET) Received: by merlin.emma.line.org (Postfix, from userid 500) id D282877E27; Mon, 24 Jan 2005 19:04:12 +0100 (CET) From: Matthias Andree To: Joerg Wunsch In-Reply-To: <20050123224755.GK30862@uriah.heep.sax.de> (Joerg Wunsch's message of "Sun, 23 Jan 2005 23:47:55 +0100") References: <20050120205501.GA69123@nagual.pp.ru> <20050120211449.GC30862@uriah.heep.sax.de> <20050120214406.GA70088@nagual.pp.ru> <20050120222137.GE30862@uriah.heep.sax.de> <20050121230949.GA34313@VARK.MIT.EDU> <20050122113015.GV30862@uriah.heep.sax.de> <20050122171743.GB39943@nagual.pp.ru> <20050123143024.GA28604@gothmog.gr> <20050123211656.GB64754@nagual.pp.ru> <20050123221630.GB22234@gothmog.gr> <20050123224755.GK30862@uriah.heep.sax.de> Date: Mon, 24 Jan 2005 19:04:12 +0100 Message-ID: User-Agent: Gnus/5.110003 (No Gnus v0.3) Emacs/21.3 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii X-Virus-Scanned: by amavisd-new at dt.e-technik.uni-dortmund.de X-Mailman-Approved-At: Tue, 25 Jan 2005 12:50:55 +0000 cc: Andrey Chernov cc: Giorgos Keramidas cc: current@freebsd.org Subject: Re: Implementation errors in strtol() X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 24 Jan 2005 18:04:22 -0000 Joerg Wunsch writes: > However, this immediately reminded me of Steinbach's Guideline for > System Programming. ;-) (-> fortune -m Steinbach) If a function be advertised to return an error code in the event of difficulties, thou shalt check for that code, yea, even though the checks triple the size of thy code and produce aches in thy typing fingers, for if thou thinkest "it cannot happen to me", the gods shall surely punish thee for thy arrogance. -- Henry Spencer, The Ten Commandments for C Programmers > At least according to C99/Posix/SUSP, once you've caught conversion > errors (by means of looking whether endptr had been advanced), and if > you are sure that base had a legitimate value (as it is probably a > hardcoded value in almost any practical application of strto*l), the > only legitimate errno value remaining is ERANGE, as after a valid > conversion and with a correct base value, there's no chance for EINVAL > anymore. The whole churn of this discussion can easily be fixed by a function with a BSD license and a decent interface. Outline: /* returns true for success (putting output in *var), false for error */ int get_long(const char *in, long *var, int base) char *e; errno = 0; var = strtol(in, &e, base); if (e == in) return 0; if ((*var == LONG_MIN || *var == LONG_MAX) && errno == ERANGE) return 0; return 1; } I hope this covers everything. No, it does not expose e, that's left as an exercise to the reader... > Sure, you can check whether errno != 0 && errno != ERANGE, but see > Steinbach, what to do in that case? abort() ;-) _Exit() to go out of the way of signals :-P -- Matthias Andree