Paper Title: The Evolution of the Unix Time-sharing System - Dannis M. Ritchie
Dennis Rich reviewed the history of creating Unix with Ken Thompson and others at Bell Labs, and then introduced the most important parts of Unix, including:
File system
- i-list: An array of i-nodes, each i-node describes a file. The i-node contains the metadata of the file: such as the protection mode, type and size, and the physical location of the content.
- Directory: A special file that contains a series of file names and related i-number. (I think i-number should be the ID of i-node)
- A special file is used to describe the device. A specific i-number corresponds to a specific device.
Process control mechanism
The approximate steps for the shell to execute a command are as follows:
- shell reads commands from the terminal
- Create a new process
- Child process execution command
- At the same time, the shell waits until the child process is completed
- shell back to the first step
It feels very interesting, I simulated it with elixir:
defmodule MF.PC do
def loop do
cmd = IO.read(:line)
pid = self()
spawn(fn ->
exec(cmd, pid)
end)
wait()
end
defp exec(cmd, pid) do
send(pid, {:done, String.upcase(cmd)})
end
defp wait do
receive do
{:done, msg} ->
IO.puts(msg)
loop()
end
end
end
No matter what is entered, the uppercase input is returned.
iex(2)> MF.PC.loop
hello
HELLO
how are u
HOW ARE U
fine
FINE
good bye
GOOD BYE
Well, it's boring, just understand the mode of process message passing in Unix.
A very interesting bug mentioned in the paper is that at the beginning, the chdir command, which is cd
, was also executed as above. As a result, only the working directory of the child process was changed, which had no effect on the shell itself. So they changed cd
Become a special command, which is only executed in the current process.
The paper also mentions an interesting bug, if there is the following command in a script file "comfile":
ls
who
Then we execute in the shell:
sh comfile >output
The expected result is ls
and who
are sequentially written to the output file. But in fact, because Unix initially saved the io pointer of the file in the process of executing the "open file", that is, the main shell process, and The write operation is performed by the sh
we opened with the 060b9e49b86865 command, so the io pointer of the file has not changed, causing the output of ls
who
the output of 060b9e49b86868. In order to fix this problem, they added a table to the system. The io pointers of all open files are saved.
To make a digression, I suddenly thought that in elixir, it seems that the writing location of the file cannot be specified. It is OK to check:
iex(4)> :file.read_file "comfile"
{:ok, "ls\nwho\n"}
iex(5)> {:ok, device} = :file.open "comfile", [:raw, :write]
{:ok,
{:file_descriptor, :prim_file,
%{
handle: #Reference<0.1011150086.1394212882.243351>,
owner: #PID<0.110.0>,
r_ahead_size: 0,
r_buffer: #Reference<0.1011150086.1394212865.243949>
}}}
iex(6)> :file.pwrite(device, 1, 'hello')
:ok
iex(7)> :file.read_file "comfile"
{:ok, <<0, 104, 101, 108, 108, 111>>}
iex(8)> <<104, 101, 108, 108, 111>>
"hello"
Finally, I also mentioned the |
and the C language.
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。