On 10 November 2017 at 10:50, Nemo <cym224(a)gmail.com> wrote:
> On 10 November 2017 at 04:56, Alec Muffett <alec.muffett(a)gmail.com> wrote:
>> http://www.cheswick.com/ches/papers/berferd.pdf ?
>
> Wonderful! I first read this as an appendix in his book and now I
> know a second edition of the book is out.
>
> N.
Egg on my face (and keyboard): (1) I failed to send this to the list;
and (2) I already have both editions.
Apologies, all, especially to Alec.
N.
I happened to come across a 1975 report from the University of Warwick
which includes a section on the state of computer networking.
(https://stacks.stanford.edu/file/druid:rq704hx4375/rq704hx4375.pdf)
It contains a section that appears to be a summary of a chat with Sandy
Fraser about Spider (pp. 66-69). It has some information on Spider network
software and Unix that is new to me, and I find amazing. I had not expected
some of this stuff to exist in 1975.
Below some of the noteworthy paragraphs:
[quote]
Spider is an experimental packet switched data communications system that
provides 64 full-duplex asynchronous channels to each connected terminal
(= host computer). The maximum data-rate per channel is 500K bits/sec. Error
control by packet retransmission is automatic and transparent to users.
Terminals are connected to a central switching computer by carrier transmission
loops operating at 1.544 Mb/s, each of which serves several terminals. The
interface between the transmission loop and a terminal contains a stored program
microcomputer. Cooperation between microcomputers and the central switching
computer effects traffic control, error control, and various other functions
related to network operation and maintenance.
The current system contains just one loop with the switching computer (TEMPO I),
four PDP-11/45 computers, two Honeywell 516 computers, two DDP 224 computers,
and one each of Honeywell 6070, PDP-8 and PDP-11/20. In fact many of these are
connected in turn to other items of digital equipment.
Spider has been running since 1972 and recent work has shifted away from the
design and construction of the network itself to developing user services to
support other research activities at Bell Labs. A major example of this has
been to construct a free-standing file store (extracted in fact from UNIX [88])
and connect it to the network. This is available as a service to any user of
the network.
[...]
The ring is used in different ways by the various computers connected to it.
The filestore has already been mentioned. Two computers use this for conventional
back-up, and access it on a file-by-file basis.
Two other machines - dedicated to laboratory experiments - access it on a
block-within-file basis. To help with program development for these dedicated
machines, the UNIX system (available on yet more computers) is used during
"unavailable" periods for editing and program preparation. The user then leaves
his programs in the filestore ready to load when he next gains access to the
dedicated machine.
Two other "dedicated" machines provide the user interface of UNIX, but lack
peripherals and a UNIX kernel! In place of both is a small amount of software
that transmits all calls on the UNIX system to a full UNIX system elsewhere!
The ring system with its filestore also provides a convenient buffering service.
Finally Fraser tells of the time where one of the PDP-11 machines was delivered
sans discs. A small alteration to a UNIX system diverted all disc transfer
requests to the filestore, where a suitable amount of disc was made available.
The system ran a full swapping version of UNIX at about a quarter of the
normal speed.
[/quote]
> From: Jon Forrest
> In the early days of Unix I was told that it wasn't practical to write a
> pager because such a thing would have to run in raw mode in order to
> process single letter commands, such as the space character for going on
> to the next page. Since raw mode introduced a significant amount of
> overhead on already overtaxed machines, it was considered an anti-social
> thing to do.
Something sounds odd here.
One could have written a pager which used 'Return' for each new page, and run
it in cooked mode and not used any less cycles (in fact, more, IIRC the
cooked/raw differences in handling in the TTY driver).
But that's all second-order effects anyway. If one were using a serial line
hooked up to a DZ (and those were common - DH's were _much_ more expensive, so
poor places like my lab at MIT used DZ's), then _every character printed_
caused an interrupt. So the overhead from printing each screen-ful of text was
orders of magnitude greater than the overhead of the user's input to get the
next screen.
> IIRC later versions of Unix added the ability to respond to a specific
> list of single characters without going into raw mode. Of course, that
> didn't help when full-screen editors like vi and the Rand editor came
> out.
Overhead was definitely an issue with EMACS on Multics, where waking up a
process on each character of input was significant. I think Bernie's Multics
EMACS document discusses this. I'm pretty sure they used the Telnet RCTE
option to try and minimize the overhead.
Noel
Hi,
In looking around the system v7 environment, I don't see a more command anywhere. I downloaded, converted, and attached 1bsd, 2bsd, and finally 3bsd and it was there that I found source for more... 3bsd looks like it's for VAX, not PDP-11, and it doesn't want to compile (looking for some externs that I gather are part of the distro's clib).
I may jump ship on V7 and head over to 2.9BSD, which, as I understand it, is a V7 with fixes and these kind of additional tools...
In the meantime, how did folks page through text like man sh and such before more? I know how to view sections of text using sed and ed's ok for paging file text (painful, but workable). I just can't seem to locate the idiomatic way of keeping everything from constantly scrolling out of view! Obviously, this isn't a problem on my mac as terminal works fine, but I like to try to stay in character as a 1970 time traveling unix user :).
Thanks,
Will
Sent from my iPhone
> I do recall 80 column monitors, but I started on 132 column decwriter
> IIs and hence have never had sympathy for 80 columns. It's weird that so
Interesting. I wonder if that's where the 132 column (alternative)
standard came from.
No. IBM's printers were 132 columns even before stored-program
computers.
> From: Steve Simon
> At the risk of stirring up another hornets nest...
I usually try not to join in to non-history threads (this list has too much
random flamage on current topics, IMNSHO), but I'll make an exception here...
> this means my code is usually fairly narrow.
I have what I think are somewhat unusual thoughts on nesting depth, etc, which
are: keep the code structure as simple as possible. That means no complex
nested if/then/else structures, etc (more below).
I'd been moving in this direction for a while, but something that happened a
long time ago at MIT crystalized this for me: a younger colleague brought me a
routine that had a complex nested if/etc structure in it, which had a bug; I
don't recall if he just wanted advice, or what, but I recall I fixed his
problem by..... throwing away half his code. (Literally.)
That really emphasized to me the downside of complexity like that; it makes it
harder to understand, harder to debug, and harder for someone else (or you
yourself, once you've been away from it for a while) to modify it. I've been
getting more formal about that ever since.
So, how did I throw away half his code? I have a number of techniques. I try
not to use 'else' unless it's the very best way to do something. So instead
of:
if (some-conditional) {
<some code>;
}
else {
<some other code>;
}
(iterated, recursively) do:
if (some-conditional) {
<some code>;
xxx;
}
<some other code>;
where xxx is a 'return', or a 'break', or a 'continue'. That way, you can
empty your brain once you hit that, and start with a clean slate.
This is also an example of another thing I do, which is use lots of simple
flow-control primitives; not go-tos (which I abhor), but loop exits, restarts,
etc. Again, it just makes things simpler; once you hit it, you can throw away
all that context/state in your mind.
Keep the control flow structure as simple as possible. If your code is several
levels of indent deep, you have much bigger problems than fitting it on the
screen.
I wrote up a complete programming style guide for people at Proteon working on
the CGW, which codified a lot of this; if there's interest, I'll see if I can
find a copy (I know I have a hardcopy _somewhere_).
Noel
Random832:
... and "p" (which is very minimalistic, despite using a few
V8-specific library features, but V8 isn't in the web-accessible source
archive) from Version 8 research unix.
====
p actually originated outside Bell Labs. I think it was
written in the late 1970s at the University of Toronto.
I first saw it at Caltech, on the UNIX systems in the
High Energy Physics group that I ran for four years.
The first few of those systems were set up by Rob Pike,
who was at Caltech working on his masters degree (in
astrophysics, I think); p was there because Rob brought
it.
For those who don't know it, p has quite an elegant
design. Its default page size is 22 lines, which
nicely fit the world of its time: allowed a couple
of lines of context between pages on a 24-line CRT;
evenly divided the 66-line pages (still!) output
by nroff and pr. It uttered no prompt and required
neither raw nor cbreak nor even no-echo mode: it
printed the final line of each page sans newline;
to continue, you typed return, which was echoed,
completing that line before the next was printed.
It buffered text internally to allow backing up a few
pages, so it was possible to back up even when input
didn't come from a file (something I'm not sure the
more of the time could do).
Internally the buffering was done with a standalone
library that could have been used in other programs,
though I don't know whether it ever was.
p also led me to an enlightening programming story.
One day I was looking over the code, trying to understand
just how the buffering worked; part of it made no sense
to me. To figure it out, I decided to write my own
simple, straightforward version with the same interface;
test and debug it carefully; then lay printouts of the
two implementations side-by-side, and walk through some
test cases. This revealed that the clever code I couldn't
make out in the original was actually buggy: it scrambled
data (I forget the details) when read returned less than
a full buffer.
p (my version) is one of the several programs I bring along
to every new UNIX-derivative environment. I use it daily.
I have also recently noticed a new bug: on OpenBSD, it
sometimes scrambles the last few lines of a file. I have
figured out that that has something to do with whether
fclose (my version uses stdio) is called explicitly or
by exit(3), but I don't know yet whether it's the library's
fault or my own.
Even the simplest programs have things to teach us.
Norman Wilson
Toronto ON
> From: Don Hopkins
> https://stackoverflow.com/questions/268132/invert-if-statement-to-reduce-ne…
Thanks for that - interesting read. (Among other things, it explains where the
'only have one return, at the end' comes from - which I never could understand.)
> Nested if statements have more 'join' points where control flow merges
> back together at the end instead of bailing out early
Exactly. In high-level terms, it's much like having a ton of goto's. Yes, the
_syntax_ is different, but the semantics - and understanding how it works - is
the same - i.e. hard.
Noel
From a mailing list I belong to, a back-and-forth is going on that I am
not involved in. The following sums it up nicely:
> It's really the implied equality that's the problem. For example:
>
> if (flags & DLADM_OPT_PERSIST) {
>
> would be better written as:
>
> if ((flags & DLADM_OPT_PERSIST) == 0) {
Seriously? What do (or would) "original C" programmers think of this? To me, anything non-zero is "true" so the first is perfectly acceptable.
The original assertion in the discussion was that the following is not "right" because of the mixing of bitwise and boolean.
> if ((flags & DLADM_OPT_PERSIST) && (link_flags & DLMGMT_PERSIST)) {
art k.
At the risk of stirring up another hornets nest...
I never accepted the Microsoft
“write functions for maximal indentation, with only one return”
and stick to
“get out if the function asap, try to have success at the bottom of the function”
style.
this means my code is usually fairly narrow.
-Steve
I found head on 3BSD and thought it might be as simple to compile as
cr3, unfortunately, it isn't. I did:
$ cc head.c
head.o?
$ cc -c head.c
head.o?
$ pcc head.c
head.c
head.o?
I thought the assembler, as, was cryptic, at least there you get a one
character error response. What is cc trying to say? Obviously head.o
won't exist unless cc succeeds...
Thanks,
Will
--
GPG Fingerprint: 68F4 B3BD 1730 555A 4462 7D45 3EAA 5B6D A982 BAAF
On 6 November 2017 at 19:36, Ron Natalie <ron(a)ronnatalie.com> wrote:
> It’s worse than that. “char” is defined as neither signed nor unsigned.
> The signedness is implementation defined. This was why we have the inane
> “signed” keyword.
What was that story about porting an early UNIX to a machine with
different char polarity? I dimly recall only a few problems.
N.
> In the meantime, how did folks page through text like man sh
Chuckle. "Text like man sh" wasn't very long back then.
.,.20p was quite an effective pager. It could go backward,
and it didn't wipe out the screen (which can destroy the
record of the problem that caused you to consult a reference).
I still do it from time to time.
Doug
>
> Regarding the links and old bsd's. The binary cr3 on 1bsd works in v7.
> Also, the book I'm reading has a c program that does paging. But, I'm
> always off down the rabbit hole... I tried to compile the cr3.c source
> and I get this error:
>
> # cc cr3.c
> Undefined:
> _fout
> _flush
> _getc
> _end
>
> My understanding is that cc includes libc by default, so these must not
> be in libc. But getc is standard lib, so what am I missing?
That source is for V6 not V7. V6 did not have the stdio lib yet, but a precursor to that.
The binary you are using has the older io routines statically linked in.
Paul
From: Ron Natalie
> We actually still had some real DEC DH's on our system.
> ...
> At least the DZ doesn't loop on the ready bit like the kernel printf
This reminds me of something I recall reading about John McNamara (designer of
the DH11) admitting that he'd screwed up a bit in the DH design; IIRC it was
that if you set the input silo alarm (interrupt) level to something greater
than 1 character, and someone types one character, and then nothing
else... you never get an input interrupt!
(Which is why some Unix DH driver which sets the silo alarm level > 1 - to get
more efficient processing by reducing the number of interrupts _if possible_ -
has to call a 'input characters ready from the DH' routine in the clock
interrupt code.)
IIRC McNamara said he should have included a timeout, so that if the silo
count was non-zero,and stayed that way for a while, it should have caused
a timeout, and an interrupt.
I was just looking for this, but couldn't find it. I thought it was here:
http://woffordwitch.com/McNamaraDH11.asp
but it doesn't seem to be. Does anyone recall seeing this anywhere, and if so,
where? Web search engines didn't turn anything up, alas...
Noel
> From: Clem Cole
> many (most) Unix sites used Able DHDM's which were cheaper than DEC DZ's
Oh, our DZ's weren't DEC, but some off-brand (I forget what). We were too poor
to afford DEC gear! :-) (Our machines, first a /40, and later a /45, were
hand-me-down's.)
Noel
> From: Will Senn
> how did folks page through text like man sh and such before more?
We wrote our own versions of more. Here is one from the roughly-PWB1 systems
at MIT:
http://ana-3.lcs.mit.edu/~jnc/tech/unix/s2/p.c
but on looking at it, I'm not 100% sure it's the one I used there (which is
documented in the MIT UPM).
Here's one I wrote for myself for use on V6:
http://mercury.lcs.mit.edu/~jnc/tech/V6Unix.html#UCmds
before I retrieved all the MIT sources (above), if you want somthing to
actually use on V6/V7.
Noel
I wrote a snippet from my K&R C studies to convert tabs and backspaces
to \t \b to display them, the code looks like this:
/* ex 1-8 */
main()
{
int c, sf;
while((c = getchar()) != EOF) {
if(c == '\t')
printf("\\t");
if(c == '\b')
printf("\\b");
else
putchar(c);
}
}
I'm not looking for code review, but the code is intended to replace the
tabs and backspaces with \t and \b respectively, but I haven't been able
to test it because I can't seem to make a backspace character appear in
input. In later unices, ^V followed by the backspace would work, but
that's not part of v7. Backspace itself is my erase character, so
anytime I just type it, it backspaces :).
Thanks,
Will
--
GPG Fingerprint: 68F4 B3BD 1730 555A 4462 7D45 3EAA 5B6D A982 BAAF
Arthur Krewat <krewat(a)kilonet.net> writes on Mon, 6 Nov 2017 19:34:34 -0500
>> char (at least these days) is signed. So really, it's 7-bit ASCII.
I decided last night to investigate that statement, and updated my
C/C++ features tool to test the sign and range of char and wchar_t.
I ran it in our test lab with physical and virtual machines
representing many different GNU/Hurd, GNU/Linux, *BSD, macOS, Minix,
Solaris, and other Unix family members, on ARM, MIPS, PowerPC, SPARC,
x86, and x86-64 CPU architectures. Here is a summary:
% cat *.log | grep '^ char type is' | sort | uniq -c
157 char type is signed
3 char type is unsigned
The sole outliers are
* Arch Linux ARM on armv7l
* IBM CentOS Linux release 7.4.1708 on PowerPC-8
* SGI IRIX 6.5 on MIPS R10000-SC
for which I found these log data:
Character range and sign...
CHAR_MIN = +0
CHAR_MAX = +255
SCHAR_MIN = -128
SCHAR_MAX = +127
UCHAR_MAX = +255
char type is unsigned
signed char type is signed
unsigned char type is unsigned
The last two lines are expected, but my program checked for an
incorrect result, and would have produced the string "WRONG!" in the
output; no system had that result.
-------------------------------------------------------------------------------
- Nelson H. F. Beebe Tel: +1 801 581 5254 -
- University of Utah FAX: +1 801 581 4148 -
- Department of Mathematics, 110 LCB Internet e-mail: beebe(a)math.utah.edu -
- 155 S 1400 E RM 233 beebe(a)acm.org beebe(a)computer.org -
- Salt Lake City, UT 84112-0090, USA URL: http://www.math.utah.edu/~beebe/ -
-------------------------------------------------------------------------------
Apologies in advance if this is found too far off list or offensive. But
some how I think many on this list might find it amusing. One of my
friends who stayed academic sent this me…. his comment was this surfaced
when students were asking for better music to code to:
https://www.youtube.com/watch?v=0rG74rG_ubs
Warning language is not PG but the it is ‘rapper cursing’ and might even be
allowed over the airwaves without ‘beeping’ by some stations. That said,
I suggest/recommend head phones so not to offend someone by the language.
Many thanks for all that background to the origins of void pointers.
Now for applying that to the early sockets API.
In the first (1981) and second (4.1a, April 1982) revision of that API, socket addresses were passed as a fixed 16-byte structure, essentially the same as the current struct sockaddr. By the time of the third revision (4.1c/4.2, 1983) of that API it had become a variable sized opaque object, passed around as a pointer and a size.
The 1983 4.2BSD system manual (http://www.cilinder.be/docs/bsd/4.2BSD_Unix_system_manual.pdf) describes it that way, e.g. defining connect() as:
connect(s, name, namelen);
int s; caddr_t name; int namelen;
Note the use of caddr_t in the user level signature. Yet, the actual source code for 4.1c/4.2 BSD only uses caddr_t in the kernel (as pointed out on this list), but continues to use struct sockaddr * in the user land interface. It would seem to me today that void * would have been a more logical choice and with void * having been around for about 3 years in 1983, it might have seemed logical back then as well -- after all, this use case is similar to the malloc() use case. It would have avoided the need for a longish type cast in socket api calls (without further loss of type safety, as that was already lost with the required cast from e.g. struct sockaddr_un* to struct sockaddr* anyway).
Related to this, from the "4.2bsd IPC Primer” (1983, https://www2.eecs.berkeley.edu/Pubs/TechRpts/1983/CSD-83-145.pdf , page 5), it would appear that the format of socket addresses was perhaps unfinished business:
- Apparently at some point in time simple strings were considered as unix domain addresses, i.e. not a sockaddr_un structure. Maybe it was limping on this thought that caused the prototype soackaddr structure not to have a size field — having had that would have simplified the signature of many socket API functions (interestingly, it would seem that such a size field was added in 4.3BSD some 6, 7 years later).
- The examples show no type casts. This may have been for didactical clarity, but perhaps it also suggests a signature with void* semantics.
I’d be happy for any background on this.
Also, about halfway down this page http://tech-insider.org/vms/research/1982/0111.html there is mention of CSRG technical report #4, "CSRG TR/4 (Proposals for the Enhancement of Unix on the Vax)”. I think this may be the initial discussion document from the summer of 1981 that evolved into the 4.2 system manual. Would anybody have a copy of that document?
Paul
Ok... so I got vi to work full screen in a telnet session to the DZ port in V8. BTW TERM=vt132 seems to be the best option given the existing termcap. Yay. Now I'm a happy camper with my v8 instance and I'm reading Rochkind's book and learning lots more about everything from unix error codes to system programming etc. V8 is much more familiar ground to me than earlier versions (mostly vi) at this point.
Anyway, my first question of the day is this - is vt132 the best that I can do terminalwise?
I'm not totally up to speed on terminals in ancient (or modern) unices, but I've been reading, and it seems that if I can match a termcap entry to my emulated terminal with a majority of available capabilities, that I would reach screen nirvana in my instance. Now, it also seems like my mac will emulate different terminals and defaults to something like xterm-256. I don't expect color to be supported, but I don't really know. This leads to a second question, if I take an xterm termcap entry and put it in my termcap file, will it work better than the vt entries?
Is my logic correct, or am I thinking incorrectly about this?
Sidenote: now that I'm in v8 and having used v6 and v7 - McIlroy's reader actually is much, much more interesting and handy! Thanks, Doug!
Sent from my iPhone
Sent from my iPhone
What should I set TERM to on V8 to get the best results on my Mac
Terminal. If I set it to vt52, vt100, or vt132, only 8 lines appear at
the bottom of the terminal window (of about 24 lines):
---
root::0:4:m0130,m322:/:
daemon:x:1:1:m0000,m000:/:
sys:sorry:2:1:m0130,m322:/usr/sys:no-login
bin:sorry:3:4:m0130,m322:/bin:
ken:sorry:6:1:m0130,m322:/usr/ken:
dmr:sorry:7:4:mh1092,m069:/usr/dmr:
nuucp::238:1:mh2019,m285,uucp:/usr/spool/uucppublic:/usr/lib/uucp/uucico
uucp::48:1:mh2019,m285,nowitz:/usr/lib/uucp:
"passwd" 20 lines, 770 characters
----
The 8 line window works about like I'd expect - the arrow keys move up
and down until the screen needs to scroll, then B's and A's show up. I'm
used to that on BSD. Using the j and k keys work better and when I
scroll down enough lines, the lines move up to fill the whole terminal
window and the file can be edited in the full window. Is there a better
TERM setting that will get 24 lines to show up on file open?
Thanks,
Will
--
GPG Fingerprint: 68F4 B3BD 1730 555A 4462 7D45 3EAA 5B6D A982 BAAF
As has been explained, void came from Algol 68 via Steve Bourne.
As no object could be declared void, void* was a useless
construct. A kind of variable that could point to any object
was required to state the type of useful functions like qsort.
To avoid proliferation of keywords, the useless void* was
pressed into service. I do not remember who suggested that.
Doug