Remove iotty test
The auxiliary utility ttyemu proved to be unreliable. Given existing differences between pty implementations and termios ioctls on various platforms, writing it in a portable way requires effort disproportional to its actual purpose. * configure.ac: Remove check for grantpt * gnulib.modules: Remove posix_openpt, ptsname, and unlockpt * tests/Makefile.am (TESTSUITE_AT): Remove iotty.at (check_PROGRAMS): Remove ttyemu. * tests/testsuite.at: Remove iotty.at * tests/iotty.at: Remove. * tests/ttyemu.c: Remove.
This commit is contained in:
@@ -206,8 +206,7 @@ fi
|
||||
|
||||
TAR_HEADERS_ATTR_XATTR_H
|
||||
|
||||
AC_CHECK_FUNCS_ONCE([fchmod fchown fsync lstat mkfifo readlink symlink grantpt])
|
||||
AM_CONDITIONAL([TAR_COND_GRANTPT], [test $ac_cv_func_grantpt = yes])
|
||||
AC_CHECK_FUNCS_ONCE([fchmod fchown fsync lstat mkfifo readlink symlink])
|
||||
|
||||
AC_CHECK_DECLS([getgrgid],,, [#include <grp.h>])
|
||||
AC_CHECK_DECLS([getpwuid],,, [#include <pwd.h>])
|
||||
|
||||
@@ -66,8 +66,6 @@ modechange
|
||||
obstack
|
||||
openat
|
||||
parse-datetime
|
||||
posix_openpt
|
||||
ptsname
|
||||
priv-set
|
||||
progname
|
||||
quote
|
||||
@@ -97,7 +95,6 @@ timespec-sub
|
||||
unlinkat
|
||||
unlinkdir
|
||||
unlocked-io
|
||||
unlockpt
|
||||
utimensat
|
||||
version-etc-fsf
|
||||
xalloc
|
||||
|
||||
@@ -124,7 +124,6 @@ TESTSUITE_AT = \
|
||||
incr11.at\
|
||||
indexfile.at\
|
||||
ignfail.at\
|
||||
iotty.at\
|
||||
label01.at\
|
||||
label02.at\
|
||||
label03.at\
|
||||
@@ -284,15 +283,9 @@ installcheck-local: $(check_PROGRAMS)
|
||||
|
||||
check_PROGRAMS = genfile checkseekhole ckmtime
|
||||
|
||||
if TAR_COND_GRANTPT
|
||||
check_PROGRAMS += ttyemu
|
||||
endif
|
||||
|
||||
genfile_SOURCES = genfile.c argcv.c argcv.h
|
||||
checkseekhole_SOURCES = checkseekhole.c
|
||||
|
||||
ttyemu_SOURCES = ttyemu.c
|
||||
|
||||
localedir = $(datadir)/locale
|
||||
AM_CPPFLAGS = \
|
||||
-I$(top_srcdir)/gnu\
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
# Process this file with autom4te to create testsuite. -*- Autotest -*-
|
||||
|
||||
# Test suite for GNU tar.
|
||||
# Copyright 2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
# This file is part of GNU tar.
|
||||
|
||||
# GNU tar is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
|
||||
# GNU tar is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# Description: Tar should refuse to read archive from the terminal.
|
||||
# Reported by: Pavel Raiskup
|
||||
# References: <5285498.uPPgZ77uHP@nb.usersys.redhat.com>,
|
||||
# http://lists.gnu.org/archive/html/bug-tar/2014-03/msg00033.html
|
||||
|
||||
AT_SETUP([terminal input])
|
||||
AT_KEYWORDS([options iotty])
|
||||
|
||||
m4_define([TTYEMU],[ttyemu -t5 -i/dev/null $*
|
||||
rc=$?
|
||||
# Skip test if ttyemu can't do its job
|
||||
test $rc -eq 126 && AT_SKIP_TEST
|
||||
echo $rc])
|
||||
|
||||
AT_TAR_CHECK([
|
||||
test -x $abs_builddir/ttyemu || AT_SKIP_TEST
|
||||
TAPE=-
|
||||
export TAPE
|
||||
TTYEMU(tar -x)
|
||||
TTYEMU(tar -xz)
|
||||
TTYEMU(tar -c .)
|
||||
],
|
||||
[0],
|
||||
[tar: Refusing to read archive contents from terminal (missing -f option?)
|
||||
tar: Error is not recoverable: exiting now
|
||||
2
|
||||
tar: Refusing to read archive contents from terminal (missing -f option?)
|
||||
tar: Error is not recoverable: exiting now
|
||||
2
|
||||
tar: Refusing to write archive contents to terminal (missing -f option?)
|
||||
tar: Error is not recoverable: exiting now
|
||||
2
|
||||
],
|
||||
[],[],[],[posix, gnu, oldgnu])
|
||||
|
||||
AT_CLEANUP
|
||||
@@ -234,7 +234,6 @@ m4_include([gzip.at])
|
||||
m4_include([recurse.at])
|
||||
m4_include([recurs02.at])
|
||||
m4_include([shortrec.at])
|
||||
m4_include([iotty.at])
|
||||
m4_include([numeric.at])
|
||||
|
||||
AT_BANNER([The --same-order option])
|
||||
|
||||
460
tests/ttyemu.c
460
tests/ttyemu.c
@@ -1,460 +0,0 @@
|
||||
/* Run program with its first three file descriptors attached to a tty.
|
||||
|
||||
Copyright 2014, 2016 Free Software Foundation, Inc.
|
||||
|
||||
This file is part of GNU tar.
|
||||
|
||||
GNU tar is free software; you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation; either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
GNU tar is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/select.h>
|
||||
#include <termios.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#ifndef TCSASOFT
|
||||
# define TCSASOFT 0
|
||||
#endif
|
||||
|
||||
#define C_EOT 4
|
||||
|
||||
#define EX_OK 0
|
||||
#define EX_USAGE 125
|
||||
#define EX_ERR 126
|
||||
#define EX_EXEC 127
|
||||
|
||||
#define BUF_SIZE 1024
|
||||
|
||||
#if 0
|
||||
# define DEBUG(c) fprintf (stderr, "%s\n", c)
|
||||
#else
|
||||
# define DEBUG(c)
|
||||
#endif
|
||||
|
||||
struct buffer
|
||||
{
|
||||
char buf[BUF_SIZE];
|
||||
int avail;
|
||||
int written;
|
||||
int cr;
|
||||
time_t ts;
|
||||
};
|
||||
|
||||
#define shut(fildes) \
|
||||
do \
|
||||
{ \
|
||||
DEBUG (("closing " #fildes)); \
|
||||
close(fildes); \
|
||||
fildes = -1; \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define bufinit(buffer,all) \
|
||||
do \
|
||||
{ \
|
||||
(buffer).avail = (buffer).written = 0; \
|
||||
(buffer).ts = time (NULL); \
|
||||
if (all) \
|
||||
(buffer).cr = 0; \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define bufisempty(buffer) ((buffer).avail == (buffer).written)
|
||||
#define bufavail(buffer) (BUF_SIZE - (buffer).avail)
|
||||
|
||||
#define bufread(buffer,fildes,tty) \
|
||||
do \
|
||||
{ \
|
||||
int r = read (fildes, (buffer).buf + (buffer).avail, \
|
||||
BUF_SIZE - (buffer).avail); \
|
||||
(buffer).ts = time (NULL); \
|
||||
if (r < 0) \
|
||||
{ \
|
||||
if (errno == EINTR) \
|
||||
continue; \
|
||||
if (tty && errno == EIO) \
|
||||
shut (fildes); \
|
||||
else \
|
||||
{ \
|
||||
fprintf (stderr, "%s:%d: reading from %s: %s", \
|
||||
__FILE__,__LINE__,#fildes, strerror (errno)); \
|
||||
exit (EX_ERR); \
|
||||
} \
|
||||
} \
|
||||
else if (r == 0) \
|
||||
shut (fildes); \
|
||||
else \
|
||||
(buffer).avail += r; \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
#define bufwrite(buffer,fildes) \
|
||||
do \
|
||||
{ \
|
||||
int r = write (fildes, (buffer).buf + (buffer).written, \
|
||||
(buffer).avail - (buffer).written); \
|
||||
(buffer).ts = time (NULL); \
|
||||
if (r < 0) \
|
||||
{ \
|
||||
if (errno == EINTR) \
|
||||
continue; \
|
||||
if (stop) \
|
||||
shut (fildes); \
|
||||
else \
|
||||
{ \
|
||||
perror ("writing"); \
|
||||
exit (EX_ERR); \
|
||||
} \
|
||||
} \
|
||||
else if (r == 0) \
|
||||
/*shut (fildes)*/; \
|
||||
else \
|
||||
(buffer).written += r; \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
void
|
||||
tr (struct buffer *bp)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = j = bp->written; i < bp->avail;)
|
||||
{
|
||||
if (bp->buf[i] == '\r')
|
||||
{
|
||||
bp->cr = 1;
|
||||
i++;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (bp->cr)
|
||||
{
|
||||
bp->cr = 0;
|
||||
if (bp->buf[i] != '\n')
|
||||
bp->buf[j++] = '\r';
|
||||
}
|
||||
bp->buf[j++] = bp->buf[i++];
|
||||
}
|
||||
}
|
||||
bp->avail = j;
|
||||
}
|
||||
|
||||
int stop;
|
||||
int status;
|
||||
|
||||
void
|
||||
sigchld (int sig)
|
||||
{
|
||||
DEBUG (("child exited"));
|
||||
wait (&status);
|
||||
stop = 1;
|
||||
}
|
||||
|
||||
void
|
||||
noecho (int fd)
|
||||
{
|
||||
struct termios to;
|
||||
|
||||
if (tcgetattr (fd, &to))
|
||||
{
|
||||
perror ("tcgetattr");
|
||||
exit (EX_ERR);
|
||||
}
|
||||
to.c_lflag |= ICANON;
|
||||
to.c_lflag &= ~(ECHO | ISIG);
|
||||
to.c_cc[VEOF] = C_EOT;
|
||||
if (tcsetattr (fd, TCSAFLUSH | TCSASOFT, &to))
|
||||
{
|
||||
perror ("tcsetattr");
|
||||
exit (EX_ERR);
|
||||
}
|
||||
}
|
||||
|
||||
char *usage_text[] = {
|
||||
"usage: ttyemu [-ah] [-i INFILE] [-o OUTFILE] [-t TIMEOUT] PROGRAM [ARGS...]",
|
||||
"ttyemu runs PROGRAM with its first three file descriptors connected to a"
|
||||
" terminal",
|
||||
"",
|
||||
"Options are:",
|
||||
"",
|
||||
" -a append output to OUTFILE, instead of overwriting it",
|
||||
" -i INFILE read input from INFILE",
|
||||
" -o OUTFILE write output to OUTFILE",
|
||||
" -t TIMEOUT set I/O timeout",
|
||||
" -h print this help summary",
|
||||
"",
|
||||
"Report bugs and suggestions to <bug-tar@gnu.org>.",
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
usage (void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; usage_text[i]; i++)
|
||||
{
|
||||
fputs (usage_text[i], stderr);
|
||||
fputc ('\n', stderr);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int i;
|
||||
int master, slave;
|
||||
pid_t pid;
|
||||
fd_set rdset, wrset;
|
||||
struct buffer ibuf, obuf;
|
||||
int in = 0, out = 1;
|
||||
char *infile = NULL, *outfile = NULL;
|
||||
int outflags = O_TRUNC;
|
||||
int maxfd;
|
||||
int eot = C_EOT;
|
||||
int timeout = 0;
|
||||
|
||||
while ((i = getopt (argc, argv, "ai:o:t:h")) != EOF)
|
||||
{
|
||||
switch (i)
|
||||
{
|
||||
case 'a':
|
||||
outflags &= ~O_TRUNC;
|
||||
break;
|
||||
|
||||
case 'i':
|
||||
infile = optarg;
|
||||
break;
|
||||
|
||||
case 'o':
|
||||
outfile = optarg;
|
||||
break;
|
||||
|
||||
case 't':
|
||||
timeout = atoi (optarg);
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
usage ();
|
||||
return EX_OK;
|
||||
|
||||
default:
|
||||
return EX_USAGE;
|
||||
}
|
||||
}
|
||||
|
||||
argc -= optind;
|
||||
argv += optind;
|
||||
|
||||
if (argc == 0)
|
||||
{
|
||||
usage ();
|
||||
return EX_USAGE;
|
||||
}
|
||||
|
||||
if (infile)
|
||||
{
|
||||
in = open (infile, O_RDONLY);
|
||||
if (in == -1)
|
||||
{
|
||||
perror (infile);
|
||||
return EX_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (outfile)
|
||||
{
|
||||
out = open (outfile, O_RDWR|O_CREAT|outflags, 0666);
|
||||
if (out == -1)
|
||||
{
|
||||
perror (outfile);
|
||||
return EX_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
master = posix_openpt (O_RDWR);
|
||||
if (master == -1)
|
||||
{
|
||||
perror ("posix_openpty");
|
||||
return EX_ERR;
|
||||
}
|
||||
|
||||
if (grantpt (master))
|
||||
{
|
||||
perror ("grantpt");
|
||||
return EX_ERR;
|
||||
}
|
||||
|
||||
if (unlockpt (master))
|
||||
{
|
||||
perror ("unlockpt");
|
||||
return EX_ERR;
|
||||
}
|
||||
|
||||
signal (SIGCHLD, sigchld);
|
||||
|
||||
pid = fork ();
|
||||
if (pid == -1)
|
||||
{
|
||||
perror ("fork");
|
||||
return EX_ERR;
|
||||
}
|
||||
|
||||
if (pid == 0)
|
||||
{
|
||||
slave = open (ptsname (master), O_RDWR);
|
||||
if (slave < 0)
|
||||
{
|
||||
perror ("open");
|
||||
return EX_ERR;
|
||||
}
|
||||
|
||||
noecho (slave);
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
if (slave != i)
|
||||
{
|
||||
close (i);
|
||||
if (dup (slave) != i)
|
||||
{
|
||||
perror ("dup");
|
||||
_exit (EX_EXEC);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (i = sysconf (_SC_OPEN_MAX) - 1; i > 2; --i)
|
||||
close (i);
|
||||
|
||||
setsid ();
|
||||
#ifdef TIOCSCTTY
|
||||
ioctl (0, TIOCSCTTY, 1);
|
||||
#endif
|
||||
execvp (argv[0], argv);
|
||||
perror (argv[0]);
|
||||
_exit (EX_EXEC);
|
||||
}
|
||||
sleep (1);
|
||||
|
||||
bufinit (ibuf, 1);
|
||||
bufinit (obuf, 1);
|
||||
while (1)
|
||||
{
|
||||
FD_ZERO (&rdset);
|
||||
FD_ZERO (&wrset);
|
||||
|
||||
maxfd = 0;
|
||||
|
||||
if (in != -1)
|
||||
{
|
||||
FD_SET (in, &rdset);
|
||||
if (in > maxfd)
|
||||
maxfd = in;
|
||||
}
|
||||
|
||||
if (master != -1)
|
||||
{
|
||||
FD_SET (master, &rdset);
|
||||
if (!stop)
|
||||
FD_SET (master, &wrset);
|
||||
if (master > maxfd)
|
||||
maxfd = master;
|
||||
}
|
||||
|
||||
if (maxfd == 0)
|
||||
{
|
||||
if (stop)
|
||||
break;
|
||||
pause ();
|
||||
continue;
|
||||
}
|
||||
|
||||
if (select (maxfd + 1, &rdset, &wrset, NULL, NULL) < 0)
|
||||
{
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
perror ("select");
|
||||
return EX_ERR;
|
||||
}
|
||||
|
||||
if (timeout)
|
||||
{
|
||||
time_t now = time (NULL);
|
||||
if (now - ibuf.ts > timeout || now - obuf.ts > timeout)
|
||||
{
|
||||
fprintf (stderr, "ttyemu: I/O timeout\n");
|
||||
return EX_ERR;
|
||||
}
|
||||
}
|
||||
|
||||
if (in >= 0)
|
||||
{
|
||||
if (bufavail (ibuf) && FD_ISSET (in, &rdset))
|
||||
bufread (ibuf, in, 0);
|
||||
}
|
||||
else if (master == -1)
|
||||
break;
|
||||
|
||||
if (master >= 0 && FD_ISSET (master, &wrset))
|
||||
{
|
||||
if (!bufisempty (ibuf))
|
||||
bufwrite (ibuf, master);
|
||||
else if (in == -1 && eot)
|
||||
{
|
||||
DEBUG (("sent EOT"));
|
||||
if (write (master, &eot, 1) <= 0)
|
||||
{
|
||||
perror ("write");
|
||||
return EX_ERR;
|
||||
}
|
||||
eot = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (master >= 0 && bufavail (obuf) && FD_ISSET (master, &rdset))
|
||||
bufread (obuf, master, 1);
|
||||
|
||||
if (bufisempty (obuf))
|
||||
bufinit (obuf, 0);
|
||||
else
|
||||
{
|
||||
tr (&obuf);
|
||||
bufwrite (obuf, out);
|
||||
}
|
||||
|
||||
if (bufisempty (ibuf))
|
||||
bufinit (ibuf, 0);
|
||||
}
|
||||
|
||||
if (WIFEXITED (status))
|
||||
return WEXITSTATUS (status);
|
||||
|
||||
if (WIFSIGNALED (status))
|
||||
fprintf (stderr, "ttyemu: child process %s failed on signal %d\n",
|
||||
argv[0], WTERMSIG (status));
|
||||
else
|
||||
fprintf (stderr, "ttyemu: child process %s failed\n", argv[0]);
|
||||
return EX_EXEC;
|
||||
}
|
||||
Reference in New Issue
Block a user