Safe coding practices (was Re: Bug in users command)

Dan Bernstein brnstnd at kramden.acf.nyu.edu
Fri Jan 25 13:34:11 AEST 1991


Ah, yes, Jef takes his place next to Chris on my list of gurus I've
caught in a mistake. Two mistakes, in fact. Read on...

In article <22870 at well.sf.ca.us> Jef Poskanzer <jef at well.sf.ca.us> writes:
> I think this is an *excellent* example of appropriate programming
> technology.  Dan Bernstein's hack of reading utmp twice and allocating
> 50 extra slots in case more users log in between the two is, when you
> come down to it, *no better*.

I address this below. You aren't thinking things through. My program
would be objectively better than yours even if it allocated *zero* extra
slots for users who log in after the first read.

> Just more complicated.  Worse, in fact,
> since he *doesn't* check for overflow.

I do check for overflow. See that test for i < lines + 50?

Jef, I expect an apology. I appreciate criticism of my code,
particularly when it gives me better insight into what people are
looking for. But I don't appreciate someone trying to excuse his
programming mistakes by saying ``Dan's code fucks up too'' when, in
fact, my code works exactly as it's supposed to.

Before this, I thought you were the type who would give constructive
criticism---things like ``You should've cast back and forth to char * or
void * at the qsort() interface.'' Not false accusations that show you
hardly even pay attention to what you're talking about.

> He complained about a hard
> limit of 200 users and then

Actually, my main project for last May was writing pty 3.0 from scratch,
including the PD utilities (like u.c, who.c, etc.) that come with the
package. So don't think I'm complaining about a problem without already
having tried to fix it.

> went and programmed a different hard limit
> of 50 new users in an unknowable time period.

You are wrong. You're correctly reporting the limit I coded, but you
said above that this behavior is no better than your fixed limit. In
that statement you are wrong.

I won't go into a long treatise about the principles of taking
snapshots of a dynamic system. But here are the two most important
properties of ``foo'', a utmp scanner: 1. foo reports a user only if he
is logged on at some point between when foo is invoked and when it
finishes. 2. There is some time interval during which foo is running,
such that foo reports any user who is logged on throughout that
interval. (The reason readdir() isn't safe for some applications is that
it doesn't obey #2 in most implementations.)

Guess what? My version of users satisfies these properties. Your version
fails #2.

Now you can talk all you want about reallocating memory (btw, there's no
safe way to use realloc(), but you knew that) to read in as many users
as possible. I'll skip the comments about a quadratic time requirement,
and about people who simply *talk* about code instead of *writing* code,
and cut to the heart of the issue: You won't be able to identify a
single functional requirement that your reallocating version satisfies
and that my users program doesn't. You see, users has to exit at some
point, and before that point there must be a window when users doesn't
detect new logins. No external requirement can tell how big that window
is. So there's no way to tell the difference between a program that cuts
things off when people log on too fast and a program that is cut off by
the scheduler. The best you can do is #2 above. (This explanation isn't
particularly lucid, but if you try to say what advantage a reallocating
version will have, you'll realize that there is none.)

---Dan



More information about the Comp.bugs.4bsd.ucb-fixes mailing list