1 /* Test for grantpt, unlockpt error corner cases.
2    Copyright (C) 2001-2022 Free Software Foundation, Inc.
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
7    License as published by the Free Software Foundation; either
8    version 2.1 of the 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; if not, see
17    <https://www.gnu.org/licenses/>.  */
18 
19 #include <sys/types.h>
20 #include <sys/stat.h>
21 #include <fcntl.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <string.h>
26 #include <unistd.h>
27 #include <support/check.h>
28 #include <support/temp_file.h>
29 #include <support/xunistd.h>
30 
31 /* Test grantpt, unlockpt with a closed descriptor.  */
32 static void
test_ebadf(void)33 test_ebadf (void)
34 {
35   int fd, ret, err;
36 
37   fd = posix_openpt (O_RDWR);
38   if (fd == -1)
39     FAIL_EXIT1 ("posix_openpt(O_RDWR) failed\nerrno %d (%m)\n", errno);
40   TEST_COMPARE (unlockpt (fd), 0);
41 
42   xclose (fd);
43   ret = grantpt (fd);
44   err = errno;
45   if (ret != -1 || err != EBADF)
46     {
47       support_record_failure ();
48       printf ("grantpt(): expected: return = %d, errno = %d\n", -1, EBADF);
49       printf ("           got: return = %d, errno = %d\n", ret, err);
50     }
51 
52   TEST_COMPARE (unlockpt (fd), -1);
53   TEST_COMPARE (errno, EBADF);
54 }
55 
56 /* Test grantpt, unlockpt on a regular file.  */
57 static void
test_einval(void)58 test_einval (void)
59 {
60   int fd, ret, err;
61 
62   fd = create_temp_file ("tst-grantpt-", NULL);
63   TEST_VERIFY_EXIT (fd >= 0);
64 
65   ret = grantpt (fd);
66   err = errno;
67   if (ret != -1 || err != EINVAL)
68     {
69       support_record_failure ();
70       printf ("grantpt(): expected: return = %d, errno = %d\n", -1, EINVAL);
71       printf ("           got: return = %d, errno = %d\n", ret, err);
72     }
73 
74   TEST_COMPARE (unlockpt (fd), -1);
75   TEST_COMPARE (errno, EINVAL);
76 
77   xclose (fd);
78 }
79 
80 /* Test grantpt, unlockpt on a non-ptmx pseudo-terminal.  */
81 static void
test_not_ptmx(void)82 test_not_ptmx (void)
83 {
84   int ptmx = posix_openpt (O_RDWR);
85   TEST_VERIFY_EXIT (ptmx >= 0);
86   TEST_COMPARE (grantpt (ptmx), 0);
87   TEST_COMPARE (unlockpt (ptmx), 0);
88 
89   /* A second unlock succeeds as well.  */
90   TEST_COMPARE (unlockpt (ptmx), 0);
91 
92   const char *name = ptsname (ptmx);
93   TEST_VERIFY_EXIT (name != NULL);
94   int pts = open (name, O_RDWR | O_NOCTTY);
95   TEST_VERIFY_EXIT (pts >= 0);
96 
97   TEST_COMPARE (grantpt (pts), -1);
98   TEST_COMPARE (errno, EINVAL);
99 
100   TEST_COMPARE (unlockpt (pts), -1);
101   TEST_COMPARE (errno, EINVAL);
102 
103   xclose (pts);
104   xclose (ptmx);
105 }
106 
107 static int
do_test(void)108 do_test (void)
109 {
110   test_ebadf ();
111   test_einval ();
112   test_not_ptmx ();
113   return 0;
114 }
115 
116 #include <support/test-driver.c>
117