support: Preserve errno in write_message, TEST_VERIFY and other checks
[glibc.git] / grp / tst-putgrent.c
blob6a75a0e0d7e5736a33cf600733318e8db4128674
1 /* Test for processing of invalid group entries. [BZ #18724]
2 Copyright (C) 2015-2018 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
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
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
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.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <http://www.gnu.org/licenses/>. */
19 #include <errno.h>
20 #include <grp.h>
21 #include <stdbool.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <string.h>
26 static bool errors;
28 static void
29 check (struct group e, const char *expected)
31 char *buf;
32 size_t buf_size;
33 FILE *f = open_memstream (&buf, &buf_size);
35 if (f == NULL)
37 printf ("open_memstream: %m\n");
38 errors = true;
39 return;
42 int ret = putgrent (&e, f);
44 if (expected == NULL)
46 if (ret == -1)
48 if (errno != EINVAL)
50 printf ("putgrent: unexpected error code: %m\n");
51 errors = true;
54 else
56 printf ("putgrent: unexpected success (\"%s\", \"%s\")\n",
57 e.gr_name, e.gr_passwd);
58 errors = true;
61 else
63 /* Expect success. */
64 size_t expected_length = strlen (expected);
65 if (ret == 0)
67 long written = ftell (f);
69 if (written <= 0 || fflush (f) < 0)
71 printf ("stream error: %m\n");
72 errors = true;
74 else if (buf[written - 1] != '\n')
76 printf ("FAILED: \"%s\" without newline\n", expected);
77 errors = true;
79 else if (strncmp (buf, expected, written - 1) != 0
80 || written - 1 != expected_length)
82 buf[written - 1] = '\0';
83 printf ("FAILED: \"%s\" (%ld), expected \"%s\" (%zu)\n",
84 buf, written - 1, expected, expected_length);
85 errors = true;
88 else
90 printf ("FAILED: putgrent (expected \"%s\"): %m\n", expected);
91 errors = true;
95 fclose (f);
96 free (buf);
99 static int
100 do_test (void)
102 check ((struct group) {
103 .gr_name = (char *) "root",
105 "root::0:");
106 check ((struct group) {
107 .gr_name = (char *) "root",
108 .gr_passwd = (char *) "password",
109 .gr_gid = 1234,
110 .gr_mem = (char *[2]) {(char *) "member1", NULL}
112 "root:password:1234:member1");
113 check ((struct group) {
114 .gr_name = (char *) "root",
115 .gr_passwd = (char *) "password",
116 .gr_gid = 1234,
117 .gr_mem = (char *[3]) {(char *) "member1", (char *) "member2", NULL}
119 "root:password:1234:member1,member2");
121 /* Bad values. */
123 static const char *const bad_strings[] = {
124 ":",
125 "\n",
126 ":bad",
127 "\nbad",
128 "b:ad",
129 "b\nad",
130 "bad:",
131 "bad\n",
132 "b:a\nd"
133 ",",
134 "\n,",
135 ":,",
136 ",bad",
137 "b,ad",
138 "bad,",
139 NULL
141 for (const char *const *bad = bad_strings; *bad != NULL; ++bad)
143 char *members[]
144 = {(char *) "first", (char *) *bad, (char *) "last", NULL};
145 if (strpbrk (*bad, ":\n") != NULL)
147 check ((struct group) {
148 .gr_name = (char *) *bad,
149 }, NULL);
150 check ((struct group) {
151 .gr_name = (char *) "root",
152 .gr_passwd = (char *) *bad,
153 }, NULL);
155 check ((struct group) {
156 .gr_name = (char *) "root",
157 .gr_passwd = (char *) "password",
158 .gr_mem = members,
159 }, NULL);
163 return errors;
166 #define TEST_FUNCTION do_test ()
167 #include "../test-skeleton.c"