Anonymous | Login | 2024-10-14 23:24 UTC |
Main | My View | View Issues | Change Log | Docs |
Viewing Issue Simple Details [ Jump to Notes ] | [ Issue History ] [ Print ] | ||||||
ID | Category | Severity | Type | Date Submitted | Last Update | ||
0001138 | [1003.1(2016/18)/Issue7+TC2] System Interfaces | Editorial | Enhancement Request | 2017-04-27 12:02 | 2024-06-11 09:09 | ||
Reporter | joerg | View Status | public | ||||
Assigned To | |||||||
Priority | normal | Resolution | Accepted As Marked | ||||
Status | Closed | ||||||
Name | Jörg Schilling | ||||||
Organization | |||||||
User Reference | |||||||
Section | System Interfaces | ||||||
Page Number | new interface | ||||||
Line Number | newinterface | ||||||
Interp Status | --- | ||||||
Final Accepted Text | Note: 0005338 | ||||||
Summary | 0001138: Add strsignal(), sig2str() and str2sig() to the standard. | ||||||
Description |
Solaris contains: char * strsignal(int signum) signal number -> sig destription int str2sig(const char *s, int *sigp) signal name -> signal number int sig2str(int i, char *s) signal number -> signal name We should add these interfaces to permit e.g. the kill command to be implemented with POSIX interfaces. |
||||||
Desired Action |
Add strsignal() to string.h Add sig2str() and str2sig() to signal.h Add the three functions to the system interfaces descriptions. We might be able to use the Solaris man pages as a starter for the text. |
||||||
Tags | issue8 | ||||||
Attached Files | |||||||
|
Notes | |
(0003678) joerg (reporter) 2017-04-27 12:11 |
I forgot: add SIG2STR_MAX to signal.h |
(0003679) schwarze (reporter) 2017-04-27 13:32 |
schwarze@isnote $ man strsignal | col -b | sed -n '/^STAN/,$p' STANDARDS The strsignal() function conforms to IEEE Std 1003.1-2008 (POSIX.1). HISTORY The strsignal() function first appeared in AT&T SystemV Release4 UNIX and was reimplemented for NetBSD 1.0. OpenBSD 6.1 June 5, 2013 OpenBSD 6.1 http://pubs.opengroup.org/onlinepubs/9699919799/functions/strsignal.html [^] Public functions str2sig(3) or sig2str(3) do not exist in FreeBSD or NetBSD, and definitely not in OpenBSD. Regarding DragonFly and the Linux man pages project, i don't see these functions in the manual pages either (while i do see strsignal(3) there). In FreeBSD, the name str2sig() clashes with at least one static symbol (in usr.bin/fstat/fuser.c). Probably not a big problem, just mentioning it for completeness. The only systems where i do see evidence for public str2sig(3) and sig2str(3) are illumos and Oracle Solaris 9 to 11. Is that sufficiently common for standardization? Just asking... As far as i understand, establishing new interfaces is not the typical job of POSIX. |
(0003680) joerg (reporter) 2017-04-27 14:15 |
Thank you for the hint that I missed to find strsignal() in the standard ;-) In order to ad a new interface, there should be a need for that interface andI believe that the two functions would help programmers to write portable programs in special as many singal numbers are not unique across platforms. |
(0003681) kre (reporter) 2017-04-27 15:47 |
Re (note 3680) In order to ad a new interface, there should be a need for that interface Quite correct, but "I believe" is not evidence of that. The way to do it is to actually implement the interface, and have it actually used (as note 3679 suggests). That way we get some real evidence that the interface proposed is the correct one. For example, I wouldn't implement either of the 2 proposed new functions with the function prototype you gave, for me it would be ... int str2sig(const char *s) signal name -> signal number int sig2str(int i, char *s, size_t len) signal number -> signal name (and that still leaves aside the choice of names, str_to_sig() (etc) would be another possibility - but with naming it tends to be whatever becomes popular first, as there is no one right answer.) For str2sig() a return value of 0 would indicate an error (no such sig name) as the one thing we know about signal numbers is that 0 is not one of them. And for sig2str() we need a buffer length arg, as while we might "just know" that SIG2STR_MAX is sufficient, implementing things that way means that there's no possibility to ever increase that value (or binary compat/safety is lost.) The constant can still exist, but it should just be for users to size the buffer, not for the internals of the function to use. But all of this is just my opinion, the only way we ever really know what works is for users to use the interface, and be happy enough that they use it (not just reinvent it) and don't keep asking for changes. |
(0003682) jilles (reporter) 2017-04-27 16:30 |
Various BSD systems provide an extern const char * const sys_signame[]; from libc, such that sys_signame[SIGHUP] is "HUP", etc. However, a function interface is superior to an array. Using common ELF linking, non-PIE executables use copy relocations to access the array, which means that changing its size is not binary compatible, and exporting an array like this forces the inefficient pattern of pointers to static data in a shared library, which need to be relocated in every process using the library even if that process does not use the array at all. Note that signal names, unlike strsignal() messages, are not translatable. Existing software that needs to work with signal names tends to either use interfaces like sys_signame and sig2str/str2sig, or create its own table using a list of signals that may exist, like char *table[] = { #ifdef SIGFOO [SIGFOO] = "FOO", #endif ... } |
(0003685) joerg (reporter) 2017-05-04 10:57 |
For making portable shell implementations easier, it would be a good idea if the standard also adds a "NSIG" definition that may redirect to a getconf() call. |
(0003686) kre (reporter) 2017-05-04 12:29 |
NSIG is not useful unless we also make assumptions about the values used for the signal numbers, like that they are from 1..NSIG which the standard avoids doing (and should continue to do.) I am soon going to delete the earlier note I posted with the proposal I made to NetBSD developers, and replace it with the current (simpler) version, which has no need of an NSIG definition. |
(0003688) kre (reporter) 2017-05-10 02:00 edited on: 2017-05-10 02:31 |
Note that this note replaces an earlier note (3683, and 3684) which described an earlier proposal. I have just added, to NetBSD, functions as described in the man page I am including in this note. If there is ever a desire to add functions for this purpose to POSIX, please consider these as alternatives to str2sig() and sig2str() as included above (I am not requesting that they actually be included, just that I believe these are better than those...) Complete source (such as it is - quite *BSD dependent, as they use sys_signame as described by Jilles in note 3682) is available (for a time anyway) from ftp://munnari.oz.au/kre/signame.tgz [^] [^] (files unpack into the current directory, a test program can be built, on BSD systems anyway, by "cc *.c" - there is no Makefile.) Note at the end where it says "First appeared in NetBSD 8.0" - 8.0 has not been released yet (getting closer, but still some way away.) The functions described are all pure, and thread safe (though depending upon the implementation might need some internal locking while acquiring the data from the system). The current NetBSD implementations are async-signal-safe, but I would not specify them that way, in order to allow the implementation to use whatever means it desires to initialise its state. And in any case, there is almost no possible need for these functions in a signal handler, the signal number is provided (so we know its number, and that it is valid) and while the name may be of interest, the results of strsignal() are far more likely to be relevant. kre NAME signalname signalnumber signalnext -- convert between signal numbers and names LIBRARY Standard C Library (libc, -lc) SYNOPSIS #include <signal.h> const char * signalname(int sig); int signalnumber(const char *name); int signalnext(int sig); DESCRIPTION The signalname() function takes a signal number sig, and returns the name of that signal. The name returned is locale independent, and can be the string representation of one of the signal names from <signal.h> such as SIGHUP, SIGSTOP, SIGKILL, or some similar name, but does not contain the leading ``SIG'' prefix. The return value of signalname() is NULL if sig does not represent a valid signal number, or if the signal number given has no name. The signalnumber() function converts the signal name name to the number corresponding to that signal. The name is handled in a case-insensitive manner. Any leading ``SIG'' prefix in name is ignored. The signalnumber() function returns the signal number, or zero (0) if the name given does not represent a valid signal. The signalnext() function takes a signal number, and returns the number of the next available bigger signal number. When no higher signal numbers remain, it returns zero (0). The parameter sig can be given as zero (0), to obtain the smallest implemented signal number. The signalnext() function returns minus one (-1) on error, if the given signal sig is neither a valid signal number, nor zero. It returns zero when the input signal number, sig, is the biggest available signal number. Otherwise it returns the signal number of an implemented signal that is larger than sig and such that there are no implemented signals with values between sig and the value returned. The signalnext() function can also be used to determine if a non-zero signal number is valid or not (0 is always invalid, but cannot be detected as such this way.) Given the non-zero signal number to check as sig, if signalnext() returns anything other than minus one (-1) then sig represents a valid signal number. If the return value is -1 then sig is invalid. SEE ALSO kill(1), intro(2), psignal(3), strsignal(3) HISTORY The signalname(), signalnext() and signalnumber() functions first appeared in NetBSD 8.0. |
(0004148) Don Cragun (manager) 2018-10-11 15:48 |
After discussing this in the 2018-10-11 conference call, we have asked the Open Group OR to see if The Open Group would sponsor adding sig2str() and str2sig() to a future revision of the standard. |
(0004212) ajosey (manager) 2019-01-16 13:36 |
The Open Group Base Working group has agreed to sponsor the addition of sig2str() and str2sig() as a new work item. The next stage will be to develop manual page entries for review and eventual approval at The Open Group. |
(0004975) geoffclare (manager) 2020-09-08 09:30 edited on: 2020-10-23 10:57 |
Suggested changes to go into The Open Group company review... On page 333 line 11275 section <signal.h>, add: [CX]The <signal.h> header shall define the following symbolic constant. The value shall be suitable for use in #if preprocessing directives: On page 338 line 11462 section <signal.h>, add: [CX]int sig2str(int, char *);[/CX] On page 338 line 11485 section <signal.h>, add: [CX]int str2sig(const char *restrict, int *restrict);[/CX] On page 339 line 11501 section <signal.h>, add sig2str() to SEE ALSO. On page 494 line 17105 section 2.4.3, add sig2str() to the list of async-signal-safe functions. On page 1950 insert a new sig2str page: NAME sig2str, str2sig -- translate between signal names and numbers SYNOPSIS #include <signal.h> [CX]int sig2str(int signum, char *str); int str2sig(const char *restrict str, int *restrict pnum);[/CX] DESCRIPTION The sig2str() function shall translate the signal number specified by signum to a signal name and shall store this string in the location specified by str. The application shall ensure that str points to a location that can store the string including the terminating null byte. The symbolic constant SIG2STR_MAX defined in <signal.h> gives the maximum number of bytes required. RETURN VALUE If signum is a valid, supported signal number (that is, one for which kill() does not return -1 with errno set to [EINVAL]), the sig2str() function shall return 0; otherwise, if signum is not equal to 0, it shall return -1. ERRORS No errors are defined. EXAMPLES None. APPLICATION USAGE None. RATIONALE Historical versions of these functions translated a signum value 0 to "EXIT" (and vice versa), so that they could be used by the shell for the trap utility. When adding the functions to this standard, the standard developers felt that they should be aimed at more general-purpose use, and consequently requiring this behavior did not seem appropriate and so the behavior in this case has been made unspecified. FUTURE DIRECTIONS None. SEE ALSO kill(), sigaction(), strsignal() CHANGE HISTORY First released in Issue 8. Add sig2str() to the SEE ALSO section for each function page listed in the sig2str() SEE ALSO above. On page 3792 line 130152 section E.1, add sig2str() and str2sig() to the POSIX_SIGNALS_EXT subprofile group. |
(0004976) kre (reporter) 2020-09-08 15:32 |
Re: Note: 0004975 Aside from most likely being an exact specification of what the Solaris (maybe linux too) implementations happen to do, that is wildly over specified for the purposes required here, and also technically wrong. I cannot even begin to imagine where a sig2str() function would be returning "EXIT" for "signal" 0 - 0 as a trap number relating to EXIT is a shell function, and has no place at all in the generic OS interface. The XBD page for signal.h says: The value 0 is reserved for use as the null signal (see kill( )). which has no relationship at all with anything relating to exit. But I suppose the Solaris function was defined for use in "trap -l" in sh, and so it was convenient to have 0 return "EXIT". That implementation quirk has no business being standardised here. Aside: note that strsignal() and psignal() (and psiginfo()) which are functions initially designed for regular applications to use aren't required to return anything related to "exit" for "signal number" 0. Beyond that, I see no particular reason why the exact signal named from signal.h (with the SIG removed) are required to be returned - what's important is that the names returned by sig2str() be able to be used as input to str2sig() and result in the correct signal number being returned. Far worse (as far as overspecification goes) is the description of how the real time signals are to be handled. Why would anyone want to specify things in that much detail? Aside from that happening to be what the Solaris implementation does? Assuming that an implementation decides to return strings in the RTMIN+n form, why cannot it always reurn RTMIN+n for all real time signals, for n in the range [0..SIGRTMAX-SIGRTMIN] if that's what the implementation prefers, or RTMAX-n (same range) or split the +n/-n variants anywhere else it pleases? What conceivable reason is there for mandating that particular split. That is, even if it were correct, if SIGRTMIN==33 and SIGRTMAX==64 then (SIGRTMIN+SIGRTMAX)/2 == 48.5 and since signals all have integral values, that means that "If signum is between SIGRTMIN+1 and (SIGRTMIN+SIGRTMAX)/2 inclusive" means signals 34..48, and (SIGRTMIN+SIGRTMAX)/2 + 1 == 49.5, which means that "If signum is between (SIGRTMIN+SIGRTMAX)/2 + 1 and SIGRTMAX-1 inclusive" covers signals 50..63. What is to be done with 49? Now obviously one could stick floor() calls around the results of the division and avoid that issue, but much better would simply be to state (which is actually already there) that for any signals which exist, but which don't have names in signal.h an implementation defined string shall be returned. That then covers the real time signals, and allows RTMIN+n RTMAX-n or anything else the implementation chooses to provide - as long as the string returned when handed to str2sig() will return the correct value. The NetBSD implementation (which is as described in Note: 0003688 except that it now also allows the RTMIN+n and RTMAX-n forms as args to signalnumber()) has real individual names for the real time signals. OK, they're boring names, but they are a name for each signal. And that's what signalname() returns for the real time signals (and signalnumber() translates back to the appropriate number). Why should we be prohibited from returning those names and be required to return the RTMIN+n (etc) format? Just delete 90% of what is there, and say what the functions do, and what the requirements on the implementation really are (justifiable requirements) and leave out all of the Solaris implementation detail. Next, why are we presuming that all values from 1 .. NSIG_MAX represent signals? There's nothing elsewhere in the standard that requires that, yet the text here says: If signum is between 1 and {NSIG_MAX}-1 inclusive, is either less than SIGRTMIN or greater than SIGRTMAX, and is not equal to one of the signal numbers for which a symbolic constant is defined in the <signal.h> header, the stored string shall uniquely identify the signal number signum in an unspecified manner. which is saying that every value from 1 to NSIG_MAX-1 is required to be a valid signal number? Why is that? My impression (which might be wrong) is that FreeBSD have the "normal" signals in the block 1..n (for some n) and the real time signals in a block which I think started at about 2*n (give or take a few) - which is actually a very reasonable thing to do, as it allows more signals to be added, in the same basic range as the existing ones, without requiring the real time signals be renumbered (that is, doesn't have the real time signals in the middle between different groups of non-real-time signals). Next: Next, and perhaps worst, in this day and age, we should not be standardising any interfaces where the application passes in a pointer to a string which is simply assumed to be big enough for the result. That's insane. I appreciate that implementations which defined such interfaces in the past, when we didn't know better, are stuck with supporting them forever, but there's no reason we should be encouraging applications to use this nonsense, At the very least the function should take a buffer length arg, to indicate to the size that is available for the functions to write in (but that would mean inventing something new, as there are no known implementations that work like that) - but there is no reason that sig2str() (unlike say strsignal()) could not return a pointer to a const char * - there aren't all that many signals in any implementation (most < 100, but even 1000 would be manageable) that the implementation cannot simply build a table of string names (including each "RTMIN+1" "RTMIN+2" ... if that is what it decidesto use) and return a pointer to the one of those that represents the signum, and use the same table to translate the name back to a number for str2sig(). That's a much nicer and safer interface, and is trivial to implement (it is also faster as there is no string copying involved). strsignal() can't work that way, as it returns a locale dependant string, but sig2str() does not, so compiling the names into read-only memory (ie: const char[]) in the function is easy and safe here (it is also thread safe, and because of the "const" there's no issue with what happens if the application mofifies the result (it cannot). The NetBSD functions mentioned in Note: 0003688 do exist (and have for multiple NetBSD releases now) and work that way without issue (of course, they don't handle the EXIT nonsense). More trivial issues: If str points to a string containing the name of one of the symbolic constants defined in the <signal.h> header that expands to a signal number, One of those constants, if Note: 0004975 was accepted as written, is SIG2STR_MAX which is likely to have a value (in most implementations) somewhere around 8..10 (enough to hold RTMAX-nn\0) which is typically longer than any SIGxxxx with the SIG part removed. Those values are signal numbers (or at least it is possible to read the text that way) as signal numbers are simly integers between 1 and NSIG_MAX-1 (incl) and NSIG_MAX is going to be much bigger than 10 (it must be, there are more than 10 defined signals). Aside from that one, signal.h also contains SIGEV_NONE SIGEV_SIGNAL and SIGEV_THREAD, the latter two of which are also likely to be valid signal numbers (and all might be). On NetBSD they are 0, 1 and 2 resp. 1 and 2 are valid signal numbers. There's also SIG_IGN which is typically 1, though that one is less clear, as its value isn't an integer, but cast to be a pointer. I doubt that the intent is that any of these are intended to be valid inputs to str2sig() - so assuming that the text needs to say any more than that the range of inputs to str2sig() is any different than the outputs from sig2str() (whatever that might be) it needs to be written more precisely. But, even more trivially,to continue that quote (expans it) If str points to a string containing the name of one of the symbolic constants defined in the <signal.h> header that expands to a signal number, without the SIG prefix, that's a very poorly constructed sentence, assuming it did not need to be rewritten anyway, then something more like If str points to a string containing the name of one of the symbolic constants that expands to a signal number, as defined in the <signal.h> header, without the SIG prefix, [aside; apart from "that is what the solaris implementation did" why are we so hung up on "without the SIG prefix" ? Why not make that implementation defined?] One more not-really related issue that I'll mention, the psignal() function has no page of its own, it appears in the psiginfo() page only. Most of the times when multiple functions are defined in one page in XSH, the ones that come after the first are given pages that just say (in this case) "see psiginfo" Finally, I continue to object to NSIG_MAX even existing - it is just a mild objection, since I can easily set it to INT_MAX (with a suitable definition of sigset_t which is easy to do) and forget it (or perhaps UINT_MAX). That that limits the signals to no more than INT_MAX-1 (or UINT_MAX-1) because NSIG_MAX for no particularly good reason is the highest possible signal number, plus 1, is irritating, but we can probably live with that. Constants like that (unlike the dynamic values returned from sysconf()) make maintaining binary compatibility much harder than it otherwise needs to be - some app is built when NSIG_MAX was 128 and then we decide we want to change it to 256 - app breaks. So once set it can never be altered again. Better not to have constants like that at all - especially not newly invented ones that aren't required for any API compat with the past. |
(0004977) joerg (reporter) 2020-09-08 21:37 |
Just in case this is not known... str2sig() and sig2str() exist since 32 years while it seems that the netbsd functions apparently have been been created just at the time when Note: 0003688 was entered. So str2sig() and sig2str() are 29 years older and a web search for these functions results in the related man pages. A web search for "signalname" does not result in a pointer to the related man page. I guess that no existing portable software supports the signalname() interface. And BTW: stg2str(0, ...) returns "EXIT" as expected by the shell. |
(0004978) kre (reporter) 2020-09-08 22:49 |
Re: Note: 0004977 str2sig() and sig2str() exist since 32 years I expect that's true, but in all that time, they've hardly been used, or they would have been in the standard from the beginning. The design of these functions (as with others of that vintage) also leads a lot to be desired. while it seems that the netbsd functions apparently have been been created just at the time when Note: 0003688 was entered true as well, the requested functions were designed in a time when there were no real concerns about defensive programming, and everyone knew that if a "big enough" buffer was needed, one would be provided. gets() was still a popular function back then. When I saw this issue I set out to see if there might not be a better interface design that would solve the same problem, and after some discussions on the NetBSD mailing lists, the result is what was implemented, and then was published here in Note: 0003688 I'm not seriously expecting anyone to add the netbsd functions to posix, or not any time soon - they haven't been around long enough, and aren't widely supported enough. I have no idea how web search engines decide what to show, or how they locate man pages - the netbsd functions man page (one page for all 3 functions) has been around, and is and has been available on the web for several years now. You can find them at https://man.netbsd.org/signalname.3 [^] They used to also be available via man-k.org but that seems to be unavailable now. But this is I think the crux of this issue: And BTW: stg2str(0, ...) returns "EXIT" as expected by the shell. Yes, that has been made clear. And what that says is that these functions are really internal shell interfaces. Like any other internal shell implementation detail, they have no real reason to appear in the standard. As defined, they're essentially useless to anything other than the shell, and its (usually) built in commands (a couple of them) and a few other commands that are clones of those. They have no general purpose applicability at all. The only difference between these functions, and some other local function in the shell is that they can vary from system to system (but they're not the only instance of that). The right thing to do is simply reject this enhancement request, and not add these functions to the standard at all. I understand how it is useful for a shell implementation to be able to depend upon functions like these existing for each system the shell is to be used upon, but that is not, IMO, a good enough reason for them to appear here. If anyone ever finds a general purpose use for being able to translate between signal names and their equivalent numbers (which can't be achieved by simply including <signal.h> and referring to the defined names) then perhaps a new interface will be designed - maybe something like the NetBSD ones, maybe not, and perhaps if that need becomes widespread enough, in some later version of the standard, a decade or two from now, something could be added. But whatever that looks like, the chances of it (them) having an interface anything like sig2str() is close to zero. But I'm not going to hold my breath, there is little need for the functionality provided (outside the shell and related commands) so I can't see anyone bothering. |
(0004980) joerg (reporter) 2020-09-09 11:27 |
Re Note: 0004978 str2sig() and sig2str() are widely used since approx. 1995 I guess this is quite a while now. Regarding what is in the standard and what is not..... In 1988/1992, people had problems to get to a standard at all and with respect to the bug fixes in the past few years, my impression is that many people did not read the standard in depth in former times, so problems in the standard have not been discovered. Look e.g. at the waitid() interface that has been added early but nobody discovered that someone forgot to change the documentation for exit() to mention that the masking with 0xFF only is in effect if the exit status is retrieved by the historic functions. This is where most programmers are srtill living in the 1970s, probably caused by plenty of incorrect implementations in the past Look e.g. at the strl*() functions that have been introduced around 1995 by OpenBSD (IIRC), rated highly useful and copied by nearly any platform but Linux. The reason why it has not been added to POSIX so far is that one person claimed that the interface is bad, while it is still the best related interface we have in the UNIX world... The interesting aspect of this meta discussion is that in the 1980s, it usually did take 1-2 years for a new useful idea to appear in other UNIX versions as well. Not that we have a standard, this takes longer. I would be happy, if problems like this one could disappear. |
(0004981) geoffclare (manager) 2020-09-10 10:59 |
I have edited Note: 0004975 to address some of the points raised in Note: 0004976. In particular:
|
(0004982) kre (reporter) 2020-09-10 13:05 |
The changes mentioned in Note: 0004981 look good, and resolve the trivial issues they address, but of course do nothing to address the substantial issues. One other thing I failed to notice before, you're making the proposed new interfaces async signal safe. Is that wise? While the actual (current) implementation of the NetBSD variants for the same functionality is, and I assume the Solaris version is as well, that is one thing I did not promise about the NetBSD implementation. It is entirely possible that an implementation of these might obtain the data required from some external source (a system call, a file, or ...) and need to malloc memory to save that data for later calls (there's no question of free() being needed - once obtained it would simply remain). An implementation like that is future-proof for statically linked programs, otherwise if simply using compiled-in data, what these functions return are the names/numbers of signals that existed at the time the application was compiled (perhaps years, or decades, ago) rather than the current versions. Or is the plan here to require all implementations to copy the implementation method of the SysVR4/Solaris version, as well as its broken interface ? |
(0004983) joerg (reporter) 2020-09-10 13:30 |
Statically linked programs are not future proof. Solaris has given them up 15 years ago, after introducing a new desaster revovery method based on shared libraries. All you need is a known backup copy of the last working libc and for the really hard cases an alternate failproof boot environment. The combination of a kernel and it's related shared libc provides the POSIX interfaces. If you do this, the SVr4 method that does not need malloc() is just fine. |
(0004984) geoffclare (manager) 2020-09-10 14:31 edited on: 2020-09-10 14:31 |
Re: Note: 0004982 In the current proposal only sig2str() is required to be async-signal-safe as that is the one that applications might want to use in a signal handler. Since open(), read() and close() are async-signal-safe, there is no reason a sig2str() that reads the info from a file could not be written in an async-signal-safe way. |
(0004986) kre (reporter) 2020-09-10 19:01 |
Re Note: 0004984 It makes no real difference whether one or both of these are required to be async-signal-safe - if one is, the other will be - they use the exact same data mapping names to numbers, just one looks up the name, and returns the number, and the other looks up the number and returns the name. It is getting the data that is the issue, the lookups and result returning are not an issue. While open/read/close are OK to use (as is stat() which might be needed), malloc() is not, and until we see the file (its size, or perhaps its contents) we don't know how big the buffer might need to be. If we have to malloc() we cannot be async-signal-safe. Re Note: 0004983 ... I am not implementing Solaris, nor am I copying its decisions. We still allow (and actually generate some) static binaries and they should work (and ideally keep on working into the future). While there are issues with running really old static binaries, with careful attention by the system, it can be done. But some data cannot help needing to be updated, that data cannot be built into the application, or any library it uses, or it will certainly cause problems. While I don't really care about these functions for NetBSD, as absolutely nothing would ever use them, I do care that the standard isn't written in a way that precludes various different (reasonable) implementations. The remote outside chance that some application might want to use sig2str() in a signal handler doesn't justify forcing a low quality implementation. |
(0004987) geoffclare (manager) 2020-09-14 08:13 edited on: 2020-09-14 08:14 |
Re Note: 0004986 str2sig() does not just "look up the name and return the number", it also does string to integer conversion, and neither atoi() nor strtol() is in the list of async-signal-safe functions. |
(0004988) kre (reporter) 2020-09-14 13:59 |
Re Note: Note: 0004987 - nothing in the description of the interface says that str2sig() uses either atoi() or strtol() - it is possible to convert a string of digits to an integer in a 100% async-signal-safe way. Particularly when the size of the resulting integer most likely doesn't even approach the limits (the value would be too big to be a signal, on most implementations, way before integer overflow becomes an issue). However, as my position is that these functions (neither of them) ought to be listed as async-signal-safe, this really doesn't matter to me. This point also raises the question of why str2sig() is doing that? Do we really need yet another atoi() in the library? I can see some utility of having a function which can convert either a signal name, or the string form of its numeric value, into the signal number - it makes coding a fraction simpler and means that all applications will offer those alternatives (assuming that there really are any other than sh & kill (and its clones) which use these) . But it means that even if the application only wants the names to work. I think it would be better to leave it unspecified what happens when a digit string is given to str2sig(). Apps that want to allow numeric input can easily call strtol() (one hopes not atoi()) and make that happen. This would also improve the symmetry of the two functions, anything is defined to work as input to str2sig() would also be the defined output of sig2str() - that doesn't happen when str2sig() converts a numeric arg. Beyond that the specification doesn't make clear what happens when the input is something like "13apples". My guess, given its vintage(), is that the SysVR4 implementation probably just does something like if (isdigit(str[0])) sig = atoi(str); (and then maybe bounds checks sig, maybe - since I assume it assumes that all signals from 1..n are valid, which they probably are in SysVR4, and Solaris) no more "valid signal number" check would be needed. If my guess is right the str2sig("13apples", ...) would return (as the signal) "13". Is that to be the required behaviour? As an aside: apart from that signal handlers shouldn't be doing anything nearly as complex as converting strings to integers (nor converting integers into signal names) I can't think of a particularly good reason that atoi() or strtol() aren't listed as async-signal-safe. Is there an implementation of them somewhere where they aren't? But once again, the best outcome here would be to simply reject this proposal, and add nothing to the standard. |
(0004989) eblake (manager) 2020-09-14 14:11 |
Regarding Note: 0004988 on strtol() not being async-signal-safe: that's because it is locale-dependent (some locales have different thousands separators, and the parsing of strings into numbers is permitted to take that difference into account when deciding what to parse). As consulting the locale means interacting with environment variables, the whole function becomes non-async-safe. |
(0004990) geoffclare (manager) 2020-09-14 14:53 |
Re Note: 0004988 The Solaris code (assuming it hasn't changed in Illumos) uses strtol() and checks that the returned end pointer points to a null byte. It also looks up the resulting integer in the table. So str2sig("13apples", ...) returns an error. https://github.com/illumos/illumos-gate/blob/master/usr/src/lib/libc/port/gen/str2sig.c [^] |
(0004993) kre (reporter) 2020-09-14 17:52 |
Re Note: Note: 0004989 ... yes, of course, somewhere I think I kind of knew that. Thanks. With that, and Note: 0004990 clearly no-one is going to make str2sig async-signal-safe. So just don't make either that way - after all an implementation of sig2str() might decide to call str2sig() on the answer to make sure that the correct value was generated. Why not? |
(0005040) geoffclare (manager) 2020-10-09 09:38 |
As agreed in the Oct 8th teleconference, Note: 0004975 has been updated to make the behaviour for a signum value of 0 unspecified. |
(0005045) mkerrisk (reporter) 2020-10-11 06:23 edited on: 2020-10-11 07:16 |
Just by way of background, I note that the GNU C Library (glibc) recently (v2.32, Aug 2020) added: const char *sigabbrev_np(int signum) "This function returns the abbreviation describing the signal signum or NULL for invalid signal number. The message points to a static storage whose lifetime is the whole lifetime of the program." For example, it returns "HUP" for SIGHUP. |
(0005061) geoffclare (manager) 2020-10-23 15:15 |
The sig2str() and str2sig() additions have been made in the Issue8NewAPIs branch in gitlab, based on Note: 0004975. |
(0005338) geoffclare (manager) 2021-04-29 15:30 |
Make the changes from "Additional APIs for Issue 8, Part 1" (Austin/1110). |
Issue History | |||
Date Modified | Username | Field | Change |
2017-04-27 12:02 | joerg | New Issue | |
2017-04-27 12:02 | joerg | Name | => Jörg Schilling |
2017-04-27 12:02 | joerg | Section | => System Interfaces |
2017-04-27 12:02 | joerg | Page Number | => new interface |
2017-04-27 12:02 | joerg | Line Number | => newinterface |
2017-04-27 12:11 | joerg | Note Added: 0003678 | |
2017-04-27 13:32 | schwarze | Note Added: 0003679 | |
2017-04-27 14:15 | joerg | Note Added: 0003680 | |
2017-04-27 15:47 | kre | Note Added: 0003681 | |
2017-04-27 16:30 | jilles | Note Added: 0003682 | |
2017-04-28 02:14 | kre | Note Added: 0003683 | |
2017-04-28 02:49 | kre | Note Added: 0003684 | |
2017-05-04 10:57 | joerg | Note Added: 0003685 | |
2017-05-04 12:29 | kre | Note Added: 0003686 | |
2017-05-10 02:00 | kre | Note Added: 0003688 | |
2017-05-10 02:00 | kre | Note Deleted: 0003683 | |
2017-05-10 02:00 | kre | Note Deleted: 0003684 | |
2017-05-10 02:31 | kre | Note Edited: 0003688 | |
2017-05-10 02:31 | kre | Note Edited: 0003688 | |
2018-10-11 15:48 | Don Cragun | Note Added: 0004148 | |
2019-01-16 13:36 | ajosey | Note Added: 0004212 | |
2020-09-08 09:30 | geoffclare | Note Added: 0004975 | |
2020-09-08 09:30 | geoffclare | Note Edited: 0004975 | |
2020-09-08 15:32 | kre | Note Added: 0004976 | |
2020-09-08 21:37 | joerg | Note Added: 0004977 | |
2020-09-08 22:49 | kre | Note Added: 0004978 | |
2020-09-08 23:12 | kre | Note Added: 0004979 | |
2020-09-08 23:13 | kre | Note Deleted: 0004979 | |
2020-09-09 11:27 | joerg | Note Added: 0004980 | |
2020-09-10 10:55 | geoffclare | Note Edited: 0004975 | |
2020-09-10 10:59 | geoffclare | Note Added: 0004981 | |
2020-09-10 13:05 | kre | Note Added: 0004982 | |
2020-09-10 13:30 | joerg | Note Added: 0004983 | |
2020-09-10 14:31 | geoffclare | Note Added: 0004984 | |
2020-09-10 14:31 | geoffclare | Note Edited: 0004984 | |
2020-09-10 19:01 | kre | Note Added: 0004986 | |
2020-09-14 07:26 | geoffclare | Note Edited: 0004975 | |
2020-09-14 08:00 | geoffclare | Note Edited: 0004975 | |
2020-09-14 08:13 | geoffclare | Note Added: 0004987 | |
2020-09-14 08:14 | geoffclare | Note Edited: 0004987 | |
2020-09-14 13:59 | kre | Note Added: 0004988 | |
2020-09-14 14:11 | eblake | Note Added: 0004989 | |
2020-09-14 14:53 | geoffclare | Note Added: 0004990 | |
2020-09-14 17:52 | kre | Note Added: 0004993 | |
2020-10-09 09:31 | geoffclare | Note Edited: 0004975 | |
2020-10-09 09:38 | geoffclare | Note Added: 0005040 | |
2020-10-11 06:23 | mkerrisk | Note Added: 0005045 | |
2020-10-11 07:15 | mkerrisk | Note Edited: 0005045 | |
2020-10-11 07:16 | mkerrisk | Note Edited: 0005045 | |
2020-10-23 10:57 | geoffclare | Note Edited: 0004975 | |
2020-10-23 15:15 | geoffclare | Note Added: 0005061 | |
2021-04-29 15:30 | geoffclare | Note Added: 0005338 | |
2021-04-29 15:32 | geoffclare | Interp Status | => --- |
2021-04-29 15:32 | geoffclare | Final Accepted Text | => Note: 0005338 |
2021-04-29 15:32 | geoffclare | Status | New => Resolved |
2021-04-29 15:32 | geoffclare | Resolution | Open => Accepted As Marked |
2021-04-29 15:32 | geoffclare | Tag Attached: issue8 | |
2021-05-07 15:33 | geoffclare | Status | Resolved => Applied |
2024-06-11 09:09 | agadmin | Status | Applied => Closed |
Mantis 1.1.6[^] Copyright © 2000 - 2008 Mantis Group |