> the storage pointed to by the argument will be modified, and the string literal that is passed is not guaranteed to be placed in a modifiable data region. I’m surprised this worked in Version 7 Unix.
PDP-11 had only 8 8kB "pages" (segments really) available for a program. Pages could be marked read-only, but making one read-only was a huge expense. A common trick was to smash code and data that were only used when initialising the program.
Wouldn't the rodata and text segments be shared across instances of the same program though?
That would seem like a straightforward optimisation, but then the code presented in the article would break subtly if you were to invoke ed twice at the same time since both instances would try to modify and use the /tmp/eXXXXX string at the same time.
The text segment was shared, the data segment was not shared. There was a single data segment containing both the initialised and uninitialised data, there was no rodata. Rodata came with ELF, it was never in a.out.
Given that Unix was primarily a multiuser system in those days, that would be a rarely useful optimisation. Especially if you expected most people to run ed at all times, since it was, after all, the standard editor.
Quite the opposite actually, this optimisation is only useful if you intend to run several instances of the same program. Otherwise each instance has its own copy of the code and rodata, therefore wasting memory.
It's one of the advantages of using shared libraries as well, several programs can share the same code and read-only data, saving in storage and memory space.
Would this code not have run on the VAX 11-780? I think the 780 had a 512-byte page size (and therefore I think it ought to have offered write protection at that granularity).
Can't remember the VAX page size, but it doesn't matter (see my other comments) because Unix of that era didn't have a rodata section. There was a single data section (eventually a.out separated data and bs , but data was still writable) that obviously couldn't have been read-only.
Rodata sections are a modern idea, the a.out binary format never had it. A.out explicitly documents the data section as writable. Rodata came with ELF.
PDP-11 had only 8 8kB "pages" (segments really) available for a program. Pages could be marked read-only, but making one read-only was a huge expense. A common trick was to smash code and data that were only used when initialising the program.