9fans - fans of the OS Plan 9 from Bell Labs
 help / color / mirror / Atom feed
* Re: [9fans] weird print(2) problems...
@ 2001-09-05 19:19 Russ Cox
  2001-09-05 19:40 ` Boyd Roberts
                   ` (2 more replies)
  0 siblings, 3 replies; 18+ messages in thread
From: Russ Cox @ 2001-09-05 19:19 UTC (permalink / raw)
  To: 9fans

> print() shouldn't call write(), as there's nothing to write.

then {echo ''} shouldn't print a newline, as there's nothing to echo.
there's no obvious answer except that we shouldn't try to "fix" it.

see _The Unix Programming Environment_,
Kernighan & Pike (1984), pp. 77-79, "A digression on echo".

the below won't make sense if you don't read k&p first,
and even then it might not make sense.  it's not quite
as amusing as i thought at the time, but the first week of
march 1999 is missing from the web archives, so i feel obligated
to repost it.

russ


 From cse.psu.edu!owner-9fans Fri Mar  5 14:18:21 EST 1999
Date: Fri, 5 Mar 1999 14:09:19 -0500
To: 9fans@cse.psu.edu
From: "Russ Cox" <rsc@plan9.bell-labs.com>
Subject: re: [9fans] What happens when you do an echo -n?
Sender: owner-9fans@cse.psu.edu
Reply-To: 9fans@cse.psu.edu

                     The Plan 9 and the Echo
           (With my deepest apologies to Doug McIlroy)

    There dwelt in the land of New Jersey, the Unix, a fair maid whom
savants traveled far to admire.  Her story has already been told.

    As the Unix grew older, younger maidens began to imitate her ways,
sometimes even to the point of changing their names to sound like
her's, in attempts to attract suitors, especially the insufferably rich
ones.  As more maidens began to act like the Unix, all but the most
exacting of suitors left the Unix for these pale stereotypes.

    When the Unix had grown old, and her myriad suitors had left her
for younger maids whose imitation of the Unix was ``good enough'', the
Unix took under her wing the Plan 9, but a small child at the time.
The Unix endeavored to teach the lessons she had learned over her
lifetime, that the Plan 9 need not make the Unix's mistakes herself.
Under the Unix's tutelage, the Plan 9 grew to be a beautiful young
maid herself.  She had far fewer suitors than the Unix had once
enjoyed, since she was competing with the Unix imitators.  Even so, a
small but faithful group of savants admired her, dazzled by the grace
and civility the Unix had taught her.  Still others were amazed by her
agility in performing exacting tasks seldom accomplished even by the
Unix.

    One sad day, the Unix passed away, leaving the Plan 9, fully grown
at this point, to fend for herself.  In deference to the venerable
Unix, Nature herself now answered to the Plan 9 more eagerly than to
other mortal beings.  Once again humbler folk delighted in such a pure
echo coming from the wilderness that had so frustrated their own
attempts since the Unix's younger days.  Taught well by her mother,
the Plan 9 obliged with perfect echoes of whatever she was asked.

    Some years later, a sensitive young lad asked the Plan 9, `Echo
nothing at all.'  Wise of the Unix's earlier troubles, the Plan 9
grinned slightly, kept her mouth closed, and did nothing.

    `Whatever do you mean,' the youth demanded, `not looking toward
the wilderness?  For perfect echoes cannot come back unless you are
facing the wilderness.  Henceforth turn toward the wilderness, even
when you are echoing nothing at all.'  And the Plan 9 obliged.

    `But echoing nothing at all is not a proper echo,' pleaded an
impatient swain, `so do not turn toward the wilderness when echoing
nothing at all.'  At this point the Plan 9 realized history repeating
itself, and although she did not want to offend either, she decided it
was better to offend the impatient youth rather than subject all her
suitors to yet another surfeit of notation.



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
  2001-09-05 19:19 [9fans] weird print(2) problems Russ Cox
@ 2001-09-05 19:40 ` Boyd Roberts
  2001-09-06  8:19 ` Matthew Hannigan
  2001-09-06 16:18 ` Douglas A. Gwyn
  2 siblings, 0 replies; 18+ messages in thread
From: Boyd Roberts @ 2001-09-05 19:40 UTC (permalink / raw)
  To: 9fans

> then {echo ''} shouldn't print a newline, as there's nothing to echo.
> there's no obvious answer except that we shouldn't try to "fix" it.

err...

    http://plan9.bell-labs.com/magic/man2html/1/echo

    Echo writes its arguments separated by blanks and terminated by a
    newline on the standard output. Option -n suppresses the newline.

_terminated by a newline_.




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
  2001-09-05 19:19 [9fans] weird print(2) problems Russ Cox
  2001-09-05 19:40 ` Boyd Roberts
