<?xml version="1.0" encoding="utf-8"?>
<!--RSS generated by Flaimo.com RSS Builder [2026-09-18 06:09:29]-->
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"><channel><docs>https://austingroupbugs.net/</docs><link>https://austingroupbugs.net/</link><description><![CDATA[Austin Group Issue Tracker - Issues]]></description><title>Austin Group Issue Tracker - Issues</title><image><title>Austin Group Issue Tracker - Issues</title><url>https://austingroupbugs.net/images/AG_HEADER.png</url><link>https://austingroupbugs.net/</link><description><![CDATA[Austin Group Issue Tracker - Issues]]></description></image><language>en</language><category>All Projects</category><ttl>10</ttl><dc:language>en</dc:language><sy:updatePeriod>hourly</sy:updatePeriod><sy:updateFrequency>1</sy:updateFrequency><item><title>0002000: XSH 3/strfmon misses info and needs attention</title><author></author><link>https://austingroupbugs.net/view.php?id=2000</link><description><![CDATA[&lt;p&gt;&lt;br /&gt;
In the sequel, I shall refer solely to &lt;i&gt;strfmon&lt;/i&gt;(), but everything applies equally to &lt;i&gt;strfmon_l&lt;/i&gt;().&lt;br /&gt;
The mechanism by which the locale data is made available is not material to anything in this defect report.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
The following defects are ordered in decreasing order of importance, as I see them, except with some related issues grouped adjacent to one another.&lt;br /&gt;
All defects (except probably the last) should be corrected however.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;ol&gt;&lt;li&gt;&lt;br /&gt;
When issue &lt;a href=&quot;https://austingroupbugs.net/view.php?id=1199&quot;&gt;0001199&lt;/a&gt; was fixed (the changes made as the result of that I generally agree with) one part of the original issue report seems to have been forgotten.&lt;br /&gt;
It (&lt;a href=&quot;https://austingroupbugs.net/view.php?id=1199&quot;&gt;0001199&lt;/a&gt;) said:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
However, without a distinction between positive and negative values, and without a visible decimal separator, this behaviour is useless, or even dangerous &lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
The issue with positive/negative was (mostly) handled, the issue when there is no visible decimal separator was not, and needs to be.&lt;br /&gt;
See issue &lt;a href=&quot;https://austingroupbugs.net/view.php?id=1199&quot;&gt;0001199&lt;/a&gt; for an example illustrating the problem.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
Following on from the previous, it is also unclear, even with the text as amended by issue &lt;a href=&quot;https://austingroupbugs.net/view.php?id=1199&quot;&gt;0001199&lt;/a&gt;,  what should be done when a locale defines non-empty strings to be used as the signs, but specifies the same string for both cases.&lt;br /&gt;
This is effectively the same problem as issue &lt;a href=&quot;https://austingroupbugs.net/view.php?id=1199&quot;&gt;0001199&lt;/a&gt; dealt with, being unable to determine whether a value is positive, or negative, just in a different way.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
Relevant to this, and what makes it different from the empty string case, is that the result might differ when the position of the sign string is different for positive and negative values.&lt;br /&gt;
That is, it is not necessarily simply invalid to use the same non-empty string for both the positive and negative signs.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
It is not always clear in the specification when &lt;i&gt;character&lt;/i&gt; means &lt;b&gt;character&lt;/b&gt; and when it means &lt;b&gt;byte&lt;/b&gt; or perhaps &quot;character from a restricted character set&quot;, or something different entirely.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
That the specification generally means &lt;b&gt;character&lt;/b&gt; is clear from line 69523:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
The format is a character string, beginning and ending in its initial state, if any, ...&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
which would make no sense if &lt;i&gt;character&lt;/i&gt; was being used as a synonym for the &lt;b&gt;C&lt;/b&gt; programming language &lt;b&gt;char&lt;/b&gt; data type, or simply a byte, or even a character from the Portable Character Set from the standard (XBD 6.1).&lt;br /&gt;
Those kinds of characters have no state, hence no initial state to require.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
This issue crops up in many places, the most obvious is in (line 69540):&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
An '=' followed by a single character &lt;i&gt;f&lt;/i&gt; which is used as the numeric fill character.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
The text (lines 69541-69542) attempts to add some meaning to this:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
In order to work with precision or width counts, the fill character shall be a single byte character; if not, the behavior is undefined.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
But that makes no sense at all.&lt;br /&gt;
To work with the precision and width counts, the fill character needs to occupy one column position in the output.&lt;br /&gt;
That distinction has nothing at all to do with how many bytes are in the representation of the character.&lt;br /&gt;
A single byte character, in some locales, might be zero-width or occupy multiple columns in the output, even in a constant width font.&lt;br /&gt;
Obvious examples are the &lt;tab&gt; character, and ASCII control characters.&lt;br /&gt;
A &lt;newline&gt; or &lt;carriage-return&gt; would have different, but related, issues.&lt;br /&gt;
It is also unclear why the behaviour should be &lt;b&gt;undefined&lt;/b&gt; should the application not give a suitable character as the fill character value.&lt;br /&gt;
That is a truly machiovellian punishment.&lt;br /&gt;
Would it not be better to simply make it clear than in such cases the intended alignment might not be able to be achieved?&lt;br /&gt;
That is, the implementation should just use whatever character is specified as &lt;i&gt;f&lt;/i&gt; when needed as the fill character, and if that character is not suitable for the purpose, the output will look odd, instead of nice.&lt;br /&gt;
No calling &lt;i&gt;abort&lt;/i&gt;(), or removing all of the user's files, which &quot;undefined behaviour&quot; would permit.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
A similar problem can be found at line 69577:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
A decimal digit string &lt;i&gt;w&lt;/i&gt; specifying a minimum field width in bytes&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
which also makes little sense, if one assumes as the specification seems to imply, at a minimum, that the objective is to be able to align output from multiple calls to &lt;i&gt;strfmon&lt;/i&gt;().&lt;br /&gt;
What matters is the appearance of the final output, not how many bytes of encoded characters are needed to achieve that result.&lt;br /&gt;
The number of bytes is, or should, only be relevant when determining whether the result fits within the &lt;i&gt;maxsize&lt;/i&gt; number of bytes available in the output buffer.&lt;br /&gt;
Everything else should be using &lt;b&gt;character&lt;/b&gt;s, possibly constrained in some cases to be printing or graphic characters, and perhaps sometimes constrained by the widths of the characters concerned.&lt;br /&gt;
This needs to be clear in the specification, with no mention of &lt;b&gt;bytes&lt;/b&gt; in any of the relevant places.&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
The same problem arises with everything else inserted into the resulting output string, including the &lt;i&gt;mon_decimal_point&lt;/i&gt; and the &lt;mon_thousands_sep&gt; strings.&lt;br /&gt;
Lines 69592-69594 do explain the idea:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
To ensure alignment, any characters appearing before or after the number in the formatted output such as currency or sign symbols are padded as necessary with &lt;space&gt; characters to make their positive and negative formats an equal length.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
though that text does give rise to the immediately following defect.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
It should also be made clear what other constraints, if any, must be met for the output to be able to be nicely aligned.&lt;br /&gt;
The use of a monospace (constant width) font to display the result is an obvious one, without that achieving alignment requires much more complex mechanisms that simply counting characters, which is all that is available here.&lt;br /&gt;
But is it expected that all the values intended to be able to be aligned have neen formatted using the same locale, or is it intended that output from different locales be able to be intermixed, and remain aligned?&lt;br /&gt;
The answer to that question constrains what constraints should be placed upon what is permitted in locales for the &lt;b&gt;mon_decimal_point&lt;/b&gt; (I have a fake locale, for testing purposes, which uses $'\u3002' as that character, and the font I use for my terminal sessions renders that character in 2 columns).&lt;br /&gt;
Is &lt;i&gt;strfmon&lt;/i&gt;() expected to work with such a value?&lt;br /&gt;
It does, even to aligning (approximately) as intended, as the alighnment is primarily for the value to the left of the radix, which is unaffected by this.&lt;br /&gt;
But something similar might be used as the &lt;b&gt;mon_thousands_sep&lt;/b&gt;.&lt;br /&gt;
Further, different locales might have different &lt;b&gt;mon_grouping&lt;/b&gt; settings.&lt;br /&gt;
My fake locale uses &quot;2;3;2;3;2&quot; which is going to result in a different number of separators being inserted in some values than the more common &quot;3&quot;.&lt;br /&gt;
As one call to &lt;i&gt;strfmon&lt;/i&gt; has no way to communicate decisions to another, nor to predict what locale might be in use when the next call is made, it might seem necessary to constrain the alignment goal to apply only as long as the same locale is used for all relevant &lt;i&gt;strfmon&lt;/i&gt; calls.&lt;br /&gt;
But that might also be too strict, perhaps as long as the locales used all use the same &lt;b&gt;mon_grouping&lt;/b&gt;, and use as their &lt;b&gt;mon_decimal_point&lt;/b&gt; and &lt;b&gt;mon_thousands_sep&lt;/b&gt; strings which occupy the same number of columns as the equivalent setting in all other locales used in a sequence intended to align correctlty, that would be enough?&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
Did no-one ever consider any of these questions?&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
The text at lines 69592-69594:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
To ensure alignment, any characters appearing before or after the number in the&lt;br /&gt;
formatted output such as currency or sign symbols are padded as necessary with&lt;br /&gt;
&lt;space&gt; characters to make their positive and negative formats an equal length.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
concentrate entirely upon making the positive and negative output forms of equal length, but the text at lines 69582-69584:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
This option can be used to keep the formatted output from multiple calls to the strfmon( ) function aligned in the same columns.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
makes it clear that the aim that is implied by lines 69592-69594 is not sufficient to meet the expectations of the &lt;i&gt;strfmon&lt;/i&gt; specification, and that more precision is required to meet the overall objective.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
That is, if for positive numbers, the sign follows the value, and for negative nnumbers the sign precedes the value, then, to keep the numeric parts of a positive and a negative value aligned, both of them must allocate space in the resulting&lt;br /&gt;
string for the possible negative sign before the value, and the possible positive sign following the value (when positive signs are being included), so that either of them might be used to occupy the sign value.&lt;br /&gt;
What's more, that is what implementations I have seen actually do.&lt;br /&gt;
Simply having the positive and negative formats being of equal length is not suffficient.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
It is also not stated anywhere, but clearly is intended (I hope), that the expected alignment is only achieved if the same format string is used for all the applicable calls to &lt;i&gt;strfmon&lt;/i&gt;().&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
A corollary to the previous two points, is that it should be made explicit that aligned values can only be expected to remain aligned when displayed or printed, if they are rendered in a constant width font, or at least one in which all characters are represented in a non-negative integer multiple of a fixed column width.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
The description of &quot;grouping characters&quot; (a term for which incidentally I can find no definition in the standard, though it is obvious that in this context it means the &lt;b&gt;mon_thousands_sep&lt;/b&gt; characters inserted to perform the grouping function of monetary output values, which is a defined operation) and how they apply to the &lt;b&gt;Left Precision&lt;/b&gt; given in lines 69589-69590 is one of the least useful specifications I think I have ever seen.&lt;br /&gt;
It states (lines 69589-69590):&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
If grouping has not been suppressed with the '^' flag, and it is defined for the current locale, grouping separators are inserted before the fill characters (if any) are added.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
The pre-conditions are simple enough, but I would interpret the action as meaning that each &quot;grouping separator&quot; (another undefined term) inserted replaces one (or perhaps more) of the fill characters, which then fill in any remaining unused positions as specified in the previous paragraph (lines 69581-69588).&lt;br /&gt;
The subsequent sentence (line 69591), which ends the paragraph, about the inapplicability of grouping to fill characters, even if they are digits, is clear enough as it stands.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
But as illustrated by the examples (see lines 69640-69642 (or 69643-69645 or 69646-69648) in comparison with lines 69649-69651 which, apart from the use of a non-space fill character in the alternatives of the former, which is immaterial, show the same example, except the former has grouping enabled, and the latter with it suppressed), and from observing what is done by actual implementations, that is not what is intended at all.&lt;br /&gt;
Rather, the value given by the &lt;b&gt;Left Precision&lt;/b&gt; &quot;&lt;i&gt;n&lt;/i&gt;&quot; value, is to be increased by the maximum number of &quot;grouping separators&quot; which would be needed if a value to be formatted generates &lt;i&gt;n&lt;/i&gt; (as specified) digits before the radix character (decimal-point) if any.&lt;br /&gt;
Then the value is formatted, and the number of &quot;grouping separators&quot; required for the actual value are inserted, and finally the increased value of &lt;i&gt;n&lt;/i&gt; is used to fill any remaining unused positions with fill characters.&lt;br /&gt;
That is, the use of grouping can increase the number of fill characters to be used for a particular &lt;i&gt;value&lt;/i&gt;, and the actual left precision width from what is in the conversion specification, but never decrease it, compared to when grouping is not used.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
How, an implementer, or an application writer, is intended to determine the intended behaviour from the written specification bamboozles me.&lt;br /&gt;
It needs rewriting.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
Note also, that though the &lt;i&gt;linux&lt;/i&gt; manual page for this function attempts to make this clear, it is not a lot better:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
Next, there may be a left precision of the form &quot;#&quot; followed by a decimal digit string.&lt;br /&gt;
If the number of digits left of the radix character is smaller than this, the representation is padded on the left with the numeric fill character.&lt;br /&gt;
Grouping characters are not counted in this field width.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
That would make it seem as if the number of grouping characters inserted, or which might be inserted, has no effect on the padding inserted by the left precision, which is not correct either.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
The &lt;b&gt;ERRORS&lt;/b&gt; section at lines 69628-69630 states the functions shall fail if:&lt;br /&gt;
&lt;ul&gt;&lt;br /&gt;
&lt;li&gt;[EINVAL]&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
The '+' flag was included in a conversion specification and the locale's positive_sign and negative_sign values would both be returned by localeconv( ) as empty strings.&lt;br /&gt;
&lt;/blockquote&gt;&lt;/li&gt;&lt;br /&gt;
&lt;/ul&gt;&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
The &lt;b&gt;APPLICATION USAGE&lt;/b&gt; section, at lines 69672-69676:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
The '+' flag should be used with care, because if the locale's positive_sign and negative_sign values are both empty strings, there is no way to distinguish negative from positive values with signs and therefore strfmon( ) fails. If the application has a preference for signs but parentheses are acceptable, it should try strfmon( ) with the '+' flag first, and if it fails with [EINVAL] then repeat the call without the '+' flag.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
and the &lt;b&gt;RATIONALE&lt;/b&gt; at lines 69678-69680:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
The [EINVAL] error condition applies only when the '+' flag is used because this flag indicates that the application requires the use of signs, and if there are no signs in the locale data then this requirement cannot be satisfied.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
together expand upon this intended unique use.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
While implementations are generally permitted to add error numbers, and to add meanings to errors the standard specifies, as specified by XSH 2.3 at lines 17831-17833:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
Implementations may support additional errors not included in this list, may generate errors included in this list under circumstances other than those described here, or may contain extensions or limitations that prevent some errors from occurring.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
that same section goes on to place a restriction upon this implementation freedom, at lines 17839-17841 (and following for more restrictions not relevant here):&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
Implementations may generate error numbers listed here under circumstances other than those described, if and only if all those error conditions can always be treated identically to the error conditions as described in this volume of POSIX.1-2024.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
Taken together all of this implies, to me anyway, that the implementation may not generate &lt;b&gt;EINVAL&lt;/b&gt; for any error other than the one listed, as an application would then be unable to ascertain that the problem was the '+' in the format string, and offer a different format for the locale in question in that case.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
The problem all this causes for the implementation, is just how it should deal with applications which fail to meet their &lt;b&gt;shall&lt;/b&gt; obligations, for example the one at line 69529:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
The application shall ensure that a conversion specification consists of the following sequence:&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
I appreciate that when an application fails to comply with its obligations, implementation behaviour is unspecified, or perhaps even undefined, and is certainly beyond the scope of the standard.&lt;br /&gt;
This however does not help the implementer, who must do something in such cases.&lt;br /&gt;
Further as it seems above, the implementer is prohibited from using the obvious &lt;b&gt;EINVAL&lt;/b&gt; error code in such a situation.&lt;br /&gt;
Further, it does not help the application writer either, if some implementations simply ignore such issues and continue formatting as best they can, others return -1 and a seemingly random error code, and yet others simply call XSH 3 section 3/abort (pages 577-558).&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
At the very least, the specification should offer some guidance in this situation, and probably rewrite the application usage and rationale, so as to no longer constrain &lt;b&gt;EINVAL&lt;/b&gt; such that it cannot be used by the implementation for other issues.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
The standard offers no guidance on what should be done, should some of the data expected to be provided by the locale, is not defined there.&lt;br /&gt;
The &lt;b&gt;POSIX&lt;/b&gt; locale is one which does not supply any.&lt;br /&gt;
Particularly after the resolution of issue &lt;a href=&quot;https://austingroupbugs.net/view.php?id=1199&quot;&gt;0001199&lt;/a&gt;, some of this has&lt;br /&gt;
been dealt with, but not all.&lt;br /&gt;
This includes the lack of a (non-empty) &lt;b&gt;mon_decimal_point&lt;/b&gt;.&lt;br /&gt;
There is also no discussion on what should be done if any of the specified strings are non-empty, but do not contain anything which produces a visible representation in the output.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
There should be.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
Returning to &lt;b&gt;APPLICATION USAGE&lt;/b&gt; section, at lines 69672-69676:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
The '+' flag should be used with care, because if the locale's positive_sign and negative_sign values are both empty strings, there is no way to distinguish negative from positive values with signs and therefore strfmon( ) fails. If the application has a preference for signs but parentheses are acceptable, it should try strfmon( ) with the '+' flag first, and if it fails with [EINVAL] then repeat the call without the '+' flag.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
That suggests that simply omitting the '+' flag, will cause &lt;i&gt;stfrmon&lt;/i&gt;() to use parentheses as the indicator for negative values.&lt;br /&gt;
That is not what the post-issue &lt;a href=&quot;https://austingroupbugs.net/view.php?id=1199&quot;&gt;0001199&lt;/a&gt; standard causes to happen.&lt;br /&gt;
Instead, as stated on lines 69567-69571 when considering the case that&lt;br /&gt;
neither of the '+' nor '(' flags are included in the format:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
If the style cannot be determined from these locale values because a value that needs to be used would be returned by localeconv() as {CHAR_MAX}, the style used shall be that specified for the '+' flag; if this would cause strfmon( ) to fail because the locale's positive_sign and negative_sign values would both be returned by localeconv( ) as empty strings, strfmon( ) shall behave as if the negative_sign value was the string &quot;-&quot;.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
In other words, unless the format specifies the '(' flag (in which case this section is never reached, and its &lt;b&gt;positive_sign&lt;/b&gt; and &lt;b&gt;negative_sign&lt;/b&gt; and sign placement values are all ignored), if the '+' flag is not given, and the locale's default is not to use parentheses to indicate negative values, then the resulting output would use the empty &lt;b&gt;positive_sign&lt;/b&gt; if the &lt;i&gt;value&lt;/i&gt; is non-negative, and use &quot;-&quot; instead of an empty &lt;b&gt;negative_sign&lt;/b&gt; if the &lt;i&gt;value&lt;/i&gt; is negative.&lt;br /&gt;
&lt;p&gt;&lt;/p&gt;&lt;br /&gt;
This &lt;b&gt;APPLICATION USAGE&lt;/b&gt; text needs to be rewritten to take that into account.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
At times the standard is too specific in what it specifies.&lt;br /&gt;
For example, at lines 69557-69558:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
If a sign's placement cannot be determined from these locale values because a value that needs to be used would be returned by &lt;i&gt;localeconv&lt;/i&gt;() as 0 or {CHAR_MAX}, ...&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
Why is it important what the issue is with the value?&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
The range of values for the sign position are 0 to 4, with 0 not being useful for the situation being discussed in those lines, or {CHAR_MAX} to mean no value is supplied.&lt;br /&gt;
But what if the locale data specifies a value of 7?&lt;br /&gt;
That has no (currently) defined meaning, and hence is not useful for determining the placement of the sign, but it is not &quot;returned by &lt;i&gt;localeconv&lt;/i&gt;() as 0 or {CHAR_MAX}&quot;, so what is the implementation to do?&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
This kind of over specification should be removed, it is not important why the sign placement cannot be determined from the locale values, just that it cannot.&lt;br /&gt;
Note that this is not just a fanciful, perhaps even imagined, impossible case.&lt;br /&gt;
A later version of the standard may add extra possible values to any of the fields for which a set of numeric designated choices are provided, and an older implenentation (an instance of &lt;i&gt;stfrmon&lt;/i&gt; compiled into an existing applicaion for example) may encounter a previously invalid value, and needs to know how to handle that case.&lt;br /&gt;
This is not an instance where &quot;behaviour is unspecified&quot; (or even &quot;undefined&quot;) is an acceptable outcome.&lt;br /&gt;
The standard must be permitted to evolve without invalidating existing applications.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
The &lt;b&gt;EXAMPLES&lt;/b&gt; section, page 2132 (lines 69632-69670) assumes the existence of &quot;a locale for the US&quot; and, to make sense of the example output, what that locale must contain.&lt;br /&gt;
I can find no justification in the standard to assume that such a locale exists anywhere.&lt;br /&gt;
I certainly believe that most readers would understand &lt;b&gt;USD&lt;/b&gt; as the international currency symbol for the United States of America, and &lt;b&gt;$&lt;/b&gt; as its national currency symbol, and probably that its &lt;b&gt;frac_digits&lt;/b&gt; and &lt;b&gt;int_frac_digits&lt;/b&gt; would usually both be two.&lt;br /&gt;
I am not sure however that using a &quot;&lt;b&gt;-&lt;/b&gt;&quot; to indicate negative values, and nothing for positive ones, rather than enclosing negative values in parentheses, or use of &lt;b&gt;CR&lt;/b&gt; for positive and &lt;b&gt;DB&lt;/b&gt; for negative, is how such a locale would be defined.&lt;br /&gt;
Nor would I necessarily expect the sign, if used, to precede the currency symbol, rather than follow it.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
If some fictional locale is to be used for examples, regardless of whether that locale might be an actual locale on some system used by one or more of the actual writers of the text, then at least as much of it as is needed to understand the examples should be presented in the specification.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
Further, there should certainly be examples given where the &lt;b&gt;POSIX&lt;/b&gt; (aka &lt;b&gt;C&lt;/b&gt;) locale, the only one the standard actually specifies, is used.&lt;br /&gt;
Had there been, some of the problems this specification had before issue &lt;a href=&quot;https://austingroupbugs.net/view.php?id=1199&quot;&gt;0001199&lt;/a&gt; rectified them, and some of the problems it still has, might have been recognised and corrected much sooner than this.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
The &lt;b&gt;DESCRIPTION&lt;/b&gt; at lines 69524-69526 contains:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
&lt;b&gt;...&lt;/b&gt;, and conversion specifications, each of which shall result in the fetching of zero or more arguments which are converted and formatted.&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
&quot;Zero or more&quot; ?&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
The zero case is obviously for the &lt;b&gt;%%&lt;/b&gt; format conversion specification (which I personally would not treat as a conversion specification at all, but as an escaping mechanism, but that isn't the point here).&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
But &quot;or more&quot; ??&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
&lt;br /&gt;&lt;br /&gt;
One is certainly more than zero, and one (exactly) is what every other format conversion requires.&lt;br /&gt;
Why not just say &quot;zero or one&quot;, and not leave the reader wondering when more than one might be required?&lt;br /&gt;
Of course, if there is some hidden intent to allow indirect specification of the field width, the left precision, or the right precision, or some or all of those, in the way that the printf family of functions permit, which would perhaps be a useful addition, though not supported by any implementation of which I am aware, then the &quot;or more&quot; would be justified.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
In the same paragraph as the previous defect (lines 69524-69526) the text elided at the beginning of the text quoted previously is:&lt;br /&gt;
&lt;blockquote&gt;&lt;br /&gt;
The format is a character string, beginning and ending in its initial state, if any, that contains two types of objects: &lt;i&gt;plain characters&lt;/i&gt;, which are simply copied to the output stream, &lt;b&gt;...&lt;/b&gt;&lt;br /&gt;
&lt;/blockquote&gt;&lt;br /&gt;
but there is no definition anywhere of what is a &lt;i&gt;plain character&lt;/i&gt;.&lt;br /&gt;
The intent is obvious, but standards should not rely upon readers being able to deduce from what appears to be obvious, they should be explicit.&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;&lt;li&gt;&lt;br /&gt;
&lt;p&gt;&lt;br /&gt;
The locale specification (XBD 7) and the specification of &lt;i&gt;strfmon&lt;/i&gt; seem to lack the ability to format currency amounts in the (old style to be sure) formats previously used in the UK, and other countries including AU and NZ.&lt;br /&gt;
That is, the Lsd format, as in £10/- or £9-19-11 and similar constructions.&lt;br /&gt;
There may be other formats in use, or previously in use, which are similarly neglected.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
There is also no way to specify that other characters, rather than '(' and ')' be used to surround values, further it should be possible to have different characters surrounding positive and negative values - the &lt;b&gt;positive_sign&lt;/b&gt; and &lt;b&gt;negative_sign&lt;/b&gt; settings cannot be used for this, as only one of them is ever used for any particular value, and whichever that is is only ever used once.&lt;br /&gt;
&lt;/p&gt;&lt;p&gt;&lt;br /&gt;
These issues should be fixed, but this is not the place to do it.&lt;br /&gt;
Thus I will not offer potential solutions - the issue is here just so it is clear that the problems are known, and cannot at some future time be dismissed with &quot;We didn't ever consider those possibilities.&quot;&lt;br /&gt;
&lt;/p&gt;&lt;br /&gt;
&lt;/li&gt;&lt;/ol&gt;]]></description><category>System Interfaces</category><pubDate>Thu, 17 Sep 2026 19:28:07 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=2000</guid><comments>https://austingroupbugs.net/view.php?id=2000#bugnotes</comments></item><item><title>0001992: Add getexepath() to retrieve the absolute pathname of the current process executable image.</title><author></author><link>https://austingroupbugs.net/view.php?id=1992</link><description><![CDATA[There is currently no standardized, portable mechanism in POSIX to retrieve the absolute pathname of the executable file currently executing the calling process. Runtimes, language interpreters, and asset loaders must resort to highly unportable, platform-specific mechanisms. &lt;br /&gt;
&lt;br /&gt;
- Linux relies on parsing the &quot;/proc/self/exe&quot; symlink or using `getauxval(AT_EXECFN)`.&lt;br /&gt;
- FreeBSD and NetBSD use a sysctl interface via KERN_PROC_PATHNAME.&lt;br /&gt;
- SunOS implements getexecname().&lt;br /&gt;
- macOS implements a non-POSIX _NSGetExecutablePath() function.&lt;br /&gt;
&lt;br /&gt;
Others like OpenBSD force us to rely on argv[0] and (if the process didn't start with an absolute path) scanning the PATH environment variable, which is fundamentally unsafe and unreliable (someone else in the PATH with the same name appearing early is picked up). Furthermore, the parent process can easily manipulate or empty argv and envp during an execve() call, leaving the child completely unable to safely determine its own physical location. &lt;br /&gt;
&lt;br /&gt;
Adding a native, safe API to POSIX eliminates immense cross-platform boilerplate across programming frameworks and toolchains that require explicit binary path auditing.]]></description><category>System Interfaces</category><pubDate>Tue, 15 Sep 2026 04:03:15 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1992</guid><comments>https://austingroupbugs.net/view.php?id=1992#bugnotes</comments></item><item><title>0001616: Standardize mktemp utility</title><author></author><link>https://austingroupbugs.net/view.php?id=1616</link><description><![CDATA[The current standard has no reliable and convenient utility to create temporary file or directory, despite that low-level interfaces, mkstemp/mkdtemp, are available for this use case. The mktemp(1) utility is a perfect candidate to fill this gap. Its interface is fairly simple and mostly consistent across various implementations, however not without some differences. I evaluated GNU, LSB, NetBSD, FreeBSD, OpenBSD, Illumos, Solaris, sbase, toybox, busybox implementations and here is what I found:&lt;br /&gt;
&lt;br /&gt;
- FreeBSD, NetBSD accept multiple templates. Others do not.&lt;br /&gt;
- FreeBSD does not specify -p option. Others do.&lt;br /&gt;
- LSB does not specify -d and -p options. Others do.&lt;br /&gt;
- FreeBSD, NetBSD accept parameter for -t option. Others do not.&lt;br /&gt;
- FreeBSD, NetBSD use -t option to specify prefix. Others use it to explicitly tell mktemp to create temporary file in temporary directory rather than in current directory.&lt;br /&gt;
- All have different default value for template.&lt;br /&gt;
- All have different requirements regarding how many Xs template should contain, but it seems they all accept six Xs.&lt;br /&gt;
- sbase, Illumos, Solaris override -p parameter with TMPDIR value if it is set. Others do not.&lt;br /&gt;
- GNU overrides -p parameter with TMPDIR value or /tmp if parameter is empty string. Others do not.&lt;br /&gt;
- OpenBSD, Illumos, Solaris(not sure), toybox do not allow '/' in template if -p option is passed. Others do.&lt;br /&gt;
&lt;br /&gt;
Given that, I think mktemp interface is not completely lost and below is my attempt to make it portable.]]></description><category>Shell and Utilities</category><pubDate>Mon, 14 Sep 2026 16:55:58 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1616</guid><comments>https://austingroupbugs.net/view.php?id=1616#bugnotes</comments></item><item><title>0001997: cp,mv,pax should not need to diagnose timestamp downresing</title><author></author><link>https://austingroupbugs.net/view.php?id=1997</link><description><![CDATA[When the command ‘mv /a/SOURCE DEST’ crosses file system boundaries, the resulting file DEST can have a timestamp with less low-order information as described by futimens (POSIX.1-2024 page 1075 lines 36821–36822). For example, the source file’s timestamp might be 1786900895.478636836 but the destinations might be on a FAT32 filesystem so its timestamp might be only 1786900895.47, as FAT32 has only 10 ms resolution.&lt;br /&gt;
&lt;br /&gt;
This topic recently came up in a bug report for GNU mv &lt;&lt;a href=&quot;https://bugs.gnu.org/13601#40&gt;&quot; rel=&quot;noopener&quot;&gt;https://bugs.gnu.org/13601#40&gt;.&lt;/a&gt; One commenter there said that this loss of information triggers the clause for mv (page 3199 lines 108114–108115) saying “If the duplication of the file characteristics fails for any reason, mv shall write a diagnostic message to standard error” which means a diagnostic is required.&lt;br /&gt;
&lt;br /&gt;
GNU mv, and I expect all other mv implementations, does not do that. Instead, it uses futimens or utimensat to set DEST’s timestamps, and if that succeeds it does not issue a diagnostic. Checking whether DEST’s timestamp lost low-order info would require another system call, and I don’t know of any mv implementation that does so.&lt;br /&gt;
&lt;br /&gt;
A clarification is needed here for the phrase “duplication of the file characteristic fails for any reason”. Does the phrase mean that (a) a system call like futimens failed, or does it mean that (b) the destination’s characteristics disagree, even slightly, from the source’s? Although implementations have chosen (a) POSIX could be read as requiring (b).&lt;br /&gt;
&lt;br /&gt;
If an implementation wanted to implement (b), for efficiency it would be helpful if utimensat acquired an additional flag to cause the system call to fail if the timestamp is downresed. However, that would be a separate topic from this bug report, and I know of no platform that has such a flag so at this point it would be pure invention on the POSIX committee’s part.&lt;br /&gt;
&lt;br /&gt;
In the DESIRED ACTION I have attempted to word things so that an implementation can do either (a) or (b). (b) is allowed because an implementation can always issue a diagnostic whenever it likes, so long as it does not change the exit status.]]></description><category>Shell and Utilities</category><pubDate>Mon, 14 Sep 2026 16:06:46 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1997</guid><comments>https://austingroupbugs.net/view.php?id=1997#bugnotes</comments></item><item><title>0001998: Where should MANTIS issues be submitted?</title><author></author><link>https://austingroupbugs.net/view.php?id=1998</link><description><![CDATA[I just spent an hour or two filling in an issue report (a long one)&lt;br /&gt;
only for when I submitted it to be told there was an invalid security&lt;br /&gt;
token, either I had submitted twice (no) or the session had timed&lt;br /&gt;
out (possible, given it had taken a LONG time to get all the details&lt;br /&gt;
page numbers, line numbers, ... inserted properly.    And to decide&lt;br /&gt;
what exactly I needed to report.&lt;br /&gt;
&lt;br /&gt;
It told me to press the back button on my browser.   I did.   All the&lt;br /&gt;
text I had entered was gone (in previous interfaces that didn't happen,&lt;br /&gt;
I could create a new report, and cut and paste everything from the old&lt;br /&gt;
to the new, which would take much less time, and no timeout would&lt;br /&gt;
occur - it has been ages since my last interaction with this, I had forgotten&lt;br /&gt;
this issue.]]></description><category>Base Definitions and Headers</category><pubDate>Mon, 14 Sep 2026 15:17:10 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1998</guid><comments>https://austingroupbugs.net/view.php?id=1998#bugnotes</comments></item><item><title>0001996: Add SIGEV_SIGNAL_THREAD to allow more efficient handling of sigevent-using functions.</title><author></author><link>https://austingroupbugs.net/view.php?id=1996</link><description><![CDATA[Currently, there are only two notification mechanisms for use with sigevent: SIGEV_SIGNAL and SIGEV_THREAD. Both of these methods have issue preventing their use, and so a new notification should be added.&lt;br /&gt;
&lt;br /&gt;
SIGEV_THREAD typically spawns a new thread on each event, which degrades performance to the point that it defeats the purpose of using such a notification; performing the corresponding blocking opperation in a new thread would typically be both faster and more convenient. SIGEV_SIGNAL requires use of a signal handler; as signal handlers are shared between all threads in a process, this makes it unsuitable for use in a library.&lt;br /&gt;
&lt;br /&gt;
To resolve this, several platforms have added mechanisms to direct the signal to a specific thread. However, this mechanism is not standardised, which imhibits its use. This proposal serves to standardise it.]]></description><category>System Interfaces</category><pubDate>Sun, 13 Sep 2026 22:12:31 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1996</guid><comments>https://austingroupbugs.net/view.php?id=1996#bugnotes</comments></item><item><title>0001994: exp() assumes default rounding</title><author></author><link>https://austingroupbugs.net/view.php?id=1994</link><description><![CDATA[If the correct value would cause overflow, a range error shall occur&lt;br /&gt;
and exp(), expf(), and expl() shall return the value of the macro&lt;br /&gt;
HUGE_VAL, HUGE_VALF, and HUGE_VALL, respectively.]]></description><category>System Interfaces</category><pubDate>Fri, 11 Sep 2026 23:39:49 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1994</guid><comments>https://austingroupbugs.net/view.php?id=1994#bugnotes</comments></item><item><title>0001999: Session timeouts too short</title><author></author><link>https://austingroupbugs.net/view.php?id=1999</link><description><![CDATA[I just spent an hour or two filling in an issue report (a long one)&lt;br /&gt;
only for when I submitted it to be told there was an invalid security&lt;br /&gt;
token, either I had submitted twice (no) or the session had timed&lt;br /&gt;
out (possible, given it had taken a LONG time to get all the details&lt;br /&gt;
page numbers, line numbers, ... inserted properly. And to decide&lt;br /&gt;
what exactly I needed to report.&lt;br /&gt;
&lt;br /&gt;
It told me to press the back button on my browser. I did. All the&lt;br /&gt;
text I had entered was gone (in previous interfaces that didn't happen,&lt;br /&gt;
I could create a new report, and cut and paste everything from the old&lt;br /&gt;
to the new, which would take much less time, and no timeout would&lt;br /&gt;
occur - it has been ages since my last interaction with this, I had forgotten&lt;br /&gt;
this issue.]]></description><category>Aardvark 2025</category><pubDate>Wed, 02 Sep 2026 15:51:29 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1999</guid><comments>https://austingroupbugs.net/view.php?id=1999#bugnotes</comments></item><item><title>0001976: specify array variables and syntax</title><author></author><link>https://austingroupbugs.net/view.php?id=1976</link><description><![CDATA[POSIX sh specifies one array per function, the argument array&lt;br /&gt;
&lt;br /&gt;
many sh implementations support having array variables past the argument array&lt;br /&gt;
&lt;br /&gt;
due to posix shell specifying a syntax for the argument array, sh implementations&lt;br /&gt;
with array extensions naturally landed on similar and compatible syntax&lt;br /&gt;
&lt;br /&gt;
mksh, ksh93, bash, zsh, osh, yash, all support the following syntax:&lt;br /&gt;
	foo=(a b &quot;c d&quot; e)&lt;br /&gt;
	foo+=(f g)&lt;br /&gt;
	&quot;${foo[@]}&quot; # a b &quot;c d&quot; e f g&lt;br /&gt;
	&quot;${foo[*]}&quot; # &quot;a b c d e f g&quot;&lt;br /&gt;
	&quot;${foo[expr]}&quot; # indexed by expr, where expr is evaluated like $(( expr ))&lt;br /&gt;
	&quot;${#foo[@]}&quot; # 6, the lenght of foo&lt;br /&gt;
&lt;br /&gt;
additionally, mksh, ksh, and zsh, support declaring arrays as such:&lt;br /&gt;
	set -A name -- values&lt;br /&gt;
&lt;br /&gt;
notably ksh does not implement the name=(values) syntax, but has no other syntax&lt;br /&gt;
that would conflict with it either&lt;br /&gt;
&lt;br /&gt;
ash and dash do not currently implement any sort of arrays, but also have&lt;br /&gt;
no syntax that conflicts with the existing extensions]]></description><category>Shell and Utilities</category><pubDate>Wed, 12 Aug 2026 15:36:30 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1976</guid><comments>https://austingroupbugs.net/view.php?id=1976#bugnotes</comments></item><item><title>0001995: Add SHM_ANON to shm_open()</title><author></author><link>https://austingroupbugs.net/view.php?id=1995</link><description><![CDATA[SHM_ANON can be used to create an unnamed shared memory object, which will be automatically destroyed when last reference to it is removed. It is mainly useful for avoiding potential conflicts with already existing shared memory objects, hiding the object from other processes and making the use of shm_unlink unnecessary since the object has no name.&lt;br /&gt;
&lt;br /&gt;
This extension is known to be implemented at least by QNX and FreeBSD. Linux provides similar memfd_create() interface, which can be used to mimic SHM_ANON.&lt;br /&gt;
&lt;br /&gt;
See also: &lt;a href=&quot;https://github.com/lassik/shm_open_anon&quot; rel=&quot;noopener&quot;&gt;https://github.com/lassik/shm_open_anon&lt;/a&gt;]]></description><category>System Interfaces</category><pubDate>Mon, 10 Aug 2026 22:10:11 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1995</guid><comments>https://austingroupbugs.net/view.php?id=1995#bugnotes</comments></item><item><title>0001949: Restore the traditional realloc(3) specification</title><author></author><link>https://austingroupbugs.net/view.php?id=1949</link><description><![CDATA[Name&lt;br /&gt;
	alx-p0001r0 - Restore the traditional realloc(3) specification&lt;br /&gt;
