-
-
Notifications
You must be signed in to change notification settings - Fork 444
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
Implement platform-independent signal lists #1206
base: main
Are you sure you want to change the base?
Conversation
It is possible to get the list of signals with their associated signal numbers in a platform-agnostic way using just the C preprocessor. However, the preprocessor is nor able to sort the list by signal number. Three solutions are viable: 1. Leave the list unsorted, or sort by signal name. 2. Sort the list on program startup. 3. Sort the list at compile-time using gross hacks. In the discussion of bug htop-dev#1200, a preference for compile-time sorting emerged. To do that, a two-step approach is needed: A C source with the signal definitions is preprocessed, the output filtered through `sed` and `sort` and then included from another, final, C source file. As of this commit, the created list does not replace signal lists in from the `Platform.c` files in individual platform subdirectories, and therefore is not used in the final binary.
Previously, each platform hardcoded its own signal list. However, at least on Linux, the signal numbers and even the available names vary between architectures, requiring a more clever approach. A platform independent code now replaces the individual lists for all platforms. This may cause minor changes in the UI. For example, Solaris used to display duplicate signal names as "22 SIGPOLL/IO", but now the panel will show two entries, "22 SIGIO" and "22 SIGPOLL", matching behavior on other platforms. Fixes htop-dev#1200
|
||
SUFFIXES = .i | ||
# Preprocessing a list of signals to get their numbers from the headers. | ||
.c.i: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.c.i: | |
signals/SignalList.in.i: signals/SignalList.in.c |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the suggested form, this won't work with out-of-tree builds. Why not use the suffix rule? I believe that suffix rules are idiomatic for Automake and the recipe is generic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The suffix rule would affect all files with the same extension in the build tree. Since we have just one file that needs such preprocessing, a suffix rule would be a bad idea.
And yes, the dependency line should be $(srcdir)/signals/SignalList.in.c
instead.
Firstly, thanks for your work that proves my idea would work. However I think you made your C preprocessor and sed script a little more complicated than necessary. I think the HTOP_SIGENTRY macro and the first sed script can be simplified to something like this (the code is untested): // It is unlikely that braces would appear in SIG* macro
// definitions; hence we use braces as field delimiters.
#define HTOP_SIGENTRY(x) __htop_sigentry__ { x }{ #x }
|
Thank you for your swift reaction and the comments!
That was my initial implementation as well, however, unlikely is not impossible and once I wrote code to at least detect extraneous braces and report an error, it quickly grew beyond the current implementation. I'd like the code to be robust, especially since braces can enclose complex expressions with multiple statements inside. I can see that somebody could try to use that to e.g. track uses of deprecated signals, so it is not entirely unlikely for such code to appear. At the very least, the code should not break when that happens. So I still prefer my solution, even though it is longer, I believe the error checking is worth it. That being said, I can redo the pull request with your suggestions if you want – let me know what your preferences are, you're the maintainer here. :-)
As written, this requires quadratic space to reach the first sigentry, though a
A possible fix is to add
after the last |
How is it possible for a I see the possibility for a signal name macro to be defined like
Okay. Thanks for catching those.
Yes. When I wrote the draft code I forgot to remove the lines beginning with
|
There is (as usual :-) ) a GNU extension for this: |
Fine, but I have another idea to make it: #define HTOP_SIGENTRY(x) __htop_sigentry__ $ x $ #x
|
An alternative might be to test a set of signal IDs for availability, e.g. via |
@cgzones Checking signal availability via such API calls would add overhead in run time; plus configure script can't check those when cross-compiling. |
You only have to do this once at startup and it's not like we are iterating millions of signal names there. I think that cost is negligible.
Which should just trigger a static fallback, we would need anyway in case that API was unavailable for some reason. Overall, IMO the current version of the patch is a bit over-engineered and a simpler "check for target arch, switch to appropriate list depending on that" would be better. |
This pull request implements platform-independent lists of signals, sorted by the signal number at compilation time, as discussed in bug #1200. The change is implemented for all platforms, but I only tested it on Linux, so more testing is definitely required.
The potentially breaking changes I'm aware of are:
#include <signal.h>
and I'm not sure how it currently works (it appears not to includesignal.h
at all), so my change might break that.signal.h
header is broken or unavailable. It is possible to define-protect all signals save e.g. SIGINT, which should be defined everywhere.#define
d as numbers, not e.g. as#define SIGINT (SIGHUP+1)
. If this assumption is incorrect, the code would issue a compile-time warning and produce an unsorted list.Stylistic and nitpicky issues:
configure.ac
andMakefile.am
works on my machine, it may not be entirely correct or idiomatic.sort
is probably unnecessary, since the test doesn't stop the build ifsort
is not present, instead setting theSORT
variable to justsort
instead of the path. The test forsed
works the same, but it at least tries to find a version ofsed
that actually works. It might be better to write it assed
scripts are arguably ugly. However, it's a tool that's available everywhere and should just work, unlike e.g. Python or Perl. Perhaps AWK would be a better choice, but I don't speak that language.