@ 2001-09-06  8:19 ` Matthew Hannigan
  2001-09-06 16:18 ` Douglas A. Gwyn
  2 siblings, 0 replies; 18+ messages in thread
From: Matthew Hannigan @ 2001-09-06  8:19 UTC (permalink / raw)
  To: 9fans



Russ Cox wrote:
> then {echo ''} shouldn't print a newline, as there's nothing to echo.
> there's no obvious answer except that we shouldn't try to "fix" it.
>
> see _The Unix Programming Environment_,
> Kernighan & Pike (1984), pp. 77-79, "A digression on echo".
> [ .. ]

damn, you beat me to it!


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
  2001-09-05 19:19 [9fans] weird print(2) problems Russ Cox
  2001-09-05 19:40 ` Boyd Roberts
  2001-09-06  8:19 ` Matthew Hannigan
@ 2001-09-06 16:18 ` Douglas A. Gwyn
  2001-09-06 20:45   ` Boyd Roberts
  2 siblings, 1 reply; 18+ messages in thread
From: Douglas A. Gwyn @ 2001-09-06 16:18 UTC (permalink / raw)
  To: 9fans

Russ Cox wrote:
> > print() shouldn't call write(), as there's nothing to write.
> then {echo ''} shouldn't print a newline, as there's nothing to echo.

No, the semantics for "echo" are traditionally defined as simply:
printing its arguments separated by spaces and followed by a newline.
So even "echo" with no additional arguments must print a newline.
(Unless, of course, told to suppress the newline, as with the -n
option.)  Echo with a 0-length string argument should print the
0-length string argument, separated from adjacent arguments in
the output by spaces, then NL.  "echo a '' '' b" should print
"a<space><space><space>b<newline>".

The problem with "higher-level" library functions such as print()
is that, generally, there is no clear specification relating their
invocation and when they call low-level functions such as write().

> there's no obvious answer except that we shouldn't try to "fix" it.

write() with buffer length 0 should of course write an empty data
packet.  Whether a subsequent read will see the packet boundaries
depends on several things, and whether a 0-length packet is
interpreted as "end of file" depends on several *other* things.

We ran into all this on early versions of UNIX, where a ^D on a
terminal input actually just delimited (sent along from raw to
canonical queue) the current input, same as a new-line input,
except of course without the embedded newline character.  The
UNIX convention was that read() returning 0 characters, such as
it would for a terminal *iff* a delimiter immediately followed
a previous delimiter (newline or ^D-activated), was interpreted
as end of file.  This was consistent with reading characters
beyond the last one present in a static (disk) file.  On pipes,
it required preservation of written record lengths so a 0-length
record could be detected by read().

Ultimately, many flavors of I/O on UNIX-based systems grew more
complicated, and record lengths were harder to preserve.  EOF
was therefore sometimes indicated by out-of-band information
instead of by a 0-length data packet.  However, the 0-length
idea has considerable appeal, and whatever problems there are
seem to be due to assuming semantics for an "end of file"
indication that are more heavyweight ("sticky") than the
condition sometimes indicates.  I would say that a "solution"
would be for read() from a source that (1) has no more data,
(2) has already reported 0-length for end of data, and (3) can
*never* have any more data to return a distinct "attempted read
past end of data" error, instead of the less informative 0-long
buffer.  That would not affect applications that interpret a
0-length return from read() as EOF, but would allow apps to
do the "natural" thing with empty data packets (i.e. process no
data) instead of having to assume they mean permanent EOF.

>                     The Plan 9 and the Echo

The parable is silly.  The traditional semantics of "echo" have
a simple, regular specification, which is not true of an "echo"
that outputs nothing when supplied with no non-option arguments.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
  2001-09-06 16:18 ` Douglas A. Gwyn
@ 2001-09-06 20:45   ` Boyd Roberts
  0 siblings, 0 replies; 18+ messages in thread
From: Boyd Roberts @ 2001-09-06 20:45 UTC (permalink / raw)
  To: 9fans

doug, is, of course, right [no sarcasm intended].




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
@ 2001-09-11 11:16 rob pike
  0 siblings, 0 replies; 18+ messages in thread
From: rob pike @ 2001-09-11 11:16 UTC (permalink / raw)
  To: 9fans

> The parable is silly.  The traditional semantics of "echo" have
> a simple, regular specification, which is not true of an "echo"
> that outputs nothing when supplied with no non-option arguments.

It may be silly but it has a point, as a parable should.  When it was
written, there was no "traditional" semantics for echo, as the parable
makes clear.

-rob



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
  2001-09-05 21:11 ` Russ Cox
@ 2001-09-05 21:24   ` Scott Schwartz
  0 siblings, 0 replies; 18+ messages in thread
From: Scott Schwartz @ 2001-09-05 21:24 UTC (permalink / raw)
  To: 9fans

| We can dive into heuristics
| ad nauseum, but I think we're just stuck
| with the overload until everyone switches
| to a language with tupled return values
| like Limbo.

If you don't mind changing old code (and I think it's fair to say
that Plan 9 fans are selected for that) you could return -2 for EOF,
or return -1 and check errstr, or have the read library function return
the length via a pointer argument and return +/0/- for ok/eof/err,
or something along those lines.



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
@ 2001-09-05 21:11 ` Russ Cox
  2001-09-05 21:24   ` Scott Schwartz
  0 siblings, 1 reply; 18+ messages in thread
From: Russ Cox @ 2001-09-05 21:11 UTC (permalink / raw)
  To: 9fans

> But, having a program that does a `print("");' render an acme window
> unusable for all intents and purposes still seems like a problem that
> needs to be fixed somehow.

We've overloaded a read of length 0 with
two meanings, and there's no good way out now.
Should write(1, "", 0) render an acme window
unusable?  Maybe it's acme's fault.  Telnetd waits
for three zero-length writes, so that
	g% echo -n
dosen't hang up the connection but
	g% echo -n; echo -n; echo -n
still does.  We can dive into heuristics
ad nauseum, but I think we're just stuck
with the overload until everyone switches
to a language with tupled return values
like Limbo.

Russ



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
  2001-09-05 18:40 Russ Cox
@ 2001-09-05 19:58 ` Dan Cross
  0 siblings, 0 replies; 18+ messages in thread
From: Dan Cross @ 2001-09-05 19:58 UTC (permalink / raw)
  To: 9fans

In article <20010905184545.BA2EF19A3F@mail.cse.psu.edu> you write:
>Kind of, but there's a special case either way.
>If you're generating morse code I'd use bio anyway,
>and then you don't have to worry about 0-length writes.

That (bio) sounds like the right solution for the morse code program,
which is actually a pipeline.  This program just generates random code
groups to be sent to another program that translates them into dots and
dashes, and then another reads that and translates it into a ``tones''
little language which is read by yet another program that generates PCM
sounds samples; the output of all that is finally directed into the
audio device.

But, having a program that does a `print("");' render an acme window
unusable for all intents and purposes still seems like a problem that
needs to be fixed somehow.

	- Dan C.



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
@ 2001-09-05 19:46 Russ Cox
  0 siblings, 0 replies; 18+ messages in thread
From: Russ Cox @ 2001-09-05 19:46 UTC (permalink / raw)
  To: 9fans

that wasn't the point and you know it.



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
  2001-09-05 18:23 ` Dan Cross
@ 2001-09-05 19:10   ` Boyd Roberts
  0 siblings, 0 replies; 18+ messages in thread
From: Boyd Roberts @ 2001-09-05 19:10 UTC (permalink / raw)
  To: 9fans

> Yes there is.  When the program I'm piping to reads zero bytes, it stops
> reading.  If it reads n > 0 bytes, it does not.

zero writes on pipes should probably be tossed.

just how do you figure out eof?




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
  2001-09-05 14:22     ` Dan Cross
@ 2001-09-05 19:01       ` Boyd Roberts
  0 siblings, 0 replies; 18+ messages in thread
From: Boyd Roberts @ 2001-09-05 19:01 UTC (permalink / raw)
  To: 9fans

> Is there an elegant solution (other than ``don't do print("");'',
> since that might really mean ``don't do,

print() shouldn't call write(), as there's nothing to write.

we're dealing with strings here.




^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
@ 2001-09-05 18:40 Russ Cox
  2001-09-05 19:58 ` Dan Cross
  0 siblings, 1 reply; 18+ messages in thread
