]>
Commit | Line | Data |
---|---|---|
3375cfaf | 1 | /* Tests for socket address type definitions. |
688903eb | 2 | Copyright (C) 2016-2018 Free Software Foundation, Inc. |
3375cfaf FW |
3 | This file is part of the GNU C Library. |
4 | ||
5 | The GNU C Library is free software; you can redistribute it and/or | |
6 | modify it under the terms of the GNU Lesser General Public License as | |
7 | published by the Free Software Foundation; either version 2.1 of the | |
8 | License, or (at your option) any later version. | |
9 | ||
10 | The GNU C Library is distributed in the hope that it will be useful, | |
11 | but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 | Lesser General Public License for more details. | |
14 | ||
15 | You should have received a copy of the GNU Lesser General Public | |
16 | License along with the GNU C Library; see the file COPYING.LIB. If | |
17 | not, see <http://www.gnu.org/licenses/>. */ | |
18 | ||
19 | #include <netinet/in.h> | |
20 | #include <stdbool.h> | |
21 | #include <stddef.h> | |
22 | #include <stdio.h> | |
23 | #include <stdlib.h> | |
24 | #include <string.h> | |
25 | #include <sys/socket.h> | |
26 | #include <sys/un.h> | |
27 | ||
28 | /* This is a copy of the previous definition of struct | |
29 | sockaddr_storage. It is not equal to the old value of _SS_SIZE | |
30 | (128) on all architectures. We must stay compatible with the old | |
31 | definition. */ | |
32 | ||
33 | #define OLD_REFERENCE_SIZE 128 | |
34 | #define OLD_PADSIZE (OLD_REFERENCE_SIZE - (2 * sizeof (__ss_aligntype))) | |
35 | struct sockaddr_storage_old | |
36 | { | |
37 | __SOCKADDR_COMMON (old_); | |
38 | __ss_aligntype old_align; | |
39 | char old_padding[OLD_PADSIZE]; | |
40 | }; | |
41 | ||
42 | static bool errors; | |
43 | ||
44 | static void | |
45 | check (bool ok, const char *message) | |
46 | { | |
47 | if (!ok) | |
48 | { | |
49 | printf ("error: failed check: %s\n", message); | |
50 | errors = true; | |
51 | } | |
52 | } | |
53 | ||
54 | static int | |
55 | do_test (void) | |
56 | { | |
57 | check (OLD_REFERENCE_SIZE >= _SS_SIZE, | |
58 | "old target size is not smaller than actual size"); | |
59 | check (sizeof (struct sockaddr_storage_old) | |
60 | == sizeof (struct sockaddr_storage), | |
61 | "old and new sizes match"); | |
62 | check (__alignof (struct sockaddr_storage_old) | |
63 | == __alignof (struct sockaddr_storage), | |
64 | "old and new alignment matches"); | |
65 | check (offsetof (struct sockaddr_storage_old, old_family) | |
66 | == offsetof (struct sockaddr_storage, ss_family), | |
67 | "old and new family offsets match"); | |
68 | check (sizeof (struct sockaddr_storage) == _SS_SIZE, | |
69 | "struct sockaddr_storage size"); | |
70 | ||
71 | /* Check for lack of holes in the struct definition. */ | |
72 | check (offsetof (struct sockaddr_storage, __ss_padding) | |
73 | == __SOCKADDR_COMMON_SIZE, | |
74 | "implicit padding before explicit padding"); | |
75 | check (offsetof (struct sockaddr_storage, __ss_align) | |
76 | == __SOCKADDR_COMMON_SIZE | |
77 | + sizeof (((struct sockaddr_storage) {}).__ss_padding), | |
78 | "implicit padding before explicit padding"); | |
79 | ||
80 | /* Check for POSIX compatibility requirements between struct | |
81 | sockaddr_storage and struct sockaddr_un. */ | |
82 | check (sizeof (struct sockaddr_storage) >= sizeof (struct sockaddr_un), | |
83 | "sockaddr_storage is at least as large as sockaddr_un"); | |
84 | check (__alignof (struct sockaddr_storage) | |
85 | >= __alignof (struct sockaddr_un), | |
86 | "sockaddr_storage is at least as aligned as sockaddr_un"); | |
87 | check (offsetof (struct sockaddr_storage, ss_family) | |
88 | == offsetof (struct sockaddr_un, sun_family), | |
89 | "family offsets match"); | |
90 | ||
91 | /* Check that the compiler preserves bit patterns in aggregate | |
92 | copies. Based on <https://gcc.gnu.org/PR71120>. */ | |
93 | check (sizeof (struct sockaddr_storage) >= sizeof (struct sockaddr_in), | |
94 | "sockaddr_storage is at least as large as sockaddr_in"); | |
95 | { | |
96 | struct sockaddr_storage addr; | |
97 | memset (&addr, 0, sizeof (addr)); | |
98 | { | |
99 | struct sockaddr_in *sinp = (struct sockaddr_in *)&addr; | |
100 | sinp->sin_family = AF_INET; | |
101 | sinp->sin_addr.s_addr = htonl (INADDR_LOOPBACK); | |
102 | sinp->sin_port = htons (80); | |
103 | } | |
104 | struct sockaddr_storage copy; | |
105 | copy = addr; | |
106 | ||
107 | struct sockaddr_storage *p = malloc (sizeof (*p)); | |
108 | if (p == NULL) | |
109 | { | |
110 | printf ("error: malloc: %m\n"); | |
111 | return 1; | |
112 | } | |
113 | *p = copy; | |
114 | const struct sockaddr_in *sinp = (const struct sockaddr_in *)p; | |
115 | check (sinp->sin_family == AF_INET, "sin_family"); | |
116 | check (sinp->sin_addr.s_addr == htonl (INADDR_LOOPBACK), "sin_addr"); | |
117 | check (sinp->sin_port == htons (80), "sin_port"); | |
118 | free (p); | |
119 | } | |
120 | ||
121 | return errors; | |
122 | } | |
123 | ||
124 | #define TEST_FUNCTION do_test () | |
125 | #include "../test-skeleton.c" |