Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 24 Jan 2005 19:04:12 +0100
From:      Matthias Andree <matthias.andree@gmx.de>
To:        Joerg Wunsch <joerg_wunsch@uriah.heep.sax.de>
Cc:        current@freebsd.org
Subject:   Re: Implementation errors in strtol()
Message-ID:  <m34qh6g0v7.fsf@merlin.emma.line.org>
In-Reply-To: <20050123224755.GK30862@uriah.heep.sax.de> (Joerg Wunsch's message of "Sun, 23 Jan 2005 23:47:55 %2B0100")
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>

next in thread | previous in thread | raw e-mail | index | archive | help
Joerg Wunsch <j@uriah.heep.sax.de> 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



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?m34qh6g0v7.fsf>