&lt;br /&gt;
Category&lt;br /&gt;
	Remove UB.&lt;br /&gt;
&lt;br /&gt;
[ADMINISTRATOR EDIT: removed personal email addresses from Description]&lt;br /&gt;
&lt;br /&gt;
History&lt;br /&gt;
	&lt;&lt;a href=&quot;https://www.alejandro-colomar.es/src/alx/alx/std/posix/alx-p0001.git/&gt;&quot; rel=&quot;noopener&quot;&gt;https://www.alejandro-colomar.es/src/alx/alx/std/posix/alx-p0001.git/&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
	alx-0029r0 (2025-06-17):&lt;br /&gt;
	-  Initial draft.&lt;br /&gt;
&lt;br /&gt;
	alx-0029r1 (2025-06-20):&lt;br /&gt;
	-  Full rewrite after the recent glibc discussion.&lt;br /&gt;
&lt;br /&gt;
	alx-0029r2 (2025-06-21):&lt;br /&gt;
	-  Remove CC.  Add CC.&lt;br /&gt;
	-  wfix.&lt;br /&gt;
	-  Drop quote.&lt;br /&gt;
	-  Add a few more principles&lt;br /&gt;
	-  Clarify why ENOMEM is used in this proposal, and make it&lt;br /&gt;
	   optional.&lt;br /&gt;
	-  Mention exceptional leak in code checking (size != 0).&lt;br /&gt;
	-  Clarify that part of the description of realloc can be&lt;br /&gt;
	   editorially removed after this change.&lt;br /&gt;
&lt;br /&gt;
	alx-0029r3 (2025-06-23):&lt;br /&gt;
	-  Fix diff missing line.&lt;br /&gt;
	-  Remove ENOMEM from the proposal.&lt;br /&gt;
	-  Clarify that ENOMEM should be retained by platforms already&lt;br /&gt;
	   using it.&lt;br /&gt;
	-  Add mention that LLVM's address sanitizer will catch the leak&lt;br /&gt;
	   mentioned in r2.&lt;br /&gt;
	-  Add links to real bugs (including an RCE bug).&lt;br /&gt;
&lt;br /&gt;
	alx-0029r4 (2025-06-24):&lt;br /&gt;
	-  Use a better link for the Whatsapp RCE.&lt;br /&gt;
	-  s/Description/Rationale/&lt;br /&gt;
	-  wfix&lt;br /&gt;
	-  Mention that glibc &lt;2.1.1 had the BSD behavior.&lt;br /&gt;
	-  Add footnote that realloc(3) may fail while shrinking.&lt;br /&gt;
&lt;br /&gt;
	alx-0029r5 (2025-06-26):&lt;br /&gt;
	-  It was glibc 2.1.1 that broke it, not glibc 2.2.&lt;br /&gt;
	-  wfix&lt;br /&gt;
	-  Mention in the footnote that the pointer may change.&lt;br /&gt;
	-  Document why not go the other way around.  It was explained&lt;br /&gt;
	   several times during discussion, but people keep suggesting&lt;br /&gt;
	   it.&lt;br /&gt;
