Merge pull request #3802 from poettering/id128-fixes

Id128 fixes and more
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2016-07-25 15:08:29 -04:00 committed by GitHub
commit f86f6f829c
5 changed files with 119 additions and 16 deletions

View file

@ -406,3 +406,26 @@
shorts as their name would suggest, but on uint32_t and uint16_t. Also,
"network byte order" is just a weird name for "big endian", hence we might
want to call it "big endian" right-away.
- You might wonder what kind of common code belongs in src/shared/ and what
belongs in src/util/. The split is like this: anything that uses public APIs
we expose (i.e. any of the sd-bus, sd-login, sd-id128, ... APIs) must be
located in src/shared/. All stuff that only uses external libraries from
other projects (such as glibc's APIs), or APIs from src/basic/ itself should
be placed in src/basic/. Conversely, src/libsystemd/ may only use symbols
from src/basic, but not from src/shared/. To summarize:
src/basic/ → may be used by all code in the tree
→ may not use any code outside of src/basic/
src/shared/ → may be used by all code in the tree, except for code in src/basic/
→ may not use any code outside of src/basic/, src/shared/, src/libsystemd/
src/libsystemd/ → may be used by all code in the tree, except for code in src/basic/
→ may not use any code outside of src/basic/, src/shared/, src/libsystemd/
- Our focus is on the GNU libc (glibc), not any other libcs. If other libcs are
incompatible with glibc it's on them. However, if there are equivalent POSIX
and Linux/GNU-specific APIs, we generally prefer the POSIX APIs. If there
aren't, we are happy to use GNU or Linux APIs, and expect non-GNU
implementations of libc to catch up with glibc.

View file

@ -80,10 +80,10 @@
<listitem><para>Additionally, <command>systemd-resolved</command> provides a local DNS stub listener on IP
address 127.0.0.53 on the local loopback interface. Programs issuing DNS requests directly, bypassing any local
API may be directed to this stub, in order to connect them <command>systemd-resolved</command>. Note however that
it is strongly recommended that local programs use the glibc NSS or bus APIs instead (as described above), as
various network resolution concepts (such as link-local addressing, or LLMNR Unicode domains) cannot be mapped to
the unicast DNS protocol.</para></listitem>
API may be directed to this stub, in order to connect them to <command>systemd-resolved</command>. Note however
that it is strongly recommended that local programs use the glibc NSS or bus APIs instead (as described above),
as various network resolution concepts (such as link-local addressing, or LLMNR Unicode domains) cannot be mapped
to the unicast DNS protocol.</para></listitem>
</itemizedlist>
<para>The DNS servers contacted are determined from the global settings in

View file

@ -1259,7 +1259,8 @@ int open_tmpfile_unlinkable(const char *directory, int flags) {
char *p;
int fd;
assert(directory);
if (!directory)
directory = "/tmp";
/* Returns an unlinked temporary file that cannot be linked into the file system anymore */

View file

@ -100,33 +100,45 @@ int id128_read_fd(int fd, Id128Format f, sd_id128_t *ret) {
assert(f < _ID128_FORMAT_MAX);
/* Reads an 128bit ID from a file, which may either be in plain format (32 hex digits), or in UUID format, both
* followed by a newline and nothing else. */
* optionally followed by a newline and nothing else. ID files should really be newline terminated, but if they
* aren't that's OK too, following the rule of "Be conservative in what you send, be liberal in what you
* accept". */
l = loop_read(fd, buffer, sizeof(buffer), false); /* we expect a short read of either 33 or 37 chars */
l = loop_read(fd, buffer, sizeof(buffer), false); /* we expect a short read of either 32/33 or 36/37 chars */
if (l < 0)
return (int) l;
if (l == 0) /* empty? */
return -ENOMEDIUM;
if (l == 33) {
if (f == ID128_UUID)
return -EINVAL;
switch (l) {
case 33: /* plain UUID with trailing newline */
if (buffer[32] != '\n')
return -EINVAL;
buffer[32] = 0;
} else if (l == 37) {
if (f == ID128_PLAIN)
/* fall through */
case 32: /* plain UUID without trailing newline */
if (f == ID128_UUID)
return -EINVAL;
buffer[32] = 0;
break;
case 37: /* RFC UUID with trailing newline */
if (buffer[36] != '\n')
return -EINVAL;
/* fall through */
case 36: /* RFC UUID without trailing newline */
if (f == ID128_PLAIN)
return -EINVAL;
buffer[36] = 0;
} else
break;
default:
return -EINVAL;
}
return sd_id128_from_string(buffer, ret);
}

View file

@ -23,10 +23,12 @@
#include "sd-id128.h"
#include "alloc-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "id128-util.h"
#include "macro.h"
#include "string-util.h"
#include "util.h"
#include "id128-util.h"
#define ID128_WALDI SD_ID128_MAKE(01, 02, 03, 04, 05, 06, 07, 08, 09, 0a, 0b, 0c, 0d, 0e, 0f, 10)
#define STR_WALDI "0102030405060708090a0b0c0d0e0f10"
@ -36,6 +38,7 @@ int main(int argc, char *argv[]) {
sd_id128_t id, id2;
char t[33], q[37];
_cleanup_free_ char *b = NULL;
_cleanup_close_ int fd = -1;
assert_se(sd_id128_randomize(&id) == 0);
printf("random: %s\n", sd_id128_to_string(id, t));
@ -86,5 +89,69 @@ int main(int argc, char *argv[]) {
assert_se(!id128_is_valid("01020304-0506-0708-090a0b0c0d0e0f10"));
assert_se(!id128_is_valid("010203040506-0708-090a-0b0c0d0e0f10"));
fd = open_tmpfile_unlinkable(NULL, O_RDWR|O_CLOEXEC);
assert_se(fd >= 0);
/* First, write as UUID */
assert_se(sd_id128_randomize(&id) >= 0);
assert_se(id128_write_fd(fd, ID128_UUID, id, false) >= 0);
assert_se(lseek(fd, 0, SEEK_SET) == 0);
assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) == -EINVAL);
assert_se(lseek(fd, 0, SEEK_SET) == 0);
assert_se(id128_read_fd(fd, ID128_UUID, &id2) >= 0);
assert_se(sd_id128_equal(id, id2));
assert_se(lseek(fd, 0, SEEK_SET) == 0);
assert_se(id128_read_fd(fd, ID128_ANY, &id2) >= 0);
assert_se(sd_id128_equal(id, id2));
/* Second, write as plain */
assert_se(lseek(fd, 0, SEEK_SET) == 0);
assert_se(ftruncate(fd, 0) >= 0);
assert_se(sd_id128_randomize(&id) >= 0);
assert_se(id128_write_fd(fd, ID128_PLAIN, id, false) >= 0);
assert_se(lseek(fd, 0, SEEK_SET) == 0);
assert_se(id128_read_fd(fd, ID128_UUID, &id2) == -EINVAL);
assert_se(lseek(fd, 0, SEEK_SET) == 0);
assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) >= 0);
assert_se(sd_id128_equal(id, id2));
assert_se(lseek(fd, 0, SEEK_SET) == 0);
assert_se(id128_read_fd(fd, ID128_ANY, &id2) >= 0);
assert_se(sd_id128_equal(id, id2));
/* Third, write plain without trailing newline */
assert_se(lseek(fd, 0, SEEK_SET) == 0);
assert_se(ftruncate(fd, 0) >= 0);
assert_se(sd_id128_randomize(&id) >= 0);
assert_se(write(fd, sd_id128_to_string(id, t), 32) == 32);
assert_se(lseek(fd, 0, SEEK_SET) == 0);
assert_se(id128_read_fd(fd, ID128_UUID, &id2) == -EINVAL);
assert_se(lseek(fd, 0, SEEK_SET) == 0);
assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) >= 0);
assert_se(sd_id128_equal(id, id2));
/* Third, write UUID without trailing newline */
assert_se(lseek(fd, 0, SEEK_SET) == 0);
assert_se(ftruncate(fd, 0) >= 0);
assert_se(sd_id128_randomize(&id) >= 0);
assert_se(write(fd, id128_to_uuid_string(id, t), 36) == 36);
assert_se(lseek(fd, 0, SEEK_SET) == 0);
assert_se(id128_read_fd(fd, ID128_PLAIN, &id2) == -EINVAL);
assert_se(lseek(fd, 0, SEEK_SET) == 0);
assert_se(id128_read_fd(fd, ID128_UUID, &id2) >= 0);
assert_se(sd_id128_equal(id, id2));
return 0;
}