Bug 256486 - uname(1) doesn't strip whitespace from -v like uname(3)
Summary: uname(1) doesn't strip whitespace from -v like uname(3)
Status: New
Alias: None
Product: Base System
Classification: Unclassified
Component: standards (show other bugs)
Version: CURRENT
Hardware: Any Any
: --- Affects Only Me
Assignee: freebsd-standards (Nobody)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2021-06-08 17:25 UTC by наб
Modified: 2021-06-08 17:25 UTC (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description наб 2021-06-08 17:25:30 UTC
Consider the following, where ./out/cmd/uname -v just prints uname(3).version:

[build@build ~/voreutils]$ sysctl -b kern.version
FreeBSD 13.0-RELEASE-p1 #0: Wed May 26 22:15:09 UTC 2021
    root@amd64-builder.daemonology.net:/usr/obj/usr/src/amd64.amd64/sys/GENERIC
[build@build ~/voreutils]$ sysctl -b kern.version | hexdump -C
00000000  46 72 65 65 42 53 44 20  31 33 2e 30 2d 52 45 4c  |FreeBSD 13.0-REL|
00000010  45 41 53 45 2d 70 31 20  23 30 3a 20 57 65 64 20  |EASE-p1 #0: Wed |
00000020  4d 61 79 20 32 36 20 32  32 3a 31 35 3a 30 39 20  |May 26 22:15:09 |
00000030  55 54 43 20 32 30 32 31  0a 20 20 20 20 72 6f 6f  |UTC 2021.    roo|
00000040  74 40 61 6d 64 36 34 2d  62 75 69 6c 64 65 72 2e  |t@amd64-builder.|
00000050  64 61 65 6d 6f 6e 6f 6c  6f 67 79 2e 6e 65 74 3a  |daemonology.net:|
00000060  2f 75 73 72 2f 6f 62 6a  2f 75 73 72 2f 73 72 63  |/usr/obj/usr/src|
00000070  2f 61 6d 64 36 34 2e 61  6d 64 36 34 2f 73 79 73  |/amd64.amd64/sys|
00000080  2f 47 45 4e 45 52 49 43  0a 00                    |/GENERIC..|
0000008a
[build@build ~/voreutils]$ uname -v
FreeBSD 13.0-RELEASE-p1 #0: Wed May 26 22:15:09 UTC 2021     root@amd64-builder.daemonology.net:/usr/obj/usr/src/amd64.amd64/sys/GENERIC
[build@build ~/voreutils]$ ./out/cmd/uname -v
FreeBSD 13.0-RELEASE-p1 #0: Wed May 26 22:15:09 UTC 2021     root@amd64-builder.daemonology.net:/usr/obj/usr/src/amd64.amd64/sys/GENERIC
[build@build ~/voreutils]$ uname -v | hexdump -C
00000000  46 72 65 65 42 53 44 20  31 33 2e 30 2d 52 45 4c  |FreeBSD 13.0-REL|
00000010  45 41 53 45 2d 70 31 20  23 30 3a 20 57 65 64 20  |EASE-p1 #0: Wed |
00000020  4d 61 79 20 32 36 20 32  32 3a 31 35 3a 30 39 20  |May 26 22:15:09 |
00000030  55 54 43 20 32 30 32 31  20 20 20 20 20 72 6f 6f  |UTC 2021     roo|
00000040  74 40 61 6d 64 36 34 2d  62 75 69 6c 64 65 72 2e  |t@amd64-builder.|
00000050  64 61 65 6d 6f 6e 6f 6c  6f 67 79 2e 6e 65 74 3a  |daemonology.net:|
00000060  2f 75 73 72 2f 6f 62 6a  2f 75 73 72 2f 73 72 63  |/usr/obj/usr/src|
00000070  2f 61 6d 64 36 34 2e 61  6d 64 36 34 2f 73 79 73  |/amd64.amd64/sys|
00000080  2f 47 45 4e 45 52 49 43  20 0a                    |/GENERIC .|
0000008a
[build@build ~/voreutils]$ ./out/cmd/uname -v | hexdump -C
00000000  46 72 65 65 42 53 44 20  31 33 2e 30 2d 52 45 4c  |FreeBSD 13.0-REL|
00000010  45 41 53 45 2d 70 31 20  23 30 3a 20 57 65 64 20  |EASE-p1 #0: Wed |
00000020  4d 61 79 20 32 36 20 32  32 3a 31 35 3a 30 39 20  |May 26 22:15:09 |
00000030  55 54 43 20 32 30 32 31  20 20 20 20 20 72 6f 6f  |UTC 2021     roo|
00000040  74 40 61 6d 64 36 34 2d  62 75 69 6c 64 65 72 2e  |t@amd64-builder.|
00000050  64 61 65 6d 6f 6e 6f 6c  6f 67 79 2e 6e 65 74 3a  |daemonology.net:|
00000060  2f 75 73 72 2f 6f 62 6a  2f 75 73 72 2f 73 72 63  |/usr/obj/usr/src|
00000070  2f 61 6d 64 36 34 2e 61  6d 64 36 34 2f 73 79 73  |/amd64.amd64/sys|
00000080  2f 47 45 4e 45 52 49 43  0a                       |/GENERIC.|
00000089

This is backed by uname(1) source:
NATIVE_SYSCTL2_GET(version, CTL_KERN, KERN_VERSION) {
	size_t n;
	char *p;

	p = NATIVE_BUFFER;
	n = NATIVE_LENGTH;
	for (; n--; ++p)
		if (*p == '\n' || *p == '\t')
			*p = ' ';
} NATIVE_SET;

And uname(3) source:
	if ((p = getenv("UNAME_v")))
		strlcpy(q, p, namesize);
	else {

		/*
		 * The version may have newlines in it, turn them into
		 * spaces.
		 */
		mib[1] = KERN_VERSION;
		len = namesize;
		oerrno = errno;
		if (sysctl(mib, 2, q, &len, NULL, 0) == -1) {
			if (errno == ENOMEM)
				errno = oerrno;
			else
				rval = -1;
		}
		q[namesize - 1] = '\0';
		for (p = q; len--; ++p) {
			if (*p == '\n' || *p == '\t') {
				if (len > 1)
					*p = ' ';
				else
					*p = '\0';
			}
		}
	}
	q += namesize;

As you can see, the code is almost identical, except for the part where uname(3) strips the final newline instead of making it a space. This breaks POSIX compatibility, which states (quoth IEEE Std 1003.1-2017):

    By default, the uname utility shall write the operating system name to standard output. When options are specified, symbols representing one or more system characteristics shall be written to the standard output. The format and contents of the symbols are implementation-defined. On systems conforming to the System Interfaces volume of POSIX.1-2017, the symbols written shall be those supported by the uname() function as defined in the System Interfaces volume of POSIX.1-2017.

and:

If the -a option is specified, the output shall be a single line of the following form:

"%s %s %s %s %s\n", <sysname>, <nodename>, <release>, <version>, <machine>

Additional implementation-defined symbols may be written; all such symbols shall be written at the end of the line of output before the <newline>.

If options are specified to select different combinations of the symbols, only those symbols shall be written, in the order shown above for the -a option. If a symbol is not selected for writing, its corresponding trailing <blank> characters also shall not be written.