Getting stdio process ID

Inside IEx when I run Process.whereis(:standard_error) I got the PID, but not when I run Process.whereis(:standard_io) . Who knows why should this happen and how to get the PID from : stdio ?

That is because the i/o system and the error handling behave in different ways. For the error handling there is a central server process registered under the name :standard_error but this is not case for the i/o system. The best way to view an erlang/elixir system to think OS with many tasks and each one has its own i/o system.

You will find a description of this in the link in the erlang rationale I wrote many years ago http://rvirding.blogspot.com/2008/11/erlang-rationale.html . Towards the end it describes the i/o system and the “task” structure in erlang. You actually hit when you do a ^G in the shell.

Strangely enough this was the first time much of the rationale for erlang was actually described, about 10-15 years after it was designed. This was because we had so thought about it and discussed it we felt it was self-evident that this was the way it should be done. We found out later that not everyone thought the same way, some had not grasped the beauty of our design. :smile:

In http://erlang.org/doc/apps/stdlib/io_protocol.html you will find a description of the i/o-protocol as it is today.

9 Likes

Lol, a lot of mathematical equations may be self-evidently beautiful, but that doesn’t mean everyone understands it. :wink:

/me grumbles about pi being the wrong value…

2 Likes

That’s a great response for a simple question Robert, thank you so much.

Just went through the erlang rationale document and I wish there was more where that came from! Thank you very much for sharing this

1 Like

@rvirding it’s possible to do something similar to this but with :stdio?

    Process.unregister(:standard_error)
    {:ok, dev} = StringIO.open("")
    Process.register(dev, :standard_error)
    Code.eval_file(exercise, File.cwd!) |> elem(0)
    captured = StringIO.flush(dev)
    Process.unregister(:standard_error)
    Process.register(original_stderr, :standard_error)

to capture :stdio output in a variable?

Not directly that I know of. Stdio doesn’t work through a registered process but uses the default process group leader. This is where it goes when you read/write without giving an i/o device.

2 Likes

To exemplify @rvirding’s reply, :standard_io translates to Process.group_leader, which can change per process. :standard_error is a local process though. Here is an interesting post on the different things that are done with the group leader: http://ferd.ca/repl-a-bit-more-and-less-than-that.html

Fred’s blog gives a very good description of how it looks and why it looks like that. We had OS inspired thinking behind the design of the system. That’s why I like to say that Erlang is not a language with concurrency but a OS with a language. Elixir buys straight into this though iex is not quite as concurrent as the Erlang shell.

1 Like