Subject: Calling units (was: problem with 3/7 sources)
To: None <>
From: Jeremy Scofield <cedar!>
List: current-users
Date: 03/14/1994 16:20:35
All the discussion of serial ports and ttyXX/cuaXX reminded me that
I had read (and saved) a very good description of the tradeoffs
between the two standard approaches to using modems for dialing in
and out, the Berkeley Calling Unit approach (ttyXX/cuaXX) versus the
older AT&T approach (CLOCAL/uugetty).

After reading the message again, I'm still convinced that the
Calling Unit approach is *much* superior to the alternative:
locking works correctly and easily, programs that use the serial
port (getty, uucico, tip, etc) don't need to do anything funny to
get the port open, and you can use the same simple getty on
two-directional ports as you do on dedicated inbound ports.

I'll include the message below -- it was posted to comp.unix.bsd
early last year by Terry Lambert.  I recommend it to anyone who
wants to understand the design issues.  The context is a bit dated
now -- it was in a discussion of whether uugetty was needed for
386BSD at the time.

    Jeremy Scofield          jeremy@cedar.UUCP
    Cedar River Software     ...!uw-beaver!cedar!jeremy
    Renton, WA               cedar!

Newsgroups: comp.unix.bsd
From: (A Wizard of Earth C)
Subject: Re: uugetty
Message-ID: <>
Date: Sun, 24 Jan 93 23:40:22 GMT

In article <> (Brian Leclair) writes:
>Hi, has anyone been able to port uugetty over to 386bsd? If so where can i
>ftp it from or where can i get the diffs for it from? I find the usual gettys
>suck... :)

There is no need for uugetty under 386BSD, no matter how used to using you
are.  386BSD uses the Berkeley "calling unit" abstraction to turn the line
around, rather than depending on exclusive use and locking files (one
wonders why uugetty does both, since one should be sufficient).

If you are familiar with /dev/ttyXX, /dev/ttyXXm, and /dev/ttyXXM on the
Microport or SunOS systems, then you already know how and why it works.  If
not, then it's fairly simpe to explain.


Basically the difference between uugetty and getty is that uugetty asserts
a lock on the port in either /usr/spool/uucp (for older implementations,
such as the SCO Xenix 2.2.1 version) or /usr/spool/locks (for newer
implementations -- substitute "var" for "usr" if you machine puts its
locks in the "client-server" locations for read-only /usr directories.

The uugetty program does not assert the lock until DCD is present and
before spitting out the "login:" banner.  Some uugetty implementations
will either wait for a <CR> before doing this, or optionally wait for a
<CR> if configured to do so.  This is window dressing for people unable
to set up their modems to not assert DCD until real carrier is present
or who have erroneously left CLOCAL set in their gettytab/gettydefs file.

In proper operation, uugetty takes advantage of the fact that the open
call to the device to put up the "login:" banner, and, later, fork off
the user's shell as stdin/stdout/stderr, hangs in the kernel until the
modem asserts DCD (we will ignore the badly configured modem instance).

Since uugetty is hung in the open, a program like uucico (the transfer
brains of uucp), or cu, or ct, or commercial packages, such as "TERM"
from Century Software (you owe me for the plug, Greg) can assert a lock
on the device prior to dialing.  This way, when the outgoing connection 
causes DCD to be asserted, the lock file will prevent uugetty from
doing I/O until it is removed.

Generally, uugetty will "wake up" every so many minute/seconds (this may
also be user configurable in some implementations) to check to see if
the lock is still asserted (and in the case of newer implementations, if
it is still valid -- most time out the lock after 90 minutes even if the
port is still in use!).

When uugetty determines that the lock has gone away, it resets to trying
to open the port without DCD.

On an incoming call, there is no lock file; therefore when the open
completes, uugetty asserts it's own lock, and spits out the "login:"
banner.  The lock remains asserted throughout the session (although,
again, it may be buggered by the 90 minute time out -- if that happens,
the dial in can be "stepped on" by the outgoing uucp.  The timing out
of lock files is, in my opinion, a stupid feature on machines where the
kill( pid, 0) call can be used to determin if a given pid is running).

Because of the "test-for-lock-sleep" loop, it can take up to the uugetty
wake-up time to find out that uugetty sould retry its open of a device
which was used for an outgoing connection.  This can result in up to 10
minute (or longer!) delays on line "turn around" -- the time between an
outgoing call being terminated and an incoming call being allowed.  This
is because proper set up will not assert DTR to the modem until an open
is waiting on the device, and the modem will not answer the phone without
DTR asserted.  In point of fact, an on-to-off transition of DTR, such as
that which occurs on device close on a correctly set up device will cause
a properly set up modem to reset as if powered off.  This keeps multispeed
modems from locking at one speed.

Is all this necessary?  (a resounding "No!" echos across the net).


The calling unit abstraction provides two devices; a standard device for
the getty, and a calling unit for outbound traffic.  The kernel prevents
a complete open on both at the same time.

The getty opens the /dev/ttyXX device and hangs waiting for DCD.  A
successful open of the /dev/cuXX device prevents the getty open from
completing... thus an outbound call does not need to provide a lock file
for other than contention with other outbound calls.  Since the open in
the getty will not complete until the calling unit device is closed and
DCD is asserted, the getty does not need to be involved in locking.

An incoming call on the /dev/ttyXX device asserts DCD, and the getty
open completes.  This locks out all opens on the /dev/cuXX device until
/dev/ttyXX is closed.  Since there is only one inbound server (getty),
this means that no lock files are necessary.  An attempted open of the
/dev/cuXX will return an error code indicating that the device is busy.

When the incoming call is terminated, the DCD drop causes the process
to exit (SIGHUP is sent to all processes whose controlling process is
the /dev/ttyXX).  In the case of a normal log out, the last process will
exit before DCD is dropped, and the DTR will drop because of no active
opens on the port.  So if you hang up, it logs you out, and if you log
out, it hangs up.

The resoloution of inbound/outbound contention in the kernel greatly
simplifies the process of line turn around, since it means an outbound
line is immediately available for inbound traffic once it is released;
it also means that the getty need not be restarted, and that a special
getty need not be used.

					Terry Lambert
Any opinions in this posting are my own and not those of my present
or previous employers.