From: Russ Cox @ 2001-09-05 18:40 UTC (permalink / raw)
  To: 9fans

> But isn't this also a special case I now need to remember?  Worse I

Kind of, but there's a special case either way.
If you're generating morse code I'd use bio anyway,
and then you don't have to worry about 0-length writes.

Russ


^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
  2001-09-05 15:11 forsyth
@ 2001-09-05 18:23 ` Dan Cross
  2001-09-05 19:10   ` Boyd Roberts
  0 siblings, 1 reply; 18+ messages in thread
From: Dan Cross @ 2001-09-05 18:23 UTC (permalink / raw)
  To: 9fans

In article <20010905150808.1FC2619A32@mail.cse.psu.edu> you write:
>>>that if write(2) sees a zero length argument, it should consider that a
>>>nop and return.  But then it seems that that would break some weird
>>>semantic somewhere (``Any write will update a timestamp; except for
>>>zero length writes, which are ignored.'' ``Dude, that's broken.'')
>
>it isn't only the possible effect on time stamps; i think it
>should do a write 0 because it's what you said to do.

Yes, that's what I mean by ``breaking some weird semantic''  (although
the semantic isn't that weird).  The timestamp thing was just a contrived
example.

>to be fair, it's disguised by print, but even so,
>if i wanted nop() i'd use
>	;
>or
>	void nop(void){}
>but i wouldn't call write() or even print.  i'd call write() when i wanted
>to write, and i prefer systems that do what i tell it, so that if i say
>`write 0 bytes' i expect it to do that, rather than adding yet
>more special cases to remember.

I don't disagree, but the behavior I've observed is demonstrably broken.

I'm looking for a fix to the system so that the guy writing a program
doesn't have to worry if he's accidentally printing out a blank string;
that's the special case I want to avoid.

After all, if I write zero bytes, I don't expect the program on the
other end of my pipe to stop reading all of a sudden.

>  the effect of writing 0 bytes
>is determined by the device, but that's true of writing 1 byte or many,
>so there's no difference there.

Yes there is.  When the program I'm piping to reads zero bytes, it stops
reading.  If it reads n > 0 bytes, it does not.

>on the other hand, i'd probably write
>	if(*str)
>		print("%s", str);
>if that's what i wanted.

Sure, that's how I fixed the program at hand (which generates morse
code, btw).

But isn't this also a special case I now need to remember?  Worse I
have to remember it when writing user level programs; the complexity
of it (granted, not much) isn't hidden from me.  It's a bummer;
surely there's an elegant solution to this problem.

	- Dan C.



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
@ 2001-09-05 15:11 forsyth
  2001-09-05 18:23 ` Dan Cross
  0 siblings, 1 reply; 18+ messages in thread
From: forsyth @ 2001-09-05 15:11 UTC (permalink / raw)
  To: 9fans

[-- Attachment #1: Type: text/plain, Size: 996 bytes --]

>>that if write(2) sees a zero length argument, it should consider that a
>>nop and return.  But then it seems that that would break some weird
>>semantic somewhere (``Any write will update a timestamp; except for
>>zero length writes, which are ignored.'' ``Dude, that's broken.'')

it isn't only the possible effect on time stamps; i think it
should do a write 0 because it's what you said to do.
to be fair, it's disguised by print, but even so,
if i wanted nop() i'd use
	;
or
	void nop(void){}
but i wouldn't call write() or even print.  i'd call write() when i wanted to write,
and i prefer systems that do what i tell it, so that if i say `write 0 bytes'
i expect it to do that, rather than adding yet
more special cases to remember.   the effect of writing 0 bytes
is determined by the device, but that's true of writing 1 byte or many,
so there's no difference there.

on the other hand, i'd probably write
	if(*str)
		print("%s", str);
if that's what i wanted.


[-- Attachment #2: Type: message/rfc822, Size: 2476 bytes --]

To: 9fans@cse.psu.edu
Cc: 
Subject: Re: [9fans] weird print(2) problems...
Date: Wed, 5 Sep 2001 10:22:18 -0400 (EDT)
Message-ID: <200109051422.KAA02761@augusta.math.psu.edu>

In article <20010904190825.3180.qmail@f.bio.cse.psu.edu> you write:
>Hm.  Pipes in Plan 9 preserve write boundaries, right?  Print is probably
>sending a zero length write, and confusing programs that interpret it
>as eof.

Hmm, that seems plausible.  It's also rather annoying; it seems to me
that if write(2) sees a zero length argument, it should consider that a
nop and return.  But then it seems that that would break some weird
semantic somewhere (``Any write will update a timestamp; except for
zero length writes, which are ignored.'' ``Dude, that's broken.'')

Is there an elegant solution (other than ``don't do print("");'',
since that might really mean ``don't do,

	read(0, str, 128);
	trimwhitespace(str);
	print("%s", str);

where the only thing read is a blank line or something.'')?

	- Dan C.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
  2001-09-04 19:08   ` Scott Schwartz
@ 2001-09-05 14:22     ` Dan Cross
  2001-09-05 19:01       ` Boyd Roberts
  0 siblings, 1 reply; 18+ messages in thread
From: Dan Cross @ 2001-09-05 14:22 UTC (permalink / raw)
  To: 9fans

In article <20010904190825.3180.qmail@f.bio.cse.psu.edu> you write:
>Hm.  Pipes in Plan 9 preserve write boundaries, right?  Print is probably
>sending a zero length write, and confusing programs that interpret it
>as eof.

Hmm, that seems plausible.  It's also rather annoying; it seems to me
that if write(2) sees a zero length argument, it should consider that a
nop and return.  But then it seems that that would break some weird
semantic somewhere (``Any write will update a timestamp; except for
zero length writes, which are ignored.'' ``Dude, that's broken.'')

Is there an elegant solution (other than ``don't do print("");'',
since that might really mean ``don't do,

	read(0, str, 128);
	trimwhitespace(str);
	print("%s", str);

where the only thing read is a blank line or something.'')?

	- Dan C.



^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [9fans] weird print(2) problems...
  2001-09-04 19:02 ` Dan Cross
@ 2001-09-04 19:08   ` Scott Schwartz
  2001-09-05 14:22     ` Dan Cross
  0 siblings, 1 reply; 18+ messages in thread
From: Scott Schwartz @ 2001-09-04 19:08 UTC (permalink / raw)
  To: 9fans

Hm.  Pipes in Plan 9 preserve write boundaries, right?  Print is probably
sending a zero length write, and confusing programs that interpret it
as eof.


^ permalink raw reply	[flat|nested] 18+ messages in thread

* [9fans] weird print(2) problems...
@ 2001-09-04 19:02 ` Dan Cross
  2001-09-04 19:08   ` Scott Schwartz
  0 siblings, 1 reply; 18+ messages in thread
From: Dan Cross @ 2001-09-04 19:02 UTC (permalink / raw)
  To: 9fans

Running the following program, output after the ``print("");''
never makes it as piped input to other programs.

Has anyone else noticed this?  btw- when I tried to run it
under an acme ``win'' window, it hung and I had to Delete the
window to clear it up.  Very strange....  Any ideas?  (btw- I
removed a literal `eot' from below.)

	- Dan C.

term% cat > test.c
#include <u.h>
#include <libc.h>
void
main(void)
{
	print("");
	print("Test.\n");
	exits(0);
}
(eot)term% 8c test.c && 8l test.8
term% 8.out
Test.
term% 8.out | cat
term% echo twilight zone theme....
twilight zone theme....
term%


^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2001-09-11 11:16 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2001-09-05 19:19 [9fans] weird print(2) problems Russ Cox
2001-09-05 19:40 ` Boyd Roberts
2001-09-06  8:19 ` Matthew Hannigan
2001-09-06 16:18 ` Douglas A. Gwyn
2001-09-06 20:45   ` Boyd Roberts
  -- strict thread matches above, loose matches on Subject: below --
2001-09-11 11:16 rob pike
     [not found] <rsc@plan9.bell-labs.com>
2001-09-05 21:11 ` Russ Cox
2001-09-05 21:24   ` Scott Schwartz
2001-09-05 19:46 Russ Cox
2001-09-05 18:40 Russ Cox
2001-09-05 19:58 ` Dan Cross
2001-09-05 15:11 forsyth
2001-09-05 18:23 ` Dan Cross
2001-09-05 19:10   ` Boyd Roberts
     [not found] <cross@math.psu.edu>
2001-09-04 19:02 ` Dan Cross
2001-09-04 19:08   ` Scott Schwartz
2001-09-05 14:22     ` Dan Cross
2001-09-05 19:01       ` Boyd Roberts

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).