&lt;br /&gt;
	alx-0029r6 (2025-06-27; n3621):&lt;br /&gt;
	-  Clarify that the paragraph about what happens when the size&lt;br /&gt;
	   is zero refers to when the total size is zero (for calloc(3)&lt;br /&gt;
	   that is nmemb*size).&lt;br /&gt;
	-  s/Unix V7/V7 Unix/&lt;br /&gt;
	-  tfix.&lt;br /&gt;
	-  wfix.&lt;br /&gt;
&lt;br /&gt;
	Brno meeting (2025-08-27):&lt;br /&gt;
	-  9/13/6&lt;br /&gt;
	-  Along the lines: 21/1/5&lt;br /&gt;
	-  People recognized in the dinner after the meeting, and in the&lt;br /&gt;
	   reflector, and in corridor discussions, that they hadn't&lt;br /&gt;
	   understood the paper, and that it was more well thought than&lt;br /&gt;
	   they initially thought.  They would change their vote to be&lt;br /&gt;
	   in favour with this proposal.&lt;br /&gt;
&lt;br /&gt;
	alx-0029r7 (2025-09-21):&lt;br /&gt;
	-  Add link.&lt;br /&gt;
&lt;br /&gt;
	alx-p0001r0 (2025-09-21):&lt;br /&gt;
	-  Fork POSIX proposal from ISO C proposal.&lt;br /&gt;
