@@ -1,3 +1,11 @@
+2014-05-06 Aurelien Jarno <aurelien@aurel32.net>
+
+ * sysdeps/unix/sysv/linux/ptsname.c (__ptsname_internal): return
+ errno if the TIOCGPTN ioctl fails with an error different than
+ EINVAL.
+ * login/tst-ptsname.c: New file.
+ * login/Makefile (tests): Add tst-ptsname.
+
2014-05-05 Aurelien Jarno <aurelien@aurel32.net>
* po/fr.po: Fix French translation of inappropriate.
@@ -43,7 +43,7 @@ endif
subdir-dirs = programs
vpath %.c programs
-tests := tst-utmp tst-utmpx tst-grantpt
+tests := tst-utmp tst-utmpx tst-grantpt tst-ptsname
# Build the -lutil library with these extra functions.
extra-libs := libutil
new file mode 100644
@@ -0,0 +1,138 @@
+#include <errno.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+static int
+test_ok (int fd)
+{
+ int ret, err;
+ char buf[512];
+
+ ret = ptsname_r (fd, buf, sizeof (buf));
+ err = errno;
+
+ if (ret != 0)
+ {
+ printf ("ptsname_r(): expected: return = %d\n", 0);
+ printf (" got: return = %d, errno = %d (%s)\n",
+ ret, err, strerror (err));
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+test_einval (int fd)
+{
+ int ret, err;
+ char *buf = NULL;
+
+ ret = ptsname_r (fd, buf, 1);
+ err = errno;
+
+ if (ret == 0 || errno != EINVAL)
+ {
+ printf ("ptsname_r(): expected: return = %d, errno = %d\n", -1, EINVAL);
+ printf (" got: return = %d, errno = %d (%s)\n",
+ ret, err, strerror (err));
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+test_erange (int fd)
+{
+ int ret, err;
+ char buf[512];
+
+ /* We assume that the PTS name will always be more than one character. */
+ ret = ptsname_r (fd, buf, 1);
+ err = errno;
+
+ if (ret == 0 || errno != ERANGE)
+ {
+ printf ("ptsname_r(): expected: return = %d, errno = %d\n", -1, ERANGE);
+ printf (" got: return = %d, errno = %d (%s)\n",
+ ret, err, strerror (err));
+ return 1;
+ }
+
+ return 0;
+}
+
+static int
+test_enotty (void)
+{
+ int fd, ret, err;
+ const char file[] = "./ptsname-einval";
+ char buf[512];
+
+ /* First try with a normal file. */
+ fd = open (file, O_RDWR | O_CREAT, 0600);
+ if (fd == -1)
+ {
+ printf ("open(\"%s\", O_RDWR) failed\nerrno %d (%s)\n",
+ file, errno, strerror (errno));
+ return 0;
+ }
+ unlink (file);
+
+ ret = ptsname_r (fd, buf, sizeof (buf));
+ err = errno;
+ close (fd);
+
+ if (ret == 0 || errno != ENOTTY)
+ {
+ printf ("ptsname_r(): expected: return = %d, errno = %d\n", -1, ENOTTY);
+ printf (" got: return = %d, errno = %d (%s)\n",
+ ret, err, strerror (err));
+ return 1;
+ }
+
+ /* Then try with a terminal device which is not a master. */
+ ret = ptsname_r (0, buf, sizeof (buf));
+ err = errno;
+
+ if (ret == 0 || errno != ENOTTY)
+ {
+ printf ("ptsname_r(): expected: return = %d, errno = %d\n", -1, ENOTTY);
+ printf (" got: return = %d, errno = %d (%s)\n",
+ ret, err, strerror (err));
+ return 1;
+ }
+
+ return 0;
+}
+
+int
+main (void)
+{
+ int result = 0;
+ int fd;
+
+ fd = posix_openpt (O_RDWR);
+ if (fd != -1)
+ {
+ result |= test_ok (fd);
+ result |= test_einval (fd);
+ result |= test_erange (fd);
+ close(fd);
+ }
+ else
+ {
+ printf ("posix_openpt(O_RDWR) failed\nerrno %d (%s)\n",
+ errno, strerror (errno));
+ /* We don't fail because of this; maybe the system does not have
+ SUS pseudo terminals. */
+ }
+
+ result |= test_enotty ();
+
+ return result;
+}
@@ -105,7 +105,9 @@ __ptsname_internal (int fd, char *buf, size_t buflen, struct stat64 *stp)
memcpy (__stpcpy (buf, devpts), p, &numbuf[sizeof (numbuf)] - p);
}
- else if (errno == EINVAL)
+ else if (errno != EINVAL)
+ return errno;
+ else
#endif
{
char *p;