Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

prim_tty: Use os:signal/2 to handle SIGCONT and SIGWINCH #8939

Open
wants to merge 4 commits into
base: master
Choose a base branch
from

Conversation

dumbbell
Copy link
Contributor

Why

Support for SIGCONT and SIGWINCH was added in previous commit to allow any Erlang application to react to them. Unfortunately, setting handlers for these two signals broke prim_tty which installed its own handlers in prim_tty_nif.c.

How

This patch changes prim_tty to use os:signal/2 along with its own gen_event callbacu module to handle the two signals from the Erlang code, like any other Erlang application.

The C code was removed because it is now unused.

Copy link
Contributor

github-actions bot commented Oct 15, 2024

CT Test Results

    4 files    200 suites   1h 50m 32s ⏱️
3 032 tests 2 742 ✅ 289 💤 1 ❌
3 963 runs  3 620 ✅ 342 💤 1 ❌

For more details on these failures, see this check.

Results for commit 7e7e588.

♻️ This comment has been updated with latest results.

To speed up review, make sure that you have read Contributing to Erlang/OTP and that all checks pass.

See the TESTING and DEVELOPMENT HowTo guides for details about how to run test locally.

Artifacts

// Erlang/OTP Github Action Bot

@dumbbell
Copy link
Contributor Author

In this patch, I could not remove the argument to tty_select/3 to make it tty_seject/2 (in both prim_tty.erl and prim_tty_nif.c). Otherwise, I get the following compilation failure:

gmake[3]: Entering directory '/home/dumbbell/Projects/erlang/GIT/lib/kernel/src'
 ERLC	../ebin/os.beam
 ERLC	../ebin/prim_tty.beam
 ERLC	../ebin/prim_tty_sighandler.beam
 VSN	../ebin/kernel.app
=WARNING REPORT==== 15-Oct-2024::10:20:33.211991 ===
The on_load function for module prim_tty returned:
{{case_clause,{error,{bad_lib,"Function not found prim_tty:tty_select/2"}}},
 [{prim_tty,on_load,1,[]},{code_server,'-handle_on_load/5-fun-0-',1,[]}]}

=ERROR REPORT==== 15-Oct-2024::10:20:33.211058 ===
Error in process <0.57.0> with exit value:
{{case_clause,{error,{bad_lib,"Function not found prim_tty:tty_select/2"}}},
 [{prim_tty,on_load,1,[]},{code_server,'-handle_on_load/5-fun-0-',1,[]}]}

=ERROR REPORT==== 15-Oct-2024::10:20:33.214625 ===
** State machine user_drv terminating
** When server state  = {undefined,undefined}
** Reason for termination = error:{'module could not be loaded',prim_tty}
** Callback modules = [user_drv]
** Callback mode = state_functions
** Stacktrace =
**  [{user_drv,init,1,[]},
     {gen_statem,init_it,6,[]},
     {proc_lib,init_p_do_apply,3,[]}]

I submitted the patch with tty_select/3 unused to share the patch and start the discussion.

@dumbbell
Copy link
Contributor Author

Another point of discussion: the added prim_tty_sighandler module sends exactly the same message {ReaderRef, {signal, Signal}} to the Parent PID. I don’t know if that message format is part of a public API or not.

@dumbbell dumbbell marked this pull request as draft October 15, 2024 08:25

static ErlNifFunc nif_funcs[] = {
{"isatty", 1, isatty_nif},
{"tty_create", 0, tty_create_nif},
{"tty_init", 3, tty_init_nif},
{"tty_set", 1, tty_set_nif},
{"tty_read_signal", 2, tty_read_signal_nif},
{"setlocale", 1, setlocale_nif},
{"tty_select", 3, tty_select_nif},
Copy link
Contributor

@jhogberg jhogberg Oct 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I submitted the patch with tty_select/3 unused to share the patch and start the discussion.

Change this to {"tty_select", 2, tty_select_nif}, and in that function, change argv[2] to argv[1] to account for the removed argument in the middle. :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’m not sure I understood. I don’t see the difference in the {"tty_select", 3, tty_select_nif}, you typed compared to the code (I didn’t modify that line).

Do you suggest that the C code still exposes tty_select/3 but only uses the first two args, then the Erlang code calls it as tty_select/2?

Copy link
Contributor

@jhogberg jhogberg Oct 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I noticed I hadn't updated it to 2 a few seconds after posting. Guess you missed my edit :-(

{"tty_select", 3, tty_select_nif}, means that tty_select/3 has to be present in the module for NIF loading to work (Edit: you can read it as "patch the function tty_select/3 with tty_select_nif").

If you want tty_select/2, change that line to {"tty_select", 2, tty_select_nif},.

Copy link
Contributor Author

@dumbbell dumbbell Oct 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That’s what I did yesterday but it fails to compile with the error pasted above.

I see that prim_tty.beam is present in the bootstrap. I looked at HOWTO/BOOTSTRAP.md but it says that it shouldn’t be modified during development.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes. To make this work while testing, run ./otp_build update_bootstrap --no-commit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I don’t have any planned changes left, but I don’t know what to do with CI :-) Do you want me to mark the pull request as ready for review?

Copy link
Contributor

@jhogberg jhogberg Oct 15, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With ./otp_build update_primary --no-commit and an improvement to take into account that erl_signal_server may not be running, I can compile locally with tty_select/2. The interactive_shell_SUITE is still happy.

That's odd, unless I'm missing something erl_signal_server should've been started before user (and thereby user_sup -> user_drv -> prim_tty), and I'm not sure that ignoring its absence is the right thing to do. @garazdawi ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok. I don’t have any planned changes left, but I don’t know what to do with CI :-) Do you want me to mark the pull request as ready for review?

Sure :-)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's odd, unless I'm missing something erl_signal_server should've been started before user

That’s how I interpret the compile-time error: gen_event:delete_handler/3 throws a noproc error. Perhaps this is a specific situation during the compilation if prim_tty from bootstrap is used?

Because with the interactive_shell_SUITE or manual testing with an Erlang shell, I didn’t hit this error.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The signal server is not started when -mode minimal is passed, so that is why it fails with erlc as it uses that flag. I pushed a commit that moves when it is started so that it is always present.

@dumbbell
Copy link
Contributor Author

Now I see that it fails to build on CI, even though interactive_shell_SUITE passes successfully locally. There must be something I didn’t get right with the build system :-)

@dumbbell dumbbell marked this pull request as ready for review October 15, 2024 12:34
@garazdawi garazdawi self-assigned this Oct 15, 2024
@garazdawi
Copy link
Contributor

I pushed some commits that fix some issues on windows and included an updated bootstrap so that github ci should work better now. Now time to sleep.

Comment on lines 33 to 36
ShortSignal = case Signal of
sigcont -> cont;
sigwinch -> winch
end,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no need to keep the old protocol, so you can send sigcont/sigwinch directly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I updated the patch to address your feedback.

Note that I rebased the branch as I usually do and force-pushed. I’m sorry, I forgot that you had a local working copy, you already pushed commits and you may have uncommitted changes…

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great! No worries about the force push.

dumbbell and others added 4 commits October 16, 2024 17:50
[Why]
Support for SIGCONT and SIGWINCH was added in previous commit to allow
any Erlang application to react to them. Unfortunately, setting handlers
for these two signals broke `prim_tty` which installed its own handlers
in `prim_tty_nif.c`.

[How]
This patch changes `prim_tty` to use `os:signal/2` along with its own
gen_event callbacu module to handle the two signals from the Erlang
code, like any other Erlang application.

The C code was removed because it is now unused.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants