Line data Source code
1 : // Copyright (c) 2011-2022 Made to Order Software Corp. All Rights Reserved
2 : //
3 : // https://snapwebsites.org/project/libaddr
4 : // contact@m2osw.com
5 : //
6 : // Permission is hereby granted, free of charge, to any
7 : // person obtaining a copy of this software and
8 : // associated documentation files (the "Software"), to
9 : // deal in the Software without restriction, including
10 : // without limitation the rights to use, copy, modify,
11 : // merge, publish, distribute, sublicense, and/or sell
12 : // copies of the Software, and to permit persons to whom
13 : // the Software is furnished to do so, subject to the
14 : // following conditions:
15 : //
16 : // The above copyright notice and this permission notice
17 : // shall be included in all copies or substantial
18 : // portions of the Software.
19 : //
20 : // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
21 : // ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
22 : // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 : // FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
24 : // EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 : // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 : // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 : // ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 : // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 : // SOFTWARE.
30 :
31 :
32 : /** \file
33 : * \brief Test the Unix address.
34 : *
35 : * These tests verify that the Unix address functions as expected.
36 : */
37 :
38 : // addr lib
39 : //
40 : #include <libaddr/unix.h>
41 :
42 :
43 : // self
44 : //
45 : #include "catch_main.h"
46 :
47 :
48 : // libutf8 lib
49 : //
50 : #include <libutf8/libutf8.h>
51 : #include <libutf8/exception.h>
52 :
53 :
54 : // snapdev lib
55 : //
56 : #include <snapdev/raii_generic_deleter.h>
57 :
58 :
59 : // C lib
60 : //
61 : #include <sys/stat.h>
62 :
63 :
64 : // last include
65 : //
66 : #include <snapdev/poison.h>
67 :
68 :
69 :
70 :
71 :
72 :
73 :
74 7 : CATCH_TEST_CASE("unix::unnamed", "[unix]")
75 : {
76 10 : CATCH_START_SECTION("unix() defaults (a.k.a. unnamed address)")
77 : {
78 1 : addr::unix u;
79 :
80 1 : CATCH_REQUIRE_FALSE(u.is_file());
81 1 : CATCH_REQUIRE_FALSE(u.is_abstract());
82 1 : CATCH_REQUIRE(u.is_unnamed());
83 1 : CATCH_REQUIRE(u.to_string() == std::string());
84 1 : CATCH_REQUIRE(u.to_uri() == "unix:");
85 :
86 1 : sockaddr_un un;
87 1 : u.get_un(un);
88 1 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
89 109 : for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
90 : {
91 108 : CATCH_CHECK(un.sun_path[idx] == 0);
92 : }
93 : }
94 : CATCH_END_SECTION()
95 :
96 10 : CATCH_START_SECTION("unix() with an unnamed address")
97 : {
98 1 : sockaddr_un init = addr::init_un();
99 1 : CATCH_REQUIRE(init.sun_family == AF_UNIX);
100 109 : for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
101 : {
102 108 : CATCH_CHECK(init.sun_path[idx] == 0);
103 : }
104 :
105 1 : addr::unix u(init);
106 :
107 1 : CATCH_REQUIRE_FALSE(u.is_file());
108 1 : CATCH_REQUIRE_FALSE(u.is_abstract());
109 1 : CATCH_REQUIRE(u.is_unnamed());
110 1 : CATCH_REQUIRE(u.to_string() == std::string());
111 1 : CATCH_REQUIRE(u.to_uri() == "unix:");
112 :
113 1 : sockaddr_un un;
114 1 : u.get_un(un);
115 1 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
116 109 : for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
117 : {
118 108 : CATCH_CHECK(un.sun_path[idx] == 0);
119 : }
120 : }
121 : CATCH_END_SECTION()
122 :
123 10 : CATCH_START_SECTION("unix() with an unnamed string")
124 : {
125 2 : std::string no_name;
126 1 : addr::unix u(no_name);
127 :
128 1 : CATCH_REQUIRE_FALSE(u.is_file());
129 1 : CATCH_REQUIRE_FALSE(u.is_abstract());
130 1 : CATCH_REQUIRE(u.is_unnamed());
131 1 : CATCH_REQUIRE(u.to_string() == std::string());
132 1 : CATCH_REQUIRE(u.to_uri() == "unix:");
133 :
134 1 : sockaddr_un un;
135 1 : u.get_un(un);
136 1 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
137 109 : for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
138 : {
139 108 : CATCH_CHECK(un.sun_path[idx] == 0);
140 : }
141 : }
142 : CATCH_END_SECTION()
143 :
144 10 : CATCH_START_SECTION("unix() with a forced unnamed URI")
145 : {
146 1 : addr::unix u;
147 :
148 1 : u.set_uri("unix:?unnamed");
149 :
150 1 : CATCH_REQUIRE_FALSE(u.is_file());
151 1 : CATCH_REQUIRE_FALSE(u.is_abstract());
152 1 : CATCH_REQUIRE(u.is_unnamed());
153 1 : CATCH_REQUIRE(u.to_string() == std::string());
154 1 : CATCH_REQUIRE(u.to_uri() == "unix:");
155 1 : CATCH_REQUIRE(u.unlink() == 0);
156 :
157 1 : sockaddr_un un;
158 1 : u.get_un(un);
159 1 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
160 109 : for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
161 : {
162 108 : CATCH_CHECK(un.sun_path[idx] == 0);
163 : }
164 : }
165 : CATCH_END_SECTION()
166 :
167 10 : CATCH_START_SECTION("unix() with an unnamed which we re-collect from socket")
168 : {
169 1 : sockaddr_un un;
170 :
171 1 : addr::unix u;
172 :
173 1 : CATCH_REQUIRE_FALSE(u.is_file());
174 1 : CATCH_REQUIRE_FALSE(u.is_abstract());
175 1 : CATCH_REQUIRE(u.is_unnamed());
176 1 : CATCH_REQUIRE(u.to_string() == std::string());
177 1 : CATCH_REQUIRE(u.to_uri() == "unix:");
178 :
179 1 : u.get_un(un);
180 1 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
181 109 : for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
182 : {
183 108 : CATCH_CHECK(un.sun_path[idx] == 0);
184 : }
185 :
186 2 : snapdev::raii_fd_t s(socket(AF_UNIX, SOCK_STREAM, 0));
187 1 : CATCH_REQUIRE(s != nullptr);
188 :
189 : // unnamed sockets are unbound...
190 :
191 1 : addr::unix retrieve;
192 1 : retrieve.set_from_socket(s.get());
193 1 : CATCH_REQUIRE(retrieve == u);
194 : }
195 : CATCH_END_SECTION()
196 5 : }
197 :
198 :
199 9 : CATCH_TEST_CASE("unix::file", "[unix]")
200 : {
201 14 : CATCH_START_SECTION("unix() with a relative file name")
202 : {
203 11 : for(int count(0); count < 10; ++count)
204 : {
205 20 : std::string name("test");
206 10 : int const max(rand() % 5 + 3);
207 51 : for(int id(0); id < max; ++id)
208 : {
209 41 : name += '0' + rand() % 10;
210 : }
211 :
212 : // verify the init_un() as we're at it
213 : //
214 10 : sockaddr_un init = addr::init_un();
215 10 : CATCH_REQUIRE(init.sun_family == AF_UNIX);
216 1090 : for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
217 : {
218 1080 : CATCH_CHECK(init.sun_path[idx] == 0);
219 : }
220 10 : strncpy(init.sun_path, name.c_str(), sizeof(init.sun_path) - 1);
221 :
222 10 : addr::unix u(init);
223 :
224 10 : CATCH_REQUIRE(u.is_file());
225 10 : CATCH_REQUIRE_FALSE(u.is_abstract());
226 10 : CATCH_REQUIRE_FALSE(u.is_unnamed());
227 10 : CATCH_REQUIRE(u.to_string() == name);
228 10 : CATCH_REQUIRE(u.to_uri() == "unix:" + name);
229 :
230 10 : sockaddr_un un;
231 10 : u.get_un(un);
232 10 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
233 10 : CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
234 1009 : for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
235 : {
236 999 : CATCH_CHECK(un.sun_path[idx] == 0);
237 : }
238 : }
239 : }
240 : CATCH_END_SECTION()
241 :
242 14 : CATCH_START_SECTION("unix() with a relative file name; string constructor")
243 : {
244 11 : for(int count(0); count < 10; ++count)
245 : {
246 20 : std::string name("test");
247 10 : int const max(rand() % 5 + 3);
248 56 : for(int id(0); id < max; ++id)
249 : {
250 46 : name += '0' + rand() % 10;
251 : }
252 :
253 10 : addr::unix u(name);
254 :
255 10 : CATCH_REQUIRE(u.is_file());
256 10 : CATCH_REQUIRE_FALSE(u.is_abstract());
257 10 : CATCH_REQUIRE_FALSE(u.is_unnamed());
258 10 : CATCH_REQUIRE(u.to_string() == name);
259 10 : CATCH_REQUIRE(u.to_uri() == "unix:" + name);
260 :
261 10 : sockaddr_un un;
262 10 : u.get_un(un);
263 10 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
264 10 : CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
265 1004 : for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
266 : {
267 994 : CATCH_CHECK(un.sun_path[idx] == 0);
268 : }
269 : }
270 : }
271 : CATCH_END_SECTION()
272 :
273 14 : CATCH_START_SECTION("unix() with a relative file name using set_file()")
274 : {
275 1 : addr::unix u;
276 :
277 11 : for(int count(0); count < 10; ++count)
278 : {
279 20 : std::string name("test");
280 10 : int const max(rand() % 25 + 3); // vary more to correctly verify that we clear the end of the buffer
281 202 : for(int id(0); id < max; ++id)
282 : {
283 192 : name += '0' + rand() % 10;
284 : }
285 :
286 : // verify the init_un() as we're at it
287 : //
288 10 : sockaddr_un init = addr::init_un();
289 10 : CATCH_REQUIRE(init.sun_family == AF_UNIX);
290 1090 : for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
291 : {
292 1080 : CATCH_CHECK(init.sun_path[idx] == 0);
293 : }
294 10 : strncpy(init.sun_path, name.c_str(), sizeof(init.sun_path) - 1);
295 :
296 10 : u.set_file(name);
297 :
298 10 : CATCH_REQUIRE(u.is_file());
299 10 : CATCH_REQUIRE_FALSE(u.is_abstract());
300 10 : CATCH_REQUIRE_FALSE(u.is_unnamed());
301 10 : CATCH_REQUIRE(u.to_string() == name);
302 10 : CATCH_REQUIRE(u.to_uri() == "unix:" + name);
303 :
304 10 : sockaddr_un un;
305 10 : u.get_un(un);
306 10 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
307 10 : CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
308 858 : for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
309 : {
310 848 : CATCH_CHECK(un.sun_path[idx] == 0);
311 : }
312 : }
313 : }
314 : CATCH_END_SECTION()
315 :
316 14 : CATCH_START_SECTION("unix() with a full file name")
317 : {
318 11 : for(int count(0); count < 10; ++count)
319 : {
320 20 : std::string name("/run/snapwebsites/sockets/test");
321 10 : int const max(rand() % 25 + 3);
322 178 : for(int id(0); id < max; ++id)
323 : {
324 168 : name += '0' + rand() % 10;
325 : }
326 :
327 : // verify the init_un() as we're at it
328 : //
329 10 : sockaddr_un init = addr::init_un();
330 10 : CATCH_REQUIRE(init.sun_family == AF_UNIX);
331 1090 : for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
332 : {
333 1080 : CATCH_CHECK(init.sun_path[idx] == 0);
334 : }
335 10 : strncpy(init.sun_path, name.c_str(), sizeof(init.sun_path) - 1);
336 :
337 10 : addr::unix u(init);
338 :
339 10 : CATCH_REQUIRE(u.is_file());
340 10 : CATCH_REQUIRE_FALSE(u.is_abstract());
341 10 : CATCH_REQUIRE_FALSE(u.is_unnamed());
342 10 : CATCH_REQUIRE(u.to_string() == name);
343 10 : CATCH_REQUIRE(u.to_uri() == "unix://" + name);
344 :
345 10 : sockaddr_un un;
346 10 : u.get_un(un);
347 10 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
348 10 : CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
349 622 : for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
350 : {
351 612 : CATCH_CHECK(un.sun_path[idx] == 0);
352 : }
353 : }
354 : }
355 : CATCH_END_SECTION()
356 :
357 14 : CATCH_START_SECTION("unix() with a long file name")
358 : {
359 1 : sockaddr_un un;
360 107 : for(int count(1); count < static_cast<int>(sizeof(un.sun_path) - 1); ++count)
361 : {
362 212 : std::string name;
363 5777 : for(int id(0); id < count; ++id)
364 : {
365 5671 : name += '0' + rand() % 10;
366 : }
367 :
368 106 : addr::unix u(name);
369 :
370 106 : CATCH_REQUIRE(u.is_file());
371 106 : CATCH_REQUIRE_FALSE(u.is_abstract());
372 106 : CATCH_REQUIRE_FALSE(u.is_unnamed());
373 106 : CATCH_REQUIRE(u.to_string() == name);
374 106 : CATCH_REQUIRE(u.to_uri() == "unix:" + name);
375 :
376 106 : u.get_un(un);
377 106 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
378 106 : CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
379 5883 : for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
380 : {
381 5777 : CATCH_CHECK(un.sun_path[idx] == 0);
382 : }
383 : }
384 : }
385 : CATCH_END_SECTION()
386 :
387 14 : CATCH_START_SECTION("unix() verify that file gets unlink()'ed")
388 : {
389 11 : for(int count(0); count < 10; ++count)
390 : {
391 20 : std::string name("test");
392 10 : int const max(rand() % 5 + 3);
393 57 : for(int id(0); id < max; ++id)
394 : {
395 47 : name += '0' + rand() % 10;
396 : }
397 :
398 : // verify the init_un() as we're at it
399 : //
400 10 : addr::unix u(name);
401 :
402 20 : std::string cmd("touch ");
403 10 : cmd += name;
404 10 : CATCH_REQUIRE(system(cmd.c_str()) == 0);
405 :
406 10 : struct stat s;
407 10 : CATCH_REQUIRE(stat(name.c_str(), &s) == 0);
408 :
409 10 : CATCH_REQUIRE(u.unlink() == 0);
410 :
411 10 : CATCH_REQUIRE(stat(name.c_str(), &s) != 0);
412 : }
413 : }
414 : CATCH_END_SECTION()
415 :
416 14 : CATCH_START_SECTION("unix() with a file name which we re-collect from socket")
417 : {
418 1 : sockaddr_un un;
419 :
420 2 : std::string name("socket-test");
421 1 : int count(rand() % 5 + 3);
422 4 : for(int id(0); id < count; ++id)
423 : {
424 3 : name += '0' + rand() % 10;
425 : }
426 1 : unlink(name.c_str());
427 :
428 1 : addr::unix u(name);
429 :
430 1 : CATCH_REQUIRE(u.is_file());
431 1 : CATCH_REQUIRE_FALSE(u.is_abstract());
432 1 : CATCH_REQUIRE_FALSE(u.is_unnamed());
433 1 : CATCH_REQUIRE(u.to_string() == name);
434 1 : CATCH_REQUIRE(u.to_uri() == "unix:" + name);
435 :
436 1 : u.get_un(un);
437 1 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
438 1 : CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
439 95 : for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
440 : {
441 94 : CATCH_CHECK(un.sun_path[idx] == 0);
442 : }
443 :
444 2 : snapdev::raii_fd_t s(socket(AF_UNIX, SOCK_STREAM, 0));
445 1 : CATCH_REQUIRE(s != nullptr);
446 1 : sockaddr_un address;
447 1 : u.get_un(address);
448 1 : CATCH_REQUIRE(bind(s.get(), reinterpret_cast<sockaddr *>(&address), sizeof(address)) == 0);
449 :
450 1 : addr::unix retrieve;
451 1 : retrieve.set_from_socket(s.get());
452 1 : CATCH_REQUIRE(retrieve == u);
453 : }
454 : CATCH_END_SECTION()
455 7 : }
456 :
457 :
458 8 : CATCH_TEST_CASE("unix::abstract", "[unix]")
459 : {
460 12 : CATCH_START_SECTION("unix() with a relative abstract name")
461 : {
462 11 : for(int count(0); count < 10; ++count)
463 : {
464 20 : std::string name("abstract/test");
465 10 : int const max(rand() % 25 + 3);
466 148 : for(int id(0); id < max; ++id)
467 : {
468 138 : name += '0' + rand() % 10;
469 : }
470 :
471 : // verify the init_un() as we're at it
472 : //
473 10 : sockaddr_un init = addr::init_un();
474 10 : CATCH_REQUIRE(init.sun_family == AF_UNIX);
475 1090 : for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
476 : {
477 1080 : CATCH_CHECK(init.sun_path[idx] == 0);
478 : }
479 10 : strncpy(init.sun_path + 1, name.c_str(), sizeof(init.sun_path) - 2);
480 :
481 10 : addr::unix u(init);
482 :
483 10 : CATCH_REQUIRE_FALSE(u.is_file());
484 10 : CATCH_REQUIRE(u.is_abstract());
485 10 : CATCH_REQUIRE_FALSE(u.is_unnamed());
486 10 : CATCH_REQUIRE(u.to_string() == name);
487 10 : CATCH_REQUIRE(u.to_uri() == "unix:" + name + "?abstract");
488 10 : CATCH_REQUIRE(u.unlink() == 0);
489 :
490 10 : sockaddr_un un;
491 10 : u.get_un(un);
492 10 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
493 10 : CATCH_REQUIRE(un.sun_path[0] == '\0');
494 10 : CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
495 812 : for(std::size_t idx(name.length() + 1); idx < sizeof(un.sun_path); ++idx)
496 : {
497 802 : CATCH_CHECK(un.sun_path[idx] == 0);
498 : }
499 : }
500 : }
501 : CATCH_END_SECTION()
502 :
503 12 : CATCH_START_SECTION("unix() with a relative abstract name with string constructor")
504 : {
505 11 : for(int count(0); count < 10; ++count)
506 : {
507 20 : std::string name("abstract/test");
508 10 : int const max(rand() % 25 + 3);
509 165 : for(int id(0); id < max; ++id)
510 : {
511 155 : name += '0' + rand() % 10;
512 : }
513 :
514 10 : addr::unix u(name, true);
515 :
516 10 : CATCH_REQUIRE_FALSE(u.is_file());
517 10 : CATCH_REQUIRE(u.is_abstract());
518 10 : CATCH_REQUIRE_FALSE(u.is_unnamed());
519 10 : CATCH_REQUIRE(u.to_string() == name);
520 10 : CATCH_REQUIRE(u.to_uri() == "unix:" + name + "?abstract");
521 :
522 10 : sockaddr_un un;
523 10 : u.get_un(un);
524 10 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
525 10 : CATCH_REQUIRE(un.sun_path[0] == '\0');
526 10 : CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
527 795 : for(std::size_t idx(name.length() + 1); idx < sizeof(un.sun_path); ++idx)
528 : {
529 785 : CATCH_CHECK(un.sun_path[idx] == 0);
530 : }
531 : }
532 : }
533 : CATCH_END_SECTION()
534 :
535 12 : CATCH_START_SECTION("unix() with an abstract name using set_abstract()")
536 : {
537 1 : addr::unix u;
538 :
539 11 : for(int count(0); count < 10; ++count)
540 : {
541 20 : std::string name("test");
542 10 : int const max(rand() % 25 + 3); // vary more to correctly verify that we clear the end of the buffer
543 127 : for(int id(0); id < max; ++id)
544 : {
545 117 : name += '0' + rand() % 10;
546 : }
547 :
548 : // verify the init_un() as we're at it
549 : //
550 10 : sockaddr_un init = addr::init_un();
551 10 : CATCH_REQUIRE(init.sun_family == AF_UNIX);
552 1090 : for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
553 : {
554 1080 : CATCH_CHECK(init.sun_path[idx] == 0);
555 : }
556 10 : strncpy(init.sun_path, name.c_str(), sizeof(init.sun_path) - 1);
557 :
558 10 : u.set_abstract(name);
559 :
560 10 : CATCH_REQUIRE_FALSE(u.is_file());
561 10 : CATCH_REQUIRE(u.is_abstract());
562 10 : CATCH_REQUIRE_FALSE(u.is_unnamed());
563 10 : CATCH_REQUIRE(u.to_string() == name);
564 10 : CATCH_REQUIRE(u.to_uri() == "unix:" + name + "?abstract");
565 :
566 10 : sockaddr_un un;
567 10 : u.get_un(un);
568 10 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
569 10 : CATCH_REQUIRE(un.sun_path[0] == '\0');
570 10 : CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
571 923 : for(std::size_t idx(name.length() +1); idx < sizeof(un.sun_path); ++idx)
572 : {
573 913 : CATCH_CHECK(un.sun_path[idx] == 0);
574 : }
575 : }
576 : }
577 : CATCH_END_SECTION()
578 :
579 12 : CATCH_START_SECTION("unix() with a full abstract name")
580 : {
581 11 : for(int count(0); count < 10; ++count)
582 : {
583 20 : std::string name("/net/snapwebsites/settings/test");
584 10 : int const max(rand() % 25 + 3);
585 188 : for(int id(0); id < max; ++id)
586 : {
587 178 : name += '0' + rand() % 10;
588 : }
589 :
590 : // verify the init_un() as we're at it
591 : //
592 10 : sockaddr_un init = addr::init_un();
593 10 : CATCH_REQUIRE(init.sun_family == AF_UNIX);
594 1090 : for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
595 : {
596 1080 : CATCH_CHECK(init.sun_path[idx] == 0);
597 : }
598 10 : strncpy(init.sun_path + 1, name.c_str(), sizeof(init.sun_path) - 2);
599 :
600 10 : addr::unix u(init);
601 :
602 10 : CATCH_REQUIRE_FALSE(u.is_file());
603 10 : CATCH_REQUIRE(u.is_abstract());
604 10 : CATCH_REQUIRE_FALSE(u.is_unnamed());
605 10 : CATCH_REQUIRE(u.to_string() == name);
606 10 : CATCH_REQUIRE(u.to_uri() == "unix://" + name + "?abstract");
607 :
608 10 : sockaddr_un un;
609 10 : u.get_un(un);
610 10 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
611 10 : CATCH_REQUIRE(un.sun_path[0] == '\0');
612 10 : CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
613 592 : for(std::size_t idx(name.length() + 1); idx < sizeof(un.sun_path); ++idx)
614 : {
615 582 : CATCH_CHECK(un.sun_path[idx] == 0);
616 : }
617 : }
618 : }
619 : CATCH_END_SECTION()
620 :
621 12 : CATCH_START_SECTION("unix() with a long abstract name")
622 : {
623 1 : sockaddr_un un;
624 106 : for(int count(1); count < static_cast<int>(sizeof(un.sun_path) - 2); ++count)
625 : {
626 210 : std::string name;
627 5670 : for(int id(0); id < count; ++id)
628 : {
629 5565 : name += '0' + rand() % 10;
630 : }
631 :
632 105 : addr::unix u(name, true);
633 :
634 105 : CATCH_REQUIRE_FALSE(u.is_file());
635 105 : CATCH_REQUIRE(u.is_abstract());
636 105 : CATCH_REQUIRE_FALSE(u.is_unnamed());
637 105 : CATCH_REQUIRE(u.to_string() == name);
638 105 : CATCH_REQUIRE(u.to_uri() == "unix:" + name + "?abstract");
639 :
640 105 : u.get_un(un);
641 105 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
642 105 : CATCH_REQUIRE(un.sun_path[0] == '\0');
643 105 : CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
644 5775 : for(std::size_t idx(name.length() + 1); idx < sizeof(un.sun_path); ++idx)
645 : {
646 5670 : CATCH_CHECK(un.sun_path[idx] == 0);
647 : }
648 : }
649 : }
650 : CATCH_END_SECTION()
651 :
652 12 : CATCH_START_SECTION("unix() with an abstract name which we re-collect from socket")
653 : {
654 1 : sockaddr_un un;
655 :
656 2 : std::string name("/net/snapwebsites/test");
657 1 : int count(rand() % 5 + 3);
658 7 : for(int id(0); id < count; ++id)
659 : {
660 6 : name += '0' + rand() % 10;
661 : }
662 :
663 1 : addr::unix u(name, true);
664 :
665 1 : CATCH_REQUIRE_FALSE(u.is_file());
666 1 : CATCH_REQUIRE(u.is_abstract());
667 1 : CATCH_REQUIRE_FALSE(u.is_unnamed());
668 1 : CATCH_REQUIRE(u.to_string() == name);
669 1 : CATCH_REQUIRE(u.to_uri() == "unix://" + name + "?abstract");
670 :
671 1 : u.get_un(un);
672 1 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
673 1 : CATCH_REQUIRE(un.sun_path[0] == '\0');
674 1 : CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
675 80 : for(std::size_t idx(name.length() + 1); idx < sizeof(un.sun_path); ++idx)
676 : {
677 79 : CATCH_CHECK(un.sun_path[idx] == 0);
678 : }
679 :
680 2 : snapdev::raii_fd_t s(socket(AF_UNIX, SOCK_STREAM, 0));
681 1 : CATCH_REQUIRE(s != nullptr);
682 1 : sockaddr_un address;
683 1 : u.get_un(address);
684 1 : socklen_t const len(sizeof(address.sun_family) + 1 + strlen(address.sun_path + 1));
685 1 : CATCH_REQUIRE(bind(s.get(), reinterpret_cast<sockaddr *>(&address), len) == 0);
686 :
687 1 : addr::unix retrieve;
688 1 : retrieve.set_from_socket(s.get());
689 1 : CATCH_REQUIRE(retrieve == u);
690 : }
691 : CATCH_END_SECTION()
692 6 : }
693 :
694 :
695 4 : CATCH_TEST_CASE("unix::compare", "[unix]")
696 : {
697 4 : CATCH_START_SECTION("two unix() to compare with ==, !=, <, <=, >, >=")
698 : {
699 1 : addr::unix a;
700 1 : addr::unix b;
701 :
702 1 : CATCH_REQUIRE(a == b);
703 1 : CATCH_REQUIRE_FALSE(a != b);
704 1 : CATCH_REQUIRE_FALSE(a < b);
705 1 : CATCH_REQUIRE(a <= b);
706 1 : CATCH_REQUIRE_FALSE(a > b);
707 1 : CATCH_REQUIRE(a >= b);
708 :
709 1 : a.set_uri("unix:flowers");
710 1 : b.set_uri("unix:oranges");
711 :
712 1 : CATCH_REQUIRE_FALSE(a == b);
713 1 : CATCH_REQUIRE(a != b);
714 1 : CATCH_REQUIRE(a < b);
715 1 : CATCH_REQUIRE(a <= b);
716 1 : CATCH_REQUIRE_FALSE(a > b);
717 1 : CATCH_REQUIRE_FALSE(a >= b);
718 :
719 1 : std::swap(a, b);
720 :
721 1 : CATCH_REQUIRE_FALSE(a == b);
722 1 : CATCH_REQUIRE(a != b);
723 1 : CATCH_REQUIRE_FALSE(a < b);
724 1 : CATCH_REQUIRE_FALSE(a <= b);
725 1 : CATCH_REQUIRE(a > b);
726 1 : CATCH_REQUIRE(a >= b);
727 : }
728 : CATCH_END_SECTION()
729 :
730 4 : CATCH_START_SECTION("two sockaddr_un to compare with ==, !=, <, <=, >, >=")
731 : {
732 1 : sockaddr_un a = addr::init_un();
733 1 : sockaddr_un b = addr::init_un();
734 :
735 1 : CATCH_REQUIRE(a == b);
736 1 : CATCH_REQUIRE_FALSE(a != b);
737 1 : CATCH_REQUIRE_FALSE(a < b);
738 1 : CATCH_REQUIRE(a <= b);
739 1 : CATCH_REQUIRE_FALSE(a > b);
740 1 : CATCH_REQUIRE(a >= b);
741 :
742 1 : strncpy(a.sun_path, "unix:flowers", sizeof(a.sun_path) - 1);
743 1 : strncpy(b.sun_path, "unix:oranges", sizeof(a.sun_path) - 1);
744 :
745 1 : CATCH_REQUIRE_FALSE(a == b);
746 1 : CATCH_REQUIRE(a != b);
747 1 : CATCH_REQUIRE(a < b);
748 1 : CATCH_REQUIRE(a <= b);
749 1 : CATCH_REQUIRE_FALSE(a > b);
750 1 : CATCH_REQUIRE_FALSE(a >= b);
751 :
752 1 : std::swap(a, b);
753 :
754 1 : CATCH_REQUIRE_FALSE(a == b);
755 1 : CATCH_REQUIRE(a != b);
756 1 : CATCH_REQUIRE_FALSE(a < b);
757 1 : CATCH_REQUIRE_FALSE(a <= b);
758 1 : CATCH_REQUIRE(a > b);
759 1 : CATCH_REQUIRE(a >= b);
760 : }
761 : CATCH_END_SECTION()
762 2 : }
763 :
764 :
765 5 : CATCH_TEST_CASE("unix::mix", "[unix]")
766 : {
767 6 : CATCH_START_SECTION("unix() with a relative file name then unnamed")
768 : {
769 11 : for(int count(0); count < 10; ++count)
770 : {
771 20 : std::string name("test");
772 10 : int const max(rand() % 5 + 3);
773 60 : for(int id(0); id < max; ++id)
774 : {
775 50 : name += '0' + rand() % 10;
776 : }
777 :
778 : // verify the init_un() as we're at it
779 : //
780 10 : sockaddr_un init = addr::init_un();
781 10 : CATCH_REQUIRE(init.sun_family == AF_UNIX);
782 1090 : for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
783 : {
784 1080 : CATCH_CHECK(init.sun_path[idx] == 0);
785 : }
786 10 : strncpy(init.sun_path, name.c_str(), sizeof(init.sun_path) - 1);
787 :
788 10 : addr::unix u(init);
789 :
790 10 : CATCH_REQUIRE(u.is_file());
791 10 : CATCH_REQUIRE_FALSE(u.is_abstract());
792 10 : CATCH_REQUIRE_FALSE(u.is_unnamed());
793 10 : CATCH_REQUIRE(u.to_string() == name);
794 10 : CATCH_REQUIRE(u.to_uri() == "unix:" + name);
795 :
796 10 : sockaddr_un un;
797 10 : u.get_un(un);
798 10 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
799 10 : CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
800 1000 : for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
801 : {
802 990 : CATCH_CHECK(un.sun_path[idx] == 0);
803 : }
804 :
805 10 : u.make_unnamed();
806 :
807 10 : CATCH_REQUIRE_FALSE(u.is_file());
808 10 : CATCH_REQUIRE_FALSE(u.is_abstract());
809 10 : CATCH_REQUIRE(u.is_unnamed());
810 10 : CATCH_REQUIRE(u.to_string() == std::string());
811 10 : CATCH_REQUIRE(u.to_uri() == "unix:");
812 :
813 10 : u.get_un(un);
814 10 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
815 1090 : for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
816 : {
817 1080 : CATCH_CHECK(un.sun_path[idx] == 0);
818 : }
819 : }
820 : }
821 : CATCH_END_SECTION()
822 :
823 6 : CATCH_START_SECTION("unix() with a full abstract name then unnamed")
824 : {
825 11 : for(int count(0); count < 10; ++count)
826 : {
827 20 : std::string name("/net/snapwebsites/settings/test");
828 10 : int const max(rand() % 25 + 3);
829 129 : for(int id(0); id < max; ++id)
830 : {
831 119 : name += '0' + rand() % 10;
832 : }
833 :
834 : // verify the init_un() as we're at it
835 : //
836 10 : sockaddr_un init = addr::init_un();
837 10 : CATCH_REQUIRE(init.sun_family == AF_UNIX);
838 1090 : for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
839 : {
840 1080 : CATCH_CHECK(init.sun_path[idx] == 0);
841 : }
842 10 : strncpy(init.sun_path + 1, name.c_str(), sizeof(init.sun_path) - 2);
843 :
844 10 : addr::unix u(init);
845 :
846 10 : CATCH_REQUIRE_FALSE(u.is_file());
847 10 : CATCH_REQUIRE(u.is_abstract());
848 10 : CATCH_REQUIRE_FALSE(u.is_unnamed());
849 10 : CATCH_REQUIRE(u.to_string() == name);
850 10 : CATCH_REQUIRE(u.to_uri() == "unix://" + name + "?abstract");
851 :
852 10 : sockaddr_un un;
853 10 : u.get_un(un);
854 10 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
855 10 : CATCH_REQUIRE(un.sun_path[0] == '\0');
856 10 : CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
857 651 : for(std::size_t idx(name.length() + 1); idx < sizeof(un.sun_path); ++idx)
858 : {
859 641 : CATCH_CHECK(un.sun_path[idx] == 0);
860 : }
861 :
862 10 : u.make_unnamed();
863 :
864 10 : CATCH_REQUIRE_FALSE(u.is_file());
865 10 : CATCH_REQUIRE_FALSE(u.is_abstract());
866 10 : CATCH_REQUIRE(u.is_unnamed());
867 10 : CATCH_REQUIRE(u.to_string() == std::string());
868 10 : CATCH_REQUIRE(u.to_uri() == "unix:");
869 :
870 10 : u.get_un(un);
871 10 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
872 1090 : for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
873 : {
874 1080 : CATCH_CHECK(un.sun_path[idx] == 0);
875 : }
876 : }
877 : }
878 : CATCH_END_SECTION()
879 :
880 6 : CATCH_START_SECTION("unix() with various set_uri()")
881 : {
882 1 : addr::unix u;
883 :
884 223 : for(int count(0); count < 222; ++count)
885 : {
886 222 : int type(count % 3);
887 :
888 444 : std::string name;
889 222 : if(type != 2)
890 : {
891 148 : name = "/run/snapwebsites/sockets/test";
892 148 : int const max(rand() % 25 + 3);
893 2307 : for(int id(0); id < max; ++id)
894 : {
895 2159 : name += '0' + rand() % 10;
896 : }
897 : }
898 :
899 222 : bool force(count % 6 != type);
900 :
901 222 : sockaddr_un un;
902 222 : switch(count % 3)
903 : {
904 74 : case 0:
905 74 : u.set_uri("unix://" + name + (force ? "?file" : ""));
906 :
907 74 : CATCH_REQUIRE(u.is_file());
908 74 : CATCH_REQUIRE_FALSE(u.is_abstract());
909 74 : CATCH_REQUIRE_FALSE(u.is_unnamed());
910 74 : CATCH_REQUIRE(u.to_string() == name);
911 74 : CATCH_REQUIRE(u.to_uri() == "unix://" + name);
912 :
913 74 : u.get_un(un);
914 74 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
915 74 : CATCH_REQUIRE(strcmp(un.sun_path, name.c_str()) == 0);
916 4813 : for(std::size_t idx(name.length()); idx < sizeof(un.sun_path); ++idx)
917 : {
918 4739 : CATCH_CHECK(un.sun_path[idx] == 0);
919 74 : }
920 74 : break;
921 :
922 74 : case 1:
923 74 : u.set_uri("unix://" + name + "?abstract");
924 :
925 74 : CATCH_REQUIRE_FALSE(u.is_file());
926 74 : CATCH_REQUIRE(u.is_abstract());
927 74 : CATCH_REQUIRE_FALSE(u.is_unnamed());
928 74 : CATCH_REQUIRE(u.to_string() == name);
929 74 : CATCH_REQUIRE(u.to_uri() == "unix://" + name + "?abstract");
930 :
931 74 : u.get_un(un);
932 74 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
933 74 : CATCH_REQUIRE(un.sun_path[0] == '\0');
934 74 : CATCH_REQUIRE(strcmp(un.sun_path + 1, name.c_str()) == 0);
935 4646 : for(std::size_t idx(name.length() + 1); idx < sizeof(un.sun_path); ++idx)
936 : {
937 4572 : CATCH_CHECK(un.sun_path[idx] == 0);
938 74 : }
939 74 : break;
940 :
941 74 : case 2:
942 74 : u.set_uri(force ? "unix:?unnamed" : "unix:");
943 :
944 74 : CATCH_REQUIRE_FALSE(u.is_file());
945 74 : CATCH_REQUIRE_FALSE(u.is_abstract());
946 74 : CATCH_REQUIRE(u.is_unnamed());
947 74 : CATCH_REQUIRE(u.to_string() == std::string());
948 74 : CATCH_REQUIRE(u.to_uri() == "unix:");
949 :
950 74 : u.get_un(un);
951 74 : CATCH_REQUIRE(un.sun_family == AF_UNIX);
952 8066 : for(std::size_t idx(0); idx < sizeof(un.sun_path); ++idx)
953 : {
954 7992 : CATCH_CHECK(un.sun_path[idx] == 0);
955 74 : }
956 74 : break;
957 :
958 : }
959 : }
960 : }
961 : CATCH_END_SECTION()
962 3 : }
963 :
964 :
965 14 : CATCH_TEST_CASE("unix::invalid", "[unix]")
966 : {
967 24 : CATCH_START_SECTION("unix() with an invalid address family")
968 : {
969 52 : for(int family(-25); family <= 25; ++family)
970 : {
971 51 : if(family == AF_UNIX)
972 : {
973 1 : continue;
974 : }
975 :
976 50 : sockaddr_un init = addr::init_un();
977 50 : init.sun_family = family;
978 :
979 : // constructor
980 : //
981 50 : CATCH_REQUIRE_THROWS_AS(addr::unix(init), addr::addr_invalid_structure);
982 :
983 : // set_un()
984 : //
985 50 : addr::unix u;
986 50 : CATCH_REQUIRE_THROWS_AS(u.set_un(init), addr::addr_invalid_structure);
987 : }
988 : }
989 : CATCH_END_SECTION()
990 :
991 24 : CATCH_START_SECTION("unix() with an unnamed string but marked abstract")
992 : {
993 1 : CATCH_REQUIRE_THROWS_AS(addr::unix(std::string(), true), addr::addr_invalid_argument);
994 : }
995 : CATCH_END_SECTION()
996 :
997 24 : CATCH_START_SECTION("unix() with a URI and a missing path")
998 : {
999 1 : addr::unix u;
1000 1 : CATCH_REQUIRE_THROWS_AS(u.set_uri("unix://"), addr::addr_invalid_argument);
1001 : }
1002 : CATCH_END_SECTION()
1003 :
1004 24 : CATCH_START_SECTION("unix() with too long a file name")
1005 : {
1006 : sockaddr_un un;
1007 12 : for(int count(static_cast<int>(sizeof(un.sun_path)));
1008 12 : count < static_cast<int>(sizeof(un.sun_path) + 11);
1009 : ++count)
1010 : {
1011 22 : std::string name;
1012 1254 : for(int id(0); id < count; ++id)
1013 : {
1014 1243 : name += '0' + rand() % 10;
1015 : }
1016 :
1017 11 : CATCH_REQUIRE_THROWS_AS(addr::unix(name), addr::addr_invalid_argument);
1018 :
1019 11 : addr::unix u;
1020 11 : CATCH_REQUIRE_THROWS_AS(u.set_uri("unix:" + name), addr::addr_invalid_argument);
1021 : }
1022 : }
1023 : CATCH_END_SECTION()
1024 :
1025 24 : CATCH_START_SECTION("unix() with too long an abstract name")
1026 : {
1027 : sockaddr_un un;
1028 12 : for(int count(static_cast<int>(sizeof(un.sun_path) - 1));
1029 12 : count < static_cast<int>(sizeof(un.sun_path) + 10);
1030 : ++count)
1031 : {
1032 22 : std::string name;
1033 1243 : for(int id(0); id < count; ++id)
1034 : {
1035 1232 : name += '0' + rand() % 10;
1036 : }
1037 :
1038 11 : CATCH_REQUIRE_THROWS_AS(addr::unix(name, true), addr::addr_invalid_argument);
1039 :
1040 11 : addr::unix u;
1041 11 : CATCH_REQUIRE_THROWS_AS(u.set_uri("unix:" + name + "?abstract"), addr::addr_invalid_argument);
1042 : }
1043 : }
1044 : CATCH_END_SECTION()
1045 :
1046 24 : CATCH_START_SECTION("unix() with a long filename (missing '\\0')")
1047 : {
1048 1 : sockaddr_un init = addr::init_un();
1049 109 : for(std::size_t idx(0); idx < sizeof(init.sun_path); ++idx)
1050 : {
1051 108 : init.sun_path[idx] = '0' + rand() % 10;
1052 : }
1053 :
1054 : // constructor
1055 : //
1056 1 : CATCH_REQUIRE_THROWS_AS(addr::unix(init), addr::addr_invalid_argument);
1057 :
1058 : // set_un()
1059 : //
1060 1 : addr::unix u;
1061 1 : CATCH_REQUIRE_THROWS_AS(u.set_un(init), addr::addr_invalid_argument);
1062 : }
1063 : CATCH_END_SECTION()
1064 :
1065 24 : CATCH_START_SECTION("unix() with a long abstrat name (missing '\\0')")
1066 : {
1067 1 : sockaddr_un init = addr::init_un();
1068 108 : for(std::size_t idx(1); idx < sizeof(init.sun_path); ++idx)
1069 : {
1070 107 : init.sun_path[idx] = '0' + rand() % 10;
1071 : }
1072 :
1073 : // constructor
1074 : //
1075 1 : CATCH_REQUIRE_THROWS_AS(addr::unix(init), addr::addr_invalid_argument);
1076 :
1077 : // set_un()
1078 : //
1079 1 : addr::unix u;
1080 1 : CATCH_REQUIRE_THROWS_AS(u.set_un(init), addr::addr_invalid_argument);
1081 : }
1082 : CATCH_END_SECTION()
1083 :
1084 24 : CATCH_START_SECTION("unix() with a long abstrat name (missing '\\0')")
1085 : {
1086 1 : addr::unix u;
1087 :
1088 : // missing ":"
1089 : //
1090 1 : CATCH_REQUIRE_THROWS_AS(u.set_uri("unix/run/snapwebsites/sockets"), addr::addr_invalid_argument);
1091 :
1092 : // "?alexis"
1093 : //
1094 1 : CATCH_REQUIRE_THROWS_AS(u.set_uri("unix:/run/snapwebsites/sockets?alexis"), addr::addr_invalid_argument);
1095 :
1096 : // "http:"
1097 : //
1098 1 : CATCH_REQUIRE_THROWS_AS(u.set_uri("http:/run/snapwebsites/sockets?abstract"), addr::addr_invalid_argument);
1099 :
1100 : // name with "?unnamed"
1101 : //
1102 1 : CATCH_REQUIRE_THROWS_AS(u.set_uri("unix:not-empty?unnamed"), addr::addr_invalid_argument);
1103 : }
1104 : CATCH_END_SECTION()
1105 :
1106 24 : CATCH_START_SECTION("unix() with invalid characters (controls)")
1107 : {
1108 32 : for(int c(1); c < 0x20; ++c)
1109 : {
1110 62 : std::string name;
1111 31 : name += c;
1112 31 : CATCH_REQUIRE_THROWS_AS(addr::unix(name), addr::addr_invalid_argument);
1113 : }
1114 :
1115 34 : for(int c(0x7F); c < 0xA0; ++c)
1116 : {
1117 66 : std::u32string u32;
1118 33 : u32 += c;
1119 66 : std::string name(libutf8::to_u8string(u32));
1120 33 : CATCH_REQUIRE_THROWS_AS(addr::unix(name), addr::addr_invalid_argument);
1121 : }
1122 : }
1123 : CATCH_END_SECTION()
1124 :
1125 24 : CATCH_START_SECTION("unix() with invalid UTF-8 characters")
1126 : {
1127 2 : std::string name;
1128 11 : for(int c(0); c < 10; ++c)
1129 : {
1130 10 : name += static_cast<char>(0x80);
1131 : }
1132 1 : CATCH_REQUIRE_THROWS_AS(addr::unix(name), libutf8::libutf8_exception_decoding);
1133 : }
1134 : CATCH_END_SECTION()
1135 :
1136 24 : CATCH_START_SECTION("get unix() of socket set to -1")
1137 : {
1138 1 : addr::unix u;
1139 1 : bool const result(u.set_from_socket(-1));
1140 1 : int const e(errno);
1141 1 : CATCH_REQUIRE_FALSE(result);
1142 1 : CATCH_REQUIRE(e == EBADF);
1143 : }
1144 : CATCH_END_SECTION()
1145 :
1146 24 : CATCH_START_SECTION("get unix() of socket set to UDP")
1147 : {
1148 1 : addr::addr udp(addr::string_to_addr(
1149 : "127.0.0.1:3999"
1150 : , "127.0.0.1"
1151 : , 3999
1152 2 : , "udp"));
1153 2 : snapdev::raii_fd_t s(socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP));
1154 1 : CATCH_REQUIRE(s != nullptr);
1155 1 : sockaddr_in in;
1156 1 : udp.get_ipv4(in);
1157 1 : CATCH_REQUIRE(bind(s.get(), reinterpret_cast<sockaddr *>(&in), sizeof(in)) == 0);
1158 :
1159 1 : addr::unix u;
1160 1 : bool const result(u.set_from_socket(s.get()));
1161 1 : int const e(errno);
1162 1 : CATCH_REQUIRE_FALSE(result);
1163 1 : CATCH_REQUIRE(e == EADDRNOTAVAIL);
1164 : }
1165 : CATCH_END_SECTION()
1166 18 : }
1167 :
1168 :
1169 : // vim: ts=4 sw=4 et
|