[net.unix] Not a typewriter

largo@homxb.UUCP (J.BAKER) (06/11/86)

What does the sys_errlist message 'Not a typewriter' *really* mean??

I am writing to a laserjet through an fd setup by dial(3C).  When the 
laserjet exercises flow control and sends a DC3 its modem hangs up
and my writes return the above message.

Is this message meaningful?


j d baker (AT&T BL HO 2D410)
homxb!largo                    "I feel I shouldn't have to deal with this."

jrw@hropus.UUCP (Jim Webb) (06/11/86)

> 
> What does the sys_errlist message 'Not a typewriter' *really* mean??
> 

This message crops up when you try to do an ioctl on a file descriptor
that is not a terminal, for example:

		$  >/tmp/file			# just create a normal file and
		$  stty 9600 </tmp/file		# try to set it to 9600 baud
		stty: : not a typewriter
-- 
Jim Webb                                        ihnp4!houxm!hropus!jrw

mikel@codas.ATT.UUCP (Mikel Manitius) (06/11/86)

> What does the sys_errlist message 'Not a typewriter' *really* mean??

Errno 25 is usually generated when a program tries to execute an
ioctl command that expects the file descriptor to be a terminal.
(ie: you can't set the baud rate on a file).

However I have also noticed that some aplications aren't very
carefull when they use errno. For example, Informix may give
you this message if it cannot open a database file because it
does not exist!

I think there may be one or two system calls that will alter
errno to be 25, without returning a non-zero value, when in
fact there was no error.
-- 
			Mikel Manitius @ AT&T-IS Altamonte Springs, FL
			...{seismo!akgua|ihnp4|cbosgd}!codas!mikel.ATT.UUCP

levy@ttrdc.UUCP (Daniel R. Levy) (06/14/86)

In article <542@codas.ATT.UUCP>, mikel@codas.ATT.UUCP (Mikel Manitius) writes:
>> What does the sys_errlist message 'Not a typewriter' *really* mean??
>Errno 25 is usually generated when a program tries to execute an
>ioctl command that expects the file descriptor to be a terminal.
>(ie: you can't set the baud rate on a file).
>However I have also noticed that some aplications aren't very
>carefull when they use errno. For example, Informix may give
>you this message if it cannot open a database file because it
>does not exist!

I have had mail through a remote machine throw this error at me when it bounced
something I was trying to mail when it didn't know the next machine in the
path.  I kind of wondered what the dickens it was trying to ioctl()...

>I think there may be one or two system calls that will alter
>errno to be 25, without returning a non-zero value, when in
>fact there was no error.
>--

Dunno 'bout system calls (though the general rule is you don't check
errno unless it's immediately after calling something which returned an error
code and for which the value of errno is documented on your system) but
isatty(3) can trigger this error (it tries to do an ioctl(fd,TCGETA,&garbage)
on the fd given and uses the return value to determine whether it
succeeded and ergo whether fd was connected to a tty).

>			Mikel Manitius @ AT&T-IS Altamonte Springs, FL
>			...{seismo!akgua|ihnp4|cbosgd}!codas!mikel.ATT.UUCP
-- 
 -------------------------------    Disclaimer:  The views contained herein are
|       dan levy | yvel nad      |  my own and are not at all those of my em-
|         an engihacker @        |  ployer or the administrator of any computer
| at&t computer systems division |  upon which I may hack.
|        skokie, illinois        |
 --------------------------------   Path: ..!{akgua,homxb,ihnp4,ltuxa,mvuxa,
						vax135}!ttrdc!levy

chris@umcp-cs.UUCP (06/16/86)

In article <542@codas.ATT.UUCP> mikel@codas.ATT.UUCP (Mikel Manitius) writes:
>I think there may be one or two system calls that will alter
>errno to be 25, without returning a non-zero value, when in
>fact there was no error.

There are many library routines that may alter errno without in
fact failing; but there are no system calls that will do so.  This
is really the main distinction between manual sections 2 and 3,
as far as user code is concerned.

Incidentally, this points up a problem even with `good' error
handling routines.  I tend to write, e.g.,

	if ((fp = fopen(name, "w")) == NULL)
		error(1, errno, "cannot open %s for writing", name);

which usually results in a message like this:

	snerfle: cannot open breuglitz for writing: Permission denied

However, if the open failure were due to, say, running out of stdio
descriptors (but NOT file descriptors), it might say something wildly
inappropriate:

	snerfle: cannot open breuglitz for writing: Not a directory

My own opinion is that section 3 routines should set errno on errors
too.  (Actually, I think that `errno' itself should go away, but I
have no good replacement for it.)
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu

dgk@ulysses.UUCP (David Korn) (06/16/86)

> > What does the sys_errlist message 'Not a typewriter' *really* mean??
> 
> Errno 25 is usually generated when a program tries to execute an
> ioctl command that expects the file descriptor to be a terminal.
> (ie: you can't set the baud rate on a file).
> 
> However I have also noticed that some aplications aren't very
> carefull when they use errno. For example, Informix may give
> you this message if it cannot open a database file because it
> does not exist!
> 
> I think there may be one or two system calls that will alter
> errno to be 25, without returning a non-zero value, when in
> fact there was no error.
> -- 
> 			Mikel Manitius @ AT&T-IS Altamonte Springs, FL
> 			...{seismo!akgua|ihnp4|cbosgd}!codas!mikel.ATT.UUCP

Things can be even worse than this.  I recently ran across a problem where
an ioctl worked fine and I was able to change the tty mode.  When I went
to restore the mode, I got an ENOTTY error from ioctl().  Appearantly,
being a 'tty' is not an invariant of a file stream.  The line was
actually a pseudo-tty and the process which was processing characters
died.

It appears that you can't do an isatty at the beginning of a program and
trust the result.  The only safe thing that you can do is to check the
error status of ioctl() and see if it changes.

David Korn
ulysses!dgk

meissner@dg_rtp.UUCP (Michael Meissner) (06/16/86)

In article <542@codas.ATT.UUCP> mikel@codas.ATT.UUCP (Mikel Manitius) writes:
>> What does the sys_errlist message 'Not a typewriter' *really* mean??
>
>Errno 25 is usually generated when a program tries to execute an
>ioctl command that expects the file descriptor to be a terminal.
>(ie: you can't set the baud rate on a file).
>
>However I have also noticed that some aplications aren't very
>carefull when they use errno. For example, Informix may give
>you this message if it cannot open a database file because it
>does not exist!

    This particular error code tends to be set in errno, the first time you
use a stdio file that is not a terminal.  That is because the runtime library
wants to know if the file is associated with a terminal (so that it can be
unbuffered output in BSD or line buffered in SV.2).  Hence the library does
a isatty, which does an ioctl, and which fails, giving the error.  If an error
occurs on ioctl, isatty returns 0 instead of 1, and the library sets up to
fully buffer the file.

	Michael Meissner
	Data General Corporation
	...{ decvax, ihnp4, ucbvax }!mcnc!rti-sel!dg_rtp!meissner

philip@axis.UUCP (06/16/86)

In article <542@codas.ATT.UUCP> mikel@codas.UUCP writes:
>> What does the sys_errlist message 'Not a typewriter' *really* mean??
>
>I think there may be one or two system calls that will alter
>errno to be 25, without returning a non-zero value, when in
>fact there was no error.

This is true. *However*, if you look at the documentation *carefully*, you
will find that it says that errno is only valid if the system call preceeding
it returned an error value.

I agree that this is a disgusting state of affairs, and I have recently
had problems with a code segment as follows:


	fp = fopen(.....);
	errno = 0;
	..
	..
	loop: fwrite(.....);
	if (errno != 0) /* a write problem occured */
	{
		...
		...
	}
	..

This bombed out complaining about "Not a teletype", there was in fact,
no problem at all. The code came from a BSD4.? system, the machine on
which the problems occured runs S5.2.

mikel@codas.ATT.UUCP (Mikel Manitius) (06/18/86)

>>>What does the sys_errlist message 'Not a typewriter' *really* mean??
>>
>>I think there may be one or two system calls that will alter
>>errno to be 25, without returning a non-zero value, when in
>>fact there was no error.
>>                                     Mikel Manitius
> 
>This is true. *However*, if you look at the documentation *carefully*, you
>will find that it says that errno is only valid if the system call preceeding
>it returned an error value.

Well, there is an exception. If a read or write is interrupted by
a signal, it will return 0 or number of bytes written before the
interrupt occured. In this case errno = 4, and no error code is
returned from the system call.
-- 
			Mikel Manitius @ AT&T-IS Altamonte Springs, FL
			...{seismo!akgua|ihnp4|cbosgd}!codas!mikel.ATT.UUCP

guy@sun.uucp (Guy Harris) (06/18/86)

> That is because the runtime library wants to know if the file is associated
> with a terminal (so that it can be unbuffered output in BSD or line
> buffered in SV.2).

Not quite.  Line buffering was introduced either in 4.1BSD or even earlier.
The USDL picked up the Berkeley implementation and dropped it into S5 in
S5R2.
-- 
	Guy Harris
	{ihnp4, decvax, seismo, decwrl, ...}!sun!guy
	guy@sun.com (or guy@sun.arpa)

ka@hropus.UUCP (Kenneth Almquist) (06/19/86)

> If a read or write is interrupted by a signal, it will return 0 or
> number of bytes written before the interrupt occured.  In this case
> errno = 4, and no error code is returned from the system call.

I suspect you are misreading the documentation.  When a write system
call is interrupted, it may either return a short count or return -1.
Errno is set to 4 in the latter case.  I don't know of any version of
UNIX in which read will return zero when interrupted.
				Kenneth Almquist

dave@onfcanim.UUCP (Dave Martindale) (06/20/86)

In article <717@axis.UUCP> philip@axis.UUCP (Philip Peake) writes:
>In article <542@codas.ATT.UUCP> mikel@codas.UUCP writes:
>>> What does the sys_errlist message 'Not a typewriter' *really* mean??
>>
>
>This is true. *However*, if you look at the documentation *carefully*, you
>will find that it says that errno is only valid if the system call preceeding
>it returned an error value.
>
>I agree that this is a disgusting state of affairs, and I have recently
>had problems with a code segment as follows:
>
>
>	fp = fopen(.....);
>	errno = 0;
>	..
>	..
>	loop: fwrite(.....);
>	if (errno != 0) /* a write problem occured */
>	{
>		...
>		...
>	}
>	..
>
>This bombed out complaining about "Not a teletype", there was in fact,
>no problem at all. The code came from a BSD4.? system, the machine on
>which the problems occured runs S5.2.

Right.  As the manual says, errno is meaningful only after a system call
has failed.  If you want to check for an error in the fwrite, either check
fwrite's return value, or use ferror().

Errno is meaningful at the level of doing system calls - read, write, etc.
Fwrite is a higher-level function, and has its own ways of indicating errors.

In fact, in this particular case, errno is being set as a side effect of
the fwrite.  The first time you do I/O on a stdio unit, the package does
an ioctl("get terminal characteristics") on the file descriptor.  If the
ioctl succeeds, stdio knows that it should line-buffer or character-buffer
that stream.  If the ioctl fails (and when it does, it will set errno to
"not a typewriter"), stdio will use block buffering appropriate to a file.

Because of this, "not a typewriter" is the error message you will almost always
see if you look at errno when there hasn't been a real error, since almost
every program does I/O through stdio fairly early.

The moral is: you *can't* reliably tell whether there has been an error by
checking an external variable every once in a while.  You have to check
the return value of everyting that could possibly go wrong.

ed@mtxinu.UUCP (Ed Gould) (06/20/86)

>>This is true. *However*, if you look at the documentation *carefully*, you
>>will find that it says that errno is only valid if the system call preceeding
>>it returned an error value.
>
>Well, there is an exception. If a read or write is interrupted by
>a signal, it will return 0 or number of bytes written before the
>interrupt occured. In this case errno = 4, and no error code is
>returned from the system call.

As long as we're reading the documentatin *carefully*, let's remember that
any return from

	write(fd, buf, n)

that is != n is an error.

This leaves only the interrupted

	read(fd, buf, n)

which could return with "no error code" returned.  Reads from fast
devices (e.g. disks) can't be interrupted.  Reads from slow devices
(e.g. ttys) can be interrupted, but not if they've caused any data to
be transferred.  That's because once there is data available, it will be
transfered to the user and the call will return.

Read() will return one of four values: <0 if error, 0 if EOF, 0<k<n if
only k bytes were available to be read (typically because the k'th byte was
a delimiter like newline or we were positioned k bytes before EOF), or
n if >= n bytes were available.  I can't test this here, since I'm
running 4.2BSD which will restart the read(), but if I remember
correctly back to V7 and 4.1, only the <0 case will cause errno to be
altered.

So what is the case that sets errno without returning an error indication?
The *only* legitimate time to use errno is after an error return from
a system call, or from a library routine that is explicitly documented
to set errno on error.

EIEIO	"Bug bug here. Bug bug there.  Here a bug, there a bug.
	Everywhere a bug bug."

-- 
Ed Gould                    mt Xinu, 2910 Seventh St., Berkeley, CA  94710  USA
{ucbvax,decvax}!mtxinu!ed   +1 415 644 0146

"A man of quality is not threatened by a woman of equality."

mikel@codas.ATT.UUCP (Mikel Manitius) (06/20/86)

>> If a read or write is interrupted by a signal, it will return 0 or
>> number of bytes written before the interrupt occured.  In this case
>> errno = 4, and no error code is returned from the system call.
>>
>>						 Mikel Manitius
> 
>I suspect you are misreading the documentation.  When a write system
>call is interrupted, it may either return a short count or return -1.
>Errno is set to 4 in the latter case.  I don't know of any version of
>UNIX in which read will return zero when interrupted.
>
> 				Kenneth Almquist

Yes, you are correct. I don't always trust the documentation, so I
rarely read it. I checked by writing a small C program, write does
indeed return -1 not 0, when the call is interrupted and no bytes
were read.
-- 
			Mikel Manitius @ AT&T-IS Altamonte Springs, FL
			...{seismo!akgua|ihnp4|cbosgd}!codas!mikel.ATT.UUCP

apartan@gouldsd.UUCP (06/26/86)

In article <37@mtxinu.UUCP>, ed@mtxinu.UUCP (Ed Gould) writes:
> As long as we're reading the documentatin *carefully*, let's remember that
> any return from
> 
> 	write(fd, buf, n)
> 
> that is != n is an error.

This is NOT so!  If the fd refers to a pipe, and you are writing more bytes
than the pipe will hold, and you get an interrupt, then the write() will return
something that is >0, but is != n.

I ran into this problem porting some code to a Perkin-Elmer XELOS system (a
port of Sys V).

	--asp (Andrew S. Partan)
	-- seismo!sundc!gouldsd!asp
	-- decuac!gouldsd!asp

bradbury@oracle.UUCP (Robert Bradbury) (07/06/86)

In article <573@codas.ATT.UUCP>, mikel@codas.ATT.UUCP (Mikel Manitius) writes:
> 
> Yes, you are correct. I don't always trust the documentation, so I
> rarely read it. I checked by writing a small C program, write does
> indeed return -1 not 0, when the call is interrupted and no bytes
> were read.
> 			Mikel Manitius

The problem is much more subtle than is indicated by this discussion.
A -1 will be returned and errno set to EINTR if a signal has been
received anytime from the beginning to the end of the system call.
In cases where the the system call may be completed without doing
a sleep() [a read from a teletype where the user has typed ahead or
a write to a pipe] the system call will actually have done the work
successfully even though it returns an error.

This maybe I did it and maybe I didn't aspect of system calls in the
presence of signals has caused me to write some very strange code
from time to time.  The Berkeley folks tried to solve this in 4.1
by "restarting" the system call.  Does this work right all the time?

It would seem the real problem revolves around the need for multiple
return values from system calls and/or the ability to prevent signals
(without the overhead of more system calls) for some system calls.

Does anyone know if P1003 or System 5.3 have come up with solutions for this
problem?


-- 
Robert Bradbury
Oracle Corporation
(206) 364-1442                            {ihnp4!muuxl,hplabs}!oracle!bradbury