&lt;br /&gt;
See also&lt;br /&gt;
	&lt;&lt;a href=&quot;https://www.alejandro-colomar.es/src/alx/alx/wg14/alx-0069.git/&gt;&quot; rel=&quot;noopener&quot;&gt;https://www.alejandro-colomar.es/src/alx/alx/wg14/alx-0069.git/&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://nabijaczleweli.xyz/content/blogn_t/017-malloc0.html&gt;&quot; rel=&quot;noopener&quot;&gt;https://nabijaczleweli.xyz/content/blogn_t/017-malloc0.html&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://sourceware.org/pipermail/libc-alpha/1999-April/000956.html&gt;&quot; rel=&quot;noopener&quot;&gt;https://sourceware.org/pipermail/libc-alpha/1999-April/000956.html&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://inbox.sourceware.org/libc-alpha/nbyurzcgzgd5rdybbi4no2kw5grrc32k63svf7oq73nfcbus5r@77gry66kpqfr/&gt;&quot; rel=&quot;noopener&quot;&gt;https://inbox.sourceware.org/libc-alpha/nbyurzcgzgd5rdybbi4no2kw5grrc32k63svf7oq73nfcbus5r@77gry66kpqfr/&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://inbox.sourceware.org/libc-alpha/20241019014002.3684656-1-siddhesh@sourceware.org/T/#u&gt;&quot; rel=&quot;noopener&quot;&gt;https://inbox.sourceware.org/libc-alpha/20241019014002.3684656-1-siddhesh@sourceware.org/T/#u&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://inbox.sourceware.org/libc-alpha/qukfe5yxycbl5v7ooskvqdnm3au3orohbx4babfltegi47iyly@or6dgf7akeqv/T/#u&gt;&quot; rel=&quot;noopener&quot;&gt;https://inbox.sourceware.org/libc-alpha/qukfe5yxycbl5v7ooskvqdnm3au3orohbx4babfltegi47iyly@or6dgf7akeqv/T/#u&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://github.com/bminor/glibc/commit/7c2b945e1fd64e0a5a4dbd6ae6592a7314dcd4b5&gt;&quot; rel=&quot;noopener&quot;&gt;https://github.com/bminor/glibc/commit/7c2b945e1fd64e0a5a4dbd6ae6592a7314dcd4b5&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://github.com/llvm/llvm-project/issues/113065&gt;&quot; rel=&quot;noopener&quot;&gt;https://github.com/llvm/llvm-project/issues/113065&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://www.austingroupbugs.net/view.php?id=400&gt;&quot; rel=&quot;noopener&quot;&gt;https://www.austingroupbugs.net/view.php?id=400&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://www.austingroupbugs.net/view.php?id=526&gt;&quot; rel=&quot;noopener&quot;&gt;https://www.austingroupbugs.net/view.php?id=526&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://www.austingroupbugs.net/view.php?id=688&gt;&quot; rel=&quot;noopener&quot;&gt;https://www.austingroupbugs.net/view.php?id=688&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://sourceware.org/bugzilla/show_bug.cgi?id=12547&gt;&quot; rel=&quot;noopener&quot;&gt;https://sourceware.org/bugzilla/show_bug.cgi?id=12547&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_400.htm&gt;&quot; rel=&quot;noopener&quot;&gt;https://www.open-std.org/jtc1/sc22/wg14/www/docs/dr_400.htm&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg14/www/docs/n868.htm&gt;&quot; rel=&quot;noopener&quot;&gt;https://www.open-std.org/jtc1/sc22/wg14/www/docs/n868.htm&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2438.htm&gt;&quot; rel=&quot;noopener&quot;&gt;https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2438.htm&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2464.pdf&gt;&quot; rel=&quot;noopener&quot;&gt;https://www.open-std.org/jtc1/sc22/wg14/www/docs/n2464.pdf&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/functions/realloc.html&gt;&quot; rel=&quot;noopener&quot;&gt;https://pubs.opengroup.org/onlinepubs/9699919799.2008edition/functions/realloc.html&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://pubs.opengroup.org/onlinepubs/9699919799.2013edition/functions/realloc.html&gt;&quot; rel=&quot;noopener&quot;&gt;https://pubs.opengroup.org/onlinepubs/9699919799.2013edition/functions/realloc.html&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120744&gt;&quot; rel=&quot;noopener&quot;&gt;https://gcc.gnu.org/bugzilla/show_bug.cgi?id=120744&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://lore.kernel.org/lkml/20220213182443.4037039-1-keescook@chromium.org/&gt;&quot; rel=&quot;noopener&quot;&gt;https://lore.kernel.org/lkml/20220213182443.4037039-1-keescook@chromium.org/&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://awakened1712.github.io/hacking/hacking-whatsapp-gif-rce/&gt;&quot; rel=&quot;noopener&quot;&gt;https://awakened1712.github.io/hacking/hacking-whatsapp-gif-rce/&gt;&lt;/a&gt;&lt;br /&gt;
	&lt;&lt;a href=&quot;https://gbhackers.com/whatsapp-double-free-vulnerability/&gt;&quot; rel=&quot;noopener&quot;&gt;https://gbhackers.com/whatsapp-double-free-vulnerability/&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Rationale&lt;br /&gt;
	The specification of realloc(3) has been problematic since the&lt;br /&gt;
	very first standards, even before ISO C.  The wording has&lt;br /&gt;
	changed significantly, trying to forcedly permit implementations&lt;br /&gt;
	to return a null pointer when the requested size is zero.  This&lt;br /&gt;
	originated from the intent of banning zero-sized objects from&lt;br /&gt;
	the language in C89, but that never worked well in&lt;br /&gt;
	retrospective, as we can see from the fallout.&lt;br /&gt;
&lt;br /&gt;
	None of the specifications have been good, and C23 finally gave&lt;br /&gt;
	up and made it undefined behavior.&lt;br /&gt;
&lt;br /&gt;
	The problem is not only theoretical.  Programmers don't know how&lt;br /&gt;
	to use realloc(3) correctly, and have written weird code in&lt;br /&gt;
	their attempts.  This has resulted in a lot of non-sensical code&lt;br /&gt;
	in configure scripts[1], and even bugs in actual programs[2].&lt;br /&gt;
&lt;br /&gt;
	[1] &lt;&lt;a href=&quot;https://codesearch.debian.net/search?q=%5Cbrealloc%5B+%5Ct%5D*%5B%28%5D%5B%5E%2C%5D*%2C%5B+%5Ct%5D0%5B%29%5D&amp;literal=0&gt;&quot; rel=&quot;noopener&quot;&gt;https://codesearch.debian.net/search?q=%5Cbrealloc%5B+%5Ct%5D*%5B%28%5D%5B%5E%2C%5D*%2C%5B+%5Ct%5D0%5B%29%5D&amp;literal=0&gt;&lt;/a&gt;&lt;br /&gt;
	[2] &lt;&lt;a href=&quot;https://lore.kernel.org/lkml/20220213182443.4037039-1-keescook@chromium.org/&gt;&quot; rel=&quot;noopener&quot;&gt;https://lore.kernel.org/lkml/20220213182443.4037039-1-keescook@chromium.org/&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
	In some cases, this non-sensical code has resulted in RCEs[3].&lt;br /&gt;
&lt;br /&gt;
	[3] &lt;&lt;a href=&quot;https://awakened1712.github.io/hacking/hacking-whatsapp-gif-rce/&gt;&quot; rel=&quot;noopener&quot;&gt;https://awakened1712.github.io/hacking/hacking-whatsapp-gif-rce/&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
	However, this doesn't need to be like that.  The traditional&lt;br /&gt;
	implementation of realloc(3), present in V7 Unix, inherited by&lt;br /&gt;
	the BSDs, and currently available in a range of systems,&lt;br /&gt;
	including musl libc, doesn't have any issues regarding zero-size&lt;br /&gt;
	allocations.  glibc --which uses an independent implementation&lt;br /&gt;
	rather than a Unix derivative-- also had this behavior&lt;br /&gt;
	originally; it changed to the current behavior in 1999&lt;br /&gt;
	(glibc 2.1.1), only for compatibility with C89, even though&lt;br /&gt;
	ironically C99 was released soon after and removed the text that&lt;br /&gt;
	glibc was trying to comply with, and introduced some new text&lt;br /&gt;
	that was very confusing, and one of its interpretations would&lt;br /&gt;
	make the new glibc behavior non-conforming.&lt;br /&gt;
&lt;br /&gt;
	Code written for platforms returning a null pointer can be&lt;br /&gt;
	migrated to platforms returning non-null, without significant&lt;br /&gt;
	issues.&lt;br /&gt;
&lt;br /&gt;
	There are two kinds of code that call realloc(p,0).  One&lt;br /&gt;
	hard-codes the 0, and is used as a replacement of free(p).  This&lt;br /&gt;
	code ignores the return value, since it's unimportant.  This&lt;br /&gt;
	code currently produces a leak of 0 bytes plus associated&lt;br /&gt;
	metadata on platforms such as musl libc, where it returns a&lt;br /&gt;
	non-null pointer.  However, assuming that there are programs&lt;br /&gt;
	written with the knowledge that they won't ever be run on such&lt;br /&gt;
	platforms, we should take care of that, and make sure they don't&lt;br /&gt;
	leak.  A way of accomplishing this would be to recommend&lt;br /&gt;
	implementations to issue a diagnostic when realloc(3) is called&lt;br /&gt;
	with a hardcoded zero.  This is only an informal recommendation&lt;br /&gt;
	made by this proposal, as this is a matter of QoI, and the&lt;br /&gt;
	standard shouldn't say anything about it.  This would prevent&lt;br /&gt;
	this class of minor leaks.&lt;br /&gt;
&lt;br /&gt;
	Moreover, in glibc, realloc(p,0) may return non-null, in the&lt;br /&gt;
	case where p is NULL, so code must already take that into&lt;br /&gt;
	account, and thus code that simply takes realloc(p,0) as a&lt;br /&gt;
	synonym of free(p) is already leaky, as free(NULL) is a no-op,&lt;br /&gt;
	but realloc(NULL,0) allocates 0 bytes.&lt;br /&gt;
&lt;br /&gt;
	The other kind of code is in algorithms that realloc(3) an&lt;br /&gt;
	arbitrary size, which might eventually be zero.  This gets more&lt;br /&gt;
	complex.&lt;br /&gt;
&lt;br /&gt;
	Here's the code that should be written for AIX or glibc:&lt;br /&gt;
&lt;br /&gt;
		errno = 0;&lt;br /&gt;
		new = realloc(old, size);&lt;br /&gt;
		if (new == NULL) {&lt;br /&gt;
			if (errno == ENOMEM)&lt;br /&gt;
				free(old);&lt;br /&gt;
			goto fail;&lt;br /&gt;
		}&lt;br /&gt;
		...&lt;br /&gt;
		free(new);&lt;br /&gt;
&lt;br /&gt;
	Failing to check for ENOMEM in these platforms before freeing&lt;br /&gt;
	the old pointer would result in a double-free.  If the program&lt;br /&gt;
	decides to continue using the old pointer instead of freeing it,&lt;br /&gt;
	it would result in a use-after-free.&lt;br /&gt;
&lt;br /&gt;
	In the platforms where realloc(p,0) returns non-null, such as&lt;br /&gt;
	the BSDs or musl libc, it is simpler to handle it:&lt;br /&gt;
&lt;br /&gt;
		new = realloc(old, size);&lt;br /&gt;
		if (new == NULL) {  // errno is ENOMEM&lt;br /&gt;
			free(old);&lt;br /&gt;
			goto fail;&lt;br /&gt;
		}&lt;br /&gt;
		...&lt;br /&gt;
		free(new);&lt;br /&gt;
&lt;br /&gt;
	Whenever the result is a null pointer, these platforms are&lt;br /&gt;
	reporting an ENOMEM error, and thus it is superfluous to check&lt;br /&gt;
	errno there.&lt;br /&gt;
&lt;br /&gt;
	Most code is written in this way, even if run on platforms&lt;br /&gt;
	returning a null pointer.  This is because most programmers are&lt;br /&gt;
	just unaware of this problem.  Part of the reason is also that&lt;br /&gt;
	returning a non-null pointer with zero bytes is the natural&lt;br /&gt;
	extension of the behavior, which is what programmers intuitively&lt;br /&gt;
	expect from libc; that is, if realloc(p,3) allocates 3 bytes,&lt;br /&gt;
	r(p,2) allocates two bytes, and r(p,1) allocates one byte, it is&lt;br /&gt;
	natural by induction to expect that r(p,0) will allocate zero&lt;br /&gt;
	bytes.  Most algorithms naturally extend to 0 just fine, and&lt;br /&gt;
	special casing 0 is artificial.&lt;br /&gt;
&lt;br /&gt;
	If the realloc(3) specification were changed to require that&lt;br /&gt;
	realloc(p,0) returns non-null on success, and that realloc(p,0)&lt;br /&gt;
	only fails when out-of-memory (and assuming the implementations&lt;br /&gt;
	will continue setting errno to ENOMEM), then code written for&lt;br /&gt;
	AIX or glibc would continue working just fine, since the errno&lt;br /&gt;
	check would be redundant with the null check.  Simply, the&lt;br /&gt;
	conditional (errno == ENOMEM) would always be true when&lt;br /&gt;
	(new == NULL).&lt;br /&gt;
&lt;br /&gt;
	Then, there are non-POSIX platforms that don't set ENOMEM.  In&lt;br /&gt;
	those platforms, code might do this:&lt;br /&gt;
&lt;br /&gt;
		new = realloc(old, size);&lt;br /&gt;
		if (new == NULL) {&lt;br /&gt;
			if (size != 0)&lt;br /&gt;
				free(old);&lt;br /&gt;
			goto fail;&lt;br /&gt;
		}&lt;br /&gt;
		...&lt;br /&gt;
		free(new);&lt;br /&gt;
&lt;br /&gt;
	That code would continue working with this proposal, except for&lt;br /&gt;
	a very rare corner case, in which it would leak.  In the normal&lt;br /&gt;
	case, (size != 0) would never be true under (new == NULL),&lt;br /&gt;
	because a reallocation of 0 bytes would almost always succeed,&lt;br /&gt;
	and thus not return a null pointer under this proposal.&lt;br /&gt;
	However, in some cases, the system might not find space even for&lt;br /&gt;
	the small metadata needed for a 0-byte allocation.  In such&lt;br /&gt;
	case, the (size != 0) conditional would prevent deallocating&lt;br /&gt;
	'old', and thus cause a memory leak.  This case is exceptional&lt;br /&gt;
	enough that it shouldn't stop us from fixing realloc(3).&lt;br /&gt;
	Anyway, on an out-of-memory case, the program is likely to&lt;br /&gt;
	terminate rather soon, so the issue is even less likely to have&lt;br /&gt;
	an impact on any existing programs.  Also, LLVM's address&lt;br /&gt;
	sanitizer will soon able to catch such a leak:&lt;br /&gt;
	&lt;&lt;a href=&quot;https://github.com/llvm/llvm-project/issues/113065&gt;&quot; rel=&quot;noopener&quot;&gt;https://github.com/llvm/llvm-project/issues/113065&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
	This proposal makes handling of realloc(3) as straightforward as&lt;br /&gt;
	one would expect, with only two states: success or error.  There&lt;br /&gt;
	are no in-between states.&lt;br /&gt;
&lt;br /&gt;
	The resulting wording in the standard is also much simpler, as&lt;br /&gt;
	it doesn't need to define so many special cases.&lt;br /&gt;
&lt;br /&gt;
	For consistency, all the other allocation functions are updated&lt;br /&gt;
	to both return a null pointer on error, and use consistent&lt;br /&gt;
	wording.&lt;br /&gt;
&lt;br /&gt;
    Why not go the other way around?&lt;br /&gt;
	Some people keep asking why not go the other way around: why not&lt;br /&gt;
	force the BSDs and musl to return a null pointer if size is 0.&lt;br /&gt;
	This would result in double-free and use-after-free bugs, which&lt;br /&gt;
	can result in RCE vulnerabilities (remote code execution), which&lt;br /&gt;
	is clearly unacceptable.&lt;br /&gt;
&lt;br /&gt;
	Consider this code, which is the usual code for calling&lt;br /&gt;
	realloc(3) in such systems:&lt;br /&gt;
&lt;br /&gt;
		new = realloc(old, size);&lt;br /&gt;
		if (new == NULL) {&lt;br /&gt;
			free(old);&lt;br /&gt;
			goto fail;&lt;br /&gt;
		}&lt;br /&gt;
		...&lt;br /&gt;
		free(new);&lt;br /&gt;
&lt;br /&gt;
	If realloc(p,0) would return a null pointer and free the old&lt;br /&gt;
	block, then the third line would be a double-free bug.&lt;br /&gt;
&lt;br /&gt;
Prior art&lt;br /&gt;
    gnulib&lt;br /&gt;
	gnulib provides the realloc-posix module, which aims to wrap the&lt;br /&gt;
	system realloc(3) and reallocarray(3) functions so that they&lt;br /&gt;
	behave in a POSIX-complying manner.&lt;br /&gt;
&lt;br /&gt;
	It previously behaved like glibc.  After I reported that it was&lt;br /&gt;
	non-conforming to POSIX, we discussed the best way forward,&lt;br /&gt;
	which we agreed was the same direction that this paper is&lt;br /&gt;
	proposing now for C2y.  The implementation was changed in&lt;br /&gt;
&lt;br /&gt;
		gnulib.git d884e6fc4a60 (2024-11-04; &quot;realloc-posix: realloc (..., 0) now returns nonnull&quot;)&lt;br /&gt;
&lt;br /&gt;
	There have been no regression reports since then, as we&lt;br /&gt;
	expected.&lt;br /&gt;
&lt;br /&gt;
    V7 Unix, BSD&lt;br /&gt;
	The proposed behavior is the one endorsed by Doug McIlroy, the&lt;br /&gt;
	author of the original implementation of realloc(3) in V7 Unix,&lt;br /&gt;
	and also present in the BSDs.&lt;br /&gt;
&lt;br /&gt;
    glibc &lt;= 2.1&lt;br /&gt;
	glibc was implemented originally to return non-null.  It was&lt;br /&gt;
	only in 1999, and purely to comply with the standards --with no&lt;br /&gt;
	requests by users to do so--, that the glibc maintainers decided&lt;br /&gt;
	to switch to the current behavior.&lt;br /&gt;
&lt;br /&gt;
Design decisions&lt;br /&gt;
	This change needs two changes, which can be applied all at once,&lt;br /&gt;
	or in separate steps.&lt;br /&gt;
&lt;br /&gt;
	The first step would make realloc(p,s) be consistent with&lt;br /&gt;
	free(p) and malloc(s), including when p is a null pointer, when&lt;br /&gt;
	s is zero, and also when both corner cases happen at the same&lt;br /&gt;
	time.  This change would already turn the implementations where&lt;br /&gt;
	malloc(0) returns non-null into the end goal we have.  This&lt;br /&gt;
	would require changes to (at least) the following&lt;br /&gt;
	implementations: glibc, Bionic, Windows.&lt;br /&gt;
&lt;br /&gt;
	The second step would be to require that malloc(0) returns a&lt;br /&gt;
	non-null pointer.  This would require changes to (at least) the&lt;br /&gt;
	following implementations: AIX.&lt;br /&gt;
&lt;br /&gt;
	This proposal has merged all steps into a single proposal.&lt;br /&gt;
&lt;br /&gt;
Caveats&lt;br /&gt;
    n?n:1&lt;br /&gt;
	Code written in the near future should be careful, in case it&lt;br /&gt;
	can run on older systems that are not fixed to comply with this&lt;br /&gt;
	stricter specification.  Thus, code written in the near future&lt;br /&gt;
	should call realloc(3) similar to this:&lt;br /&gt;
&lt;br /&gt;
		realloc(p, n?n:1);&lt;br /&gt;
&lt;br /&gt;
	When all existing implementations are fixed to comply with this&lt;br /&gt;
	stricter specification, that workaround can be removed.&lt;br /&gt;
&lt;br /&gt;
    ENOMEM&lt;br /&gt;
	Existing implementations that set errno to ENOMEM must continue&lt;br /&gt;
	doing so when the input pointer is not freed.  If they didn't,&lt;br /&gt;
	code that is currently portable to all POSIX systems&lt;br /&gt;
&lt;br /&gt;
		errno = 0;&lt;br /&gt;
		new = realloc(old, size);&lt;br /&gt;
		if (new == NULL) {&lt;br /&gt;
			if (errno == ENOMEM)&lt;br /&gt;
				free(old);&lt;br /&gt;
			goto fail;&lt;br /&gt;
		}&lt;br /&gt;
		...&lt;br /&gt;
		free(new);&lt;br /&gt;
&lt;br /&gt;
	would leak on error.&lt;br /&gt;
&lt;br /&gt;
	Since it is currently impossible to write code today that is&lt;br /&gt;
	portable to arbitrary C17 systems, this is not an issue in&lt;br /&gt;
	ISO C.&lt;br /&gt;
&lt;br /&gt;
		-  New code written for C2y will only need to check for&lt;br /&gt;
		   NULL to detect errors.&lt;br /&gt;
&lt;br /&gt;
		-  Code written for specific C17 and older platforms&lt;br /&gt;
		   that don't set errno will continue to work for those&lt;br /&gt;
		   specific platforms.&lt;br /&gt;
&lt;br /&gt;
		-  Code written for POSIX.1-2024 and older platforms&lt;br /&gt;
		   will continue working on POSIX C2y platforms,&lt;br /&gt;
		   assuming that POSIX will continue mandating ENOMEM.&lt;br /&gt;
&lt;br /&gt;
		-  Code written for POSIX.1-2024 and older will not be&lt;br /&gt;
		   able to be run on non-POSIX C2y platforms, but that&lt;br /&gt;
		   could be expected.&lt;br /&gt;
&lt;br /&gt;
	The only important thing is that platforms that did set ENOMEM&lt;br /&gt;
	should continue setting it, to avoid introducing leaks.]]></description><category>System Interfaces</category><pubDate>Mon, 10 Aug 2026 08:55:56 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1949</guid><comments>https://austingroupbugs.net/view.php?id=1949#bugnotes</comments></item><item><title>0001984: Ambiguous requirements for command -v on printing absolute pathnames</title><author></author><link>https://austingroupbugs.net/view.php?id=1984</link><description><![CDATA[The requirements for command -v read:&lt;br /&gt;
&lt;br /&gt;
- Executable utilities, regular built-in utilities, command_names including a &lt;slash&gt; character, and any implementation-provided functions that are found using the PATH variable (as described in 2.9.1.4 Command Search and Execution), shall be written as absolute pathnames.&lt;br /&gt;
&lt;br /&gt;
This is ambiguous as to whether &quot;that are found using the PATH variable&quot; applies to &quot;Executable utilities, regular built-in utilities, command_names including a &lt;slash&gt; character, and any implementation-provided functions&quot;, or only to &quot;any implementation-provided functions&quot;.&lt;br /&gt;
&lt;br /&gt;
Given that &quot;command_names including a &lt;slash&gt; character&quot; are never looked up using the PATH variable (as pointed out by Herbert Xu on the dash mailing list), the intent must be that &quot;that are found using the PATH variable&quot; applies only to &quot;any implementation-provided functions&quot;, but at least one shell (bash) does not currently write command_names including a &lt;slash&gt; character as absolute pathnames, even in POSIX mode, and in my opinion, the current text of the standard does not say it should.]]></description><category>Shell and Utilities</category><pubDate>Wed, 29 Jul 2026 07:19:22 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1984</guid><comments>https://austingroupbugs.net/view.php?id=1984#bugnotes</comments></item><item><title>0001993: pthread_create() should allow failure with ENOMEM, not just EAGAIN</title><author></author><link>https://austingroupbugs.net/view.php?id=1993</link><description><![CDATA[pthread_create() is currently defined to allow EAGAIN or EPERM. while _some_ resource issues fit EAGAIN, others do not warrant a retry loop. glibc and bionic both want to return ENOMEM in particular as an unretriable failure.]]></description><category>System Interfaces</category><pubDate>Tue, 28 Jul 2026 08:55:40 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1993</guid><comments>https://austingroupbugs.net/view.php?id=1993#bugnotes</comments></item><item><title>0001973: awk "numeric string " origins</title><author></author><link>https://austingroupbugs.net/view.php?id=1973</link><description><![CDATA[The awk specification (&lt;a href=&quot;https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/utilities/awk.html#tag_20_06_13_02&quot; rel=&quot;noopener&quot;&gt;https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/utilities/awk.html#tag_20_06_13_02&lt;/a&gt;) has:&lt;br /&gt;
&lt;br /&gt;
&lt;&lt;&lt;&lt;br /&gt;
 A string value shall be considered a numeric string if it comes from one of the following:&lt;br /&gt;
&lt;br /&gt;
     1. Field variables&lt;br /&gt;
     2. Input from the getline() function&lt;br /&gt;
     3. FILENAME&lt;br /&gt;
     4. ARGV array elements&lt;br /&gt;
     5. ENVIRON array elements&lt;br /&gt;
     6. Array elements created by the split() function&lt;br /&gt;
     7. A command line variable assignment&lt;br /&gt;
     8. Variable assignment from another numeric string variable&lt;br /&gt;
&gt;&gt;&gt;&lt;br /&gt;
&lt;br /&gt;
It can be interpreted as meaning that&lt;br /&gt;
&lt;br /&gt;
awk 'BEGIN{$1 = &quot;10&quot;; print ($1 &gt; 2)}'&lt;br /&gt;
&lt;br /&gt;
should return 1 for instance. But no implementation that I know does so. By assigning a string to $1, it loses that special property whereby when containing a string that looks like a number it shall be considered as a number.&lt;br /&gt;
&lt;br /&gt;
Same applies for ARGV, FILENAME...&lt;br /&gt;
&lt;br /&gt;
Typo in rationale section btw:&lt;br /&gt;
&lt;br /&gt;
&gt; also shall have the numeric value of the numeric string&quot; was removed&lt;br /&gt;
&gt;from several sections of the ISO POSIX-2:1993 standard because *is* &lt;br /&gt;
&gt; specifies an unnecessary implementation detail&lt;br /&gt;
&lt;br /&gt;
is -&gt; it]]></description><category>Shell and Utilities</category><pubDate>Mon, 20 Jul 2026 16:11:56 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1973</guid><comments>https://austingroupbugs.net/view.php?id=1973#bugnotes</comments></item><item><title>0001987: The option value type for TCP_NODELAY is not specified.</title><author></author><link>https://austingroupbugs.net/view.php?id=1987</link><description><![CDATA[The option value type for TCP_NODELAY is not specified. This seem to be the case since at least Issue 6.&lt;br /&gt;
&lt;br /&gt;
Many other options have types of rank `int`, and their Windows counterparts often have DWORD or similar, as such I believe the type for this option value is most likely also `int`, rather than `_Bool` which may have issue with ABI compatibility.]]></description><category>Base Definitions and Headers</category><pubDate>Mon, 20 Jul 2026 15:36:02 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1987</guid><comments>https://austingroupbugs.net/view.php?id=1987#bugnotes</comments></item><item><title>0001991: touch -d 2026-06-29T00:00:60 should not be required to succeed</title><author></author><link>https://austingroupbugs.net/view.php?id=1991</link><description><![CDATA[The POSIX spec for 'touch' (POSIX.1-2024 page 3451 line 117731) specifies an option -d whose argument uses ISO 8601 notation to specify the time. However, if read literally there is a disagreement with ISO 8601 that I believe is unintentional, and which causes GNU coreutils 'touch' to fail to conform.&lt;br /&gt;
&lt;br /&gt;
The apparent disagreement was introduced in POSIX.1-2017, when -d was added with ISO 8601 syntax, but with semantics that seem to defer to the longstanding -t option in the treatment of the seconds (SS) field, namely, if SS is 60 that should mean the first second of the next minute. This meaning for SS contradicts ISO 8601, which says an SS value of 60 can only mean a leap second.&lt;br /&gt;
&lt;br /&gt;
I expect this disagreement with ISO 8601 was unintentional. Furthermore, the disagreement disagrees with GNU 'touch', which reserves SS=60 for true leap seconds which exist on (non-POSIX) platforms that support leap seconds.&lt;br /&gt;
&lt;br /&gt;
GNU 'touch' takes the not unreasonable position that it is helpful to catch typos, such as hours, minutes or seconds that are out of ISO 8601 range. POSIX surely did not intend to require implementations to implement timestamps in a way that disagrees with ISO 8601. Although some implementations, such as FreeBSD 'touch', treat &quot;:60&quot; as meaning the first second of the next minute, this behavior should not be required.]]></description><category>Shell and Utilities</category><pubDate>Mon, 13 Jul 2026 09:13:35 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1991</guid><comments>https://austingroupbugs.net/view.php?id=1991#bugnotes</comments></item><item><title>0001979: conflicting specification for open("existing-directory", O_RDONLY | O_CREAT, 0644)</title><author></author><link>https://austingroupbugs.net/view.php?id=1979</link><description><![CDATA[The description of open() explains O_CREAT with a paragraph that starts:&lt;br /&gt;
&lt;br /&gt;
O_CREAT   If the file exists, this flag has no effect except as noted under O_EXCL below.  &lt;...&gt;&lt;br /&gt;
&lt;br /&gt;
'file' is of course the XBD 'file' which includes directories, devices, etc.  So, open(O_RDONLY|O_CREAT) naming a directory that exists should behave the same as open(O_RDONLY) of that same path.&lt;br /&gt;
&lt;br /&gt;
Then later the ERRORS section contradicts that:&lt;br /&gt;
&lt;br /&gt;
[EISDIR]    The named file is a directory and oflag includes O_WRONLY or O_RDWR, or&lt;br /&gt;
                  includes O_CREAT without O_DIRECTORY, or &lt;...&gt;]]></description><category>System Interfaces</category><pubDate>Mon, 13 Jul 2026 09:02:53 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1979</guid><comments>https://austingroupbugs.net/view.php?id=1979#bugnotes</comments></item><item><title>0001989: Confusing reference to "Symbol" for $0</title><author></author><link>https://austingroupbugs.net/view.php?id=1989</link><description><![CDATA[&gt; The symbol $0 shall refer to the entire record&lt;br /&gt;
&lt;br /&gt;
It's not a &quot;symbol&quot;, it's the $ operator applied to number 0 that yields the &quot;full record variable&quot;, $ 0, $(12/4-3) refer to the same variable.]]></description><category>Shell and Utilities</category><pubDate>Thu, 09 Jul 2026 15:25:35 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1989</guid><comments>https://austingroupbugs.net/view.php?id=1989#bugnotes</comments></item><item><title>0001988: Incorrect reference to "whole input record" for $0</title><author></author><link>https://austingroupbugs.net/view.php?id=1988</link><description><![CDATA[In&lt;br /&gt;
&lt;br /&gt;
&gt; The print statement shall write the value of each expression&lt;br /&gt;
&gt; argument onto the indicated output stream separated by the&lt;br /&gt;
&gt; current output field separator (see variable OFS above), and&lt;br /&gt;
&gt; terminated by the output record separator (see variable ORS&lt;br /&gt;
&gt; above). All expression arguments shall be taken as strings,&lt;br /&gt;
&gt; being converted if necessary; this conversion shall be as&lt;br /&gt;
&gt; described in Expressions in awk, with the exception that the&lt;br /&gt;
&gt; printf format in OFMT shall be used instead of the value in&lt;br /&gt;
&gt; CONVFMT. An empty expression list shall stand for the whole&lt;br /&gt;
&gt; input record ($0).&lt;br /&gt;
&lt;br /&gt;
That late sentence is erroneous and misleading as $0's value is only the input record after that record has been read in and before it has been modified.]]></description><category>Shell and Utilities</category><pubDate>Thu, 09 Jul 2026 15:19:49 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1988</guid><comments>https://austingroupbugs.net/view.php?id=1988#bugnotes</comments></item><item><title>0001985: Add a dark theme to the HTML rendition</title><author></author><link>https://austingroupbugs.net/view.php?id=1985</link><description><![CDATA[Right now, there's only a light theme of the HTML rendition, which has a bright background.&lt;br /&gt;
&lt;br /&gt;
This may cause eye sore for some readers, who switches back and forth between their IDE and the standard text.]]></description><category>Base Definitions and Headers</category><pubDate>Thu, 02 Jul 2026 15:31:44 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1985</guid><comments>https://austingroupbugs.net/view.php?id=1985#bugnotes</comments></item><item><title>0001548: Addition of a POSIX.utf-8 locale (likely as 7.3 "POSIX.utf-8 locale")</title><author></author><link>https://austingroupbugs.net/view.php?id=1548</link><description><![CDATA[Today's modern POSIX systems use Unicode aware locales, almost all realized via the UTF-8 8-bit character set.&lt;br /&gt;
Even though the standard(s) do not offer proper interfaces to deal with this, external libraries (GNU libunicode, ICU) fill this gap in practice.&lt;br /&gt;
(These libraries can also be used with UTF-16 and UTF-32 character sets, the latter i think prefers the 16-bit encoding that is in use in a widely distributed commercial non-POSIX operating system.)&lt;br /&gt;
&lt;br /&gt;
As it stands users are using language/territory specific UTF-8 locales in real-life, like en_US.utf8 or de_DE.utf8.&lt;br /&gt;
Right now there is no UTF-8 aka Unicode-spectrum POSIX locale available.&lt;br /&gt;
&lt;br /&gt;
Some operating systems (OpenBSD) and some libraries (musl LibC) however, and already, &quot;always work with UTF-8 8-bit&quot; Unicode, giving it the name &quot;C.UTF-8&quot; (musl; and as can be seen, the usual naming scheme mess continues).]]></description><category>Base Definitions and Headers</category><pubDate>Thu, 02 Jul 2026 12:38:11 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1548</guid><comments>https://austingroupbugs.net/view.php?id=1548#bugnotes</comments></item><item><title>0001990: This is a configuration test issue. Please ignore if you see this.</title><author></author><link>https://austingroupbugs.net/view.php?id=1990</link><description><![CDATA[Please ignore.]]></description><category>Base Definitions and Headers</category><pubDate>Thu, 25 Jun 2026 19:55:24 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1990</guid><comments>https://austingroupbugs.net/view.php?id=1990#bugnotes</comments></item><item><title>0001986: This is a configuration test issue. Please ignore if you see this.</title><author></author><link>https://austingroupbugs.net/view.php?id=1986</link><description><![CDATA[Test a new email notification configuration on the new hosting setup.]]></description><category>Base Definitions and Headers</category><pubDate>Thu, 25 Jun 2026 18:33:07 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1986</guid><comments>https://austingroupbugs.net/view.php?id=1986#bugnotes</comments></item><item><title>0001983: typo in sendmsg() EXAMPLES</title><author></author><link>https://austingroupbugs.net/view.php?id=1983</link><description><![CDATA[I'm forwarding a report I received by email from someone else.&lt;br /&gt;
&lt;br /&gt;
On 2026-06-02T15:02:40+0800, Zhai Can wrote:&lt;br /&gt;
&gt; &lt;a href=&quot;https://man7.org/linux/man-pages/man3/sendmsg.3p.html&quot; rel=&quot;noopener&quot;&gt;https://man7.org/linux/man-pages/man3/sendmsg.3p.html&lt;/a&gt;&lt;br /&gt;
&gt;&lt;br /&gt;
&gt; In the EXAMPLES section it states a &quot;Done.&quot; which is weird here. I suppose it&lt;br /&gt;
&gt; should be a &quot;None.&quot;? A quick grep shows the whole 3p manuals (2017) only have&lt;br /&gt;
&gt; the one occurrence.&lt;br /&gt;
&gt;&lt;br /&gt;
&gt;   ~/man-pages-posix-2017/man3p ❯ rg Done.&lt;br /&gt;
&gt;   sendmsg.3p&lt;br /&gt;
&gt;   281:Done.&lt;br /&gt;
&gt;&lt;br /&gt;
&gt; It's an upstream issue. Also in:&lt;br /&gt;
&gt;&lt;br /&gt;
&gt; &lt;a href=&quot;https://pubs.opengroup.org/onlinepubs/9799919799/&quot; rel=&quot;noopener&quot;&gt;https://pubs.opengroup.org/onlinepubs/9799919799/&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Reported-by: Zhai Can &lt;&lt;a href=&quot;mailto:bczhc0@126.com&quot;&gt;bczhc0@126.com&lt;/a&gt;&gt;]]></description><category>System Interfaces</category><pubDate>Thu, 04 Jun 2026 15:16:40 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1983</guid><comments>https://austingroupbugs.net/view.php?id=1983#bugnotes</comments></item><item><title>0001981: Request to define ssize_t as the signed version of size_t</title><author></author><link>https://austingroupbugs.net/view.php?id=1981</link><description><![CDATA[Currently ssize_t is defined as:&lt;br /&gt;
ssize_t shall be signed integer types.&lt;br /&gt;
The type ssize_t shall be capable of storing values at least in the range [-1, {SSIZE_MAX}].&lt;br /&gt;
&lt;br /&gt;
But the sizeof ssize_t is not explicitly defined.&lt;br /&gt;
&lt;br /&gt;
And for glibc,musl,cygwin newlib, they all defined that sizeof(ssize_t)=== sizeof(size_t)&lt;br /&gt;
&lt;br /&gt;
And maybe because the sizeof ssize_t is not defined clearly. clang did not defined the sizeof of ssize_t well:&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://github.com/llvm/llvm-project/issues/198975&quot; rel=&quot;noopener&quot;&gt;https://github.com/llvm/llvm-project/issues/198975&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
The glibc defined the sizeof ssize_t to be equal to size_t by the following codes:&lt;br /&gt;
#if __WORDSIZE == 32&lt;br /&gt;
# define __SWORD_TYPE		int&lt;br /&gt;
#else&lt;br /&gt;
# define __SWORD_TYPE		long int&lt;br /&gt;
#endif&lt;br /&gt;
&lt;br /&gt;
at&lt;br /&gt;
&lt;a href=&quot;https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/bits/types.h;h=33b582a8eabf09aadc093658db82353c288590d2;hb=HEAD#l118&quot; rel=&quot;noopener&quot;&gt;https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/bits/types.h;h=33b582a8eabf09aadc093658db82353c288590d2;hb=HEAD#l118&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
#define __SSIZE_T_TYPE          __SWORD_TYPE&lt;br /&gt;
at&lt;br /&gt;
&lt;a href=&quot;https://sourceware.org/git/?p=glibc.git;a=blob;f=bits/typesizes.h;h=466dd36681a7364952e49b73067d66174543cffd;hb=HEAD#l60&quot; rel=&quot;noopener&quot;&gt;https://sourceware.org/git/?p=glibc.git;a=blob;f=bits/typesizes.h;h=466dd36681a7364952e49b73067d66174543cffd;hb=HEAD#l60&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
__STD_TYPE __SSIZE_T_TYPE __ssize_t; /* Type of a byte count, or error.  */&lt;br /&gt;
at&lt;br /&gt;
&lt;a href=&quot;https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/bits/types.h;h=33b582a8eabf09aadc093658db82353c288590d2;hb=HEAD#l194&quot; rel=&quot;noopener&quot;&gt;https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/bits/types.h;h=33b582a8eabf09aadc093658db82353c288590d2;hb=HEAD#l194&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
#ifndef __ssize_t_defined&lt;br /&gt;
typedef __ssize_t ssize_t;&lt;br /&gt;
# define __ssize_t_defined&lt;br /&gt;
#endif&lt;br /&gt;
at&lt;br /&gt;
&lt;a href=&quot;https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/sys/types.h;h=2b524761748fc2e0576e3b86fd5558e8a9ebcb18;hb=HEAD#l108&quot; rel=&quot;noopener&quot;&gt;https://sourceware.org/git/?p=glibc.git;a=blob;f=posix/sys/types.h;h=2b524761748fc2e0576e3b86fd5558e8a9ebcb18;hb=HEAD#l108&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
And the document of __WORDSIZE is:&lt;br /&gt;
/* Size in bits of the 'long int' and pointer types.  */&lt;br /&gt;
#define __WORDSIZE&lt;br /&gt;
at &lt;br /&gt;
&lt;a href=&quot;https://sourceware.org/git/?p=glibc.git;a=blob;f=bits/wordsize.h;h=53013a9275c7c81eccb0356ab956eb2688bcf512;hb=HEAD#l7&quot; rel=&quot;noopener&quot;&gt;https://sourceware.org/git/?p=glibc.git;a=blob;f=bits/wordsize.h;h=53013a9275c7c81eccb0356ab956eb2688bcf512;hb=HEAD#l7&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
So basically glibc is already ensure ssize_t is the same size as size_t. Even thoug the command &quot;/* Size in bits of the 'long int' and pointer types.  */&quot; is a bit mis-leading.&lt;br /&gt;
As sizeof pointer will  not always have the same size as size_t.]]></description><category>Base Definitions and Headers</category><pubDate>Thu, 04 Jun 2026 15:12:53 +0000</pubDate><guid>https://austingroupbugs.net/view.php?id=1981</guid><comments>https://austingroupbugs.net/view.php?id=1981#bugnotes</comments></item></channel></rss>
