Comprehension: reading the evolution of UNIX time-sharing system

Time:2021-7-27

Thesis Name: the evolution of the UNIX time sharing system — Danis M. Ritchie

Dennis rich reviewed the process of creating UNIX with Ken Thompson at Bell Labs, and then introduced the most important parts of UNIX, including:

file system

  1. I-list: an array of i-nodes. Each i-node describes a file. I-node contains the metadata of the file, such as protection mode, type and size, and the physical location of the content
  2. 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)
  3. A special file is used to describe a device. A specific I – number corresponds to a specific device

Process control mechanism

The general steps for the shell to execute the command are as follows:

  1. The shell reads commands from the terminal
  2. Create a new process
  3. Subprocess execute command
  4. At the same time, the shell begins to wait until the subprocess is executed
  5. Shell goes back to the first step

It’s 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

Whatever you enter, 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 process messaging mode in UNIX

A very interesting bug mentioned in the paper is the chdir command at the beginning, that iscdAs a result, only the working directory of the child process has changed, which has no effect on the shell itselfcdIt becomes a special command and is only executed in the current process

An interesting bug is also mentioned in the paper. If there are the following commands in a script file “comfile”:

ls
who

Then we execute in the shell:

sh comfile >output

The expected result islsandwhoBut in fact, UNIX initially saved the IO pointer of the file in the process of executing “open file”, that is, the main shell process, and we used it to perform the write operationshThe sub shell opened by the command, so the IO pointer of the file never changes, resulting inwhoOutput handlelsIn order to fix this problem, they added a table to the system and saved the IO pointers of all open files

As a digression, it suddenly occurred to me that the writing location of the file cannot be specified in elixir. It is OK to check it:

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 mentioned the pipe operator|And C language

Recommended Today

Implementation example of go operation etcd

etcdIt is an open-source, distributed key value pair data storage system, which provides shared configuration, service registration and discovery. This paper mainly introduces the installation and use of etcd. Etcdetcd introduction etcdIt is an open source and highly available distributed key value storage system developed with go language, which can be used to configure sharing […]