mirror of
https://repo.or.cz/socat.git
synced 2024-12-22 15:32:35 +00:00
Procan: Try to identify controlling terminal
This commit is contained in:
parent
cd5673dbd0
commit
27877ea777
7 changed files with 314 additions and 36 deletions
4
CHANGES
4
CHANGES
|
@ -193,6 +193,10 @@ Features:
|
||||||
value of SO_PROTOCOL/SO_PROTOTYPE and some other defines, definitions
|
value of SO_PROTOCOL/SO_PROTOTYPE and some other defines, definitions
|
||||||
of many C types, and the actual umask.
|
of many C types, and the actual umask.
|
||||||
|
|
||||||
|
Procan tries to find the name of the controlling terminal, on Linux it
|
||||||
|
reads info from /proc/self/stat and searches for a device with matching
|
||||||
|
major and minor numbers.
|
||||||
|
|
||||||
Corrections:
|
Corrections:
|
||||||
When a sub process (EXEC, SYSTEM) terminated with exit code other than
|
When a sub process (EXEC, SYSTEM) terminated with exit code other than
|
||||||
0, its last sent data might have been lost depending on timing of read/
|
0, its last sent data might have been lost depending on timing of read/
|
||||||
|
|
2
VERSION
2
VERSION
|
@ -1 +1 @@
|
||||||
"1.7.4.5+setpipe"
|
"1.7.4.5+"
|
||||||
|
|
|
@ -684,6 +684,8 @@
|
||||||
#undef HAVE_PROC_DIR_FD
|
#undef HAVE_PROC_DIR_FD
|
||||||
#undef HAVE_PROC_DIR_PATH
|
#undef HAVE_PROC_DIR_PATH
|
||||||
|
|
||||||
|
#undef HAVE_DIRENT_D_TYPE
|
||||||
|
|
||||||
#undef HAVE_RES_RETRANS
|
#undef HAVE_RES_RETRANS
|
||||||
#undef HAVE_RES_RETRY
|
#undef HAVE_RES_RETRY
|
||||||
#undef HAVE_RES_NSADDR_LIST
|
#undef HAVE_RES_NSADDR_LIST
|
||||||
|
|
11
configure.ac
11
configure.ac
|
@ -2191,6 +2191,17 @@ else
|
||||||
AC_MSG_RESULT(no)
|
AC_MSG_RESULT(no)
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# On Solaris family there is not dirent.d_type
|
||||||
|
AC_MSG_CHECKING(for d_type in struct dirent)
|
||||||
|
AC_CACHE_VAL(sc_cv_dirent_d_type,
|
||||||
|
[AC_TRY_COMPILE([#include <dirent.h>],[struct dirent d; d.d_type],
|
||||||
|
[sc_cv_dirent_d_type=yes],
|
||||||
|
[sc_cv_dirent_d_type=no])])
|
||||||
|
if test $sc_cv_dirent_d_type = yes; then
|
||||||
|
AC_DEFINE(HAVE_DIRENT_D_TYPE)
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT($sc_cv_dirent_d_type)
|
||||||
|
|
||||||
# Some OSes have undocumented _res.retrans, _res.retry components
|
# Some OSes have undocumented _res.retrans, _res.retry components
|
||||||
AC_MSG_CHECKING(for _res.retrans)
|
AC_MSG_CHECKING(for _res.retrans)
|
||||||
AC_TRY_COMPILE([#include <resolv.h>],
|
AC_TRY_COMPILE([#include <resolv.h>],
|
||||||
|
|
8
hostan.c
8
hostan.c
|
@ -169,6 +169,7 @@ int hostan(FILE *outfile) {
|
||||||
fprintf(outfile, "typedef unsigned long long off_t; /* sizeof(off_t) = %u */\n", (unsigned int)sizeof(off_t));
|
fprintf(outfile, "typedef unsigned long long off_t; /* sizeof(off_t) = %u */\n", (unsigned int)sizeof(off_t));
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if HAVE_TYPE_OFF64 && defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T
|
||||||
# if HAVE_BASIC_OFF64_T==1
|
# if HAVE_BASIC_OFF64_T==1
|
||||||
fprintf(outfile, "typedef short off64_t; /* sizeof(off64_t) = %u */\n", (unsigned int)sizeof(off64_t));
|
fprintf(outfile, "typedef short off64_t; /* sizeof(off64_t) = %u */\n", (unsigned int)sizeof(off64_t));
|
||||||
#elif HAVE_BASIC_OFF64_T==2
|
#elif HAVE_BASIC_OFF64_T==2
|
||||||
|
@ -186,6 +187,7 @@ int hostan(FILE *outfile) {
|
||||||
#elif HAVE_BASIC_OFF64_T==8
|
#elif HAVE_BASIC_OFF64_T==8
|
||||||
fprintf(outfile, "typedef unsigned long long off64_t; /* sizeof(off64_t) = %u */\n", (unsigned int)sizeof(off64_t));
|
fprintf(outfile, "typedef unsigned long long off64_t; /* sizeof(off64_t) = %u */\n", (unsigned int)sizeof(off64_t));
|
||||||
#endif
|
#endif
|
||||||
|
#endif /* defined(HAVE_BASIC_OFF64_T) && HAVE_BASIC_OFF64_T */
|
||||||
|
|
||||||
# if HAVE_BASIC_DEV_T==1
|
# if HAVE_BASIC_DEV_T==1
|
||||||
fprintf(outfile, "typedef short dev_t; /* sizeof(dev_t) = %u */\n", (unsigned int)sizeof(dev_t));
|
fprintf(outfile, "typedef short dev_t; /* sizeof(dev_t) = %u */\n", (unsigned int)sizeof(dev_t));
|
||||||
|
@ -270,7 +272,7 @@ static int iffan(FILE *outfile) {
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if ((s = Socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) {
|
if ((s = Socket(PF_INET, SOCK_DGRAM, IPPROTO_IP)) < 0) {
|
||||||
Error1("socket(PF_INET, SOCK_DGRAM, IPPROTO_IP): %s", strerror(errno));
|
Warn1("socket(PF_INET, SOCK_DGRAM, IPPROTO_IP): %s", strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -280,7 +282,7 @@ static int iffan(FILE *outfile) {
|
||||||
ic.ifc_len = sizeof(buff);
|
ic.ifc_len = sizeof(buff);
|
||||||
ic.ifc_ifcu.ifcu_buf = (caddr_t)buff;
|
ic.ifc_ifcu.ifcu_buf = (caddr_t)buff;
|
||||||
if (Ioctl(s, SIOCGIFCONF, &ic) < 0) {
|
if (Ioctl(s, SIOCGIFCONF, &ic) < 0) {
|
||||||
Error3("ioctl(%d, SIOCGIFCONF, %p): %s", s, &ic, strerror(errno));
|
Warn3("ioctl(%d, SIOCGIFCONF, %p): %s", s, &ic, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,7 +295,7 @@ static int iffan(FILE *outfile) {
|
||||||
#if 0 || defined(SIOCGIFINDEX) /* not NetBSD, OpenBSD */
|
#if 0 || defined(SIOCGIFINDEX) /* not NetBSD, OpenBSD */
|
||||||
strcpy(ifr.ifr_name, ifp->ifr_name);
|
strcpy(ifr.ifr_name, ifp->ifr_name);
|
||||||
if (Ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
|
if (Ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
|
||||||
Error3("ioctl(%d, SIOCGIFINDEX, {\"%s\"}): %s",
|
Warn3("ioctl(%d, SIOCGIFINDEX, {\"%s\"}): %s",
|
||||||
s, ifr.ifr_name, strerror(errno));
|
s, ifr.ifr_name, strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
183
procan.c
183
procan.c
|
@ -16,38 +16,168 @@
|
||||||
#include "sched.h"
|
#include "sched.h"
|
||||||
#include "filan.h"
|
#include "filan.h"
|
||||||
|
|
||||||
#include <sys/resource.h>
|
#include <sys/resource.h> /* RLIMIT_CPU ... */
|
||||||
|
#include <dirent.h> /* opendir() readdir() closedir() */
|
||||||
|
|
||||||
#include "procan.h"
|
#include "procan.h"
|
||||||
|
|
||||||
|
|
||||||
|
/* Search dir recursively for matching device file.
|
||||||
|
Returns 0 on success;
|
||||||
|
returns -1 when it failed to find the device file. */
|
||||||
|
int find_devpath(
|
||||||
|
char *dirname,
|
||||||
|
unsigned int major,
|
||||||
|
unsigned int minor,
|
||||||
|
char *devname)
|
||||||
|
{
|
||||||
|
DIR *dirp;
|
||||||
|
struct dirent *dirent;
|
||||||
|
char devpath[PATH_MAX];
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
/* Pass 1: search dir flatly for this device entry */
|
||||||
|
dirp = opendir(dirname);
|
||||||
|
if (dirp == NULL) {
|
||||||
|
Warn2("failed to open dir \"%s\": %s", dirname, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
while ((errno = 0) || (dirent = readdir(dirp))) {
|
||||||
|
struct stat statbuf;
|
||||||
|
|
||||||
|
#if HAVE_DIRENT_D_TYPE
|
||||||
|
if (dirent->d_type != DT_CHR && dirent->d_type != DT_UNKNOWN)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
snprintf(devpath, PATH_MAX, "%s/%s", dirname, dirent->d_name);
|
||||||
|
if (Stat(devpath, &statbuf) < 0) {
|
||||||
|
Warn2("failed to stat entry \"%s\": %s", devpath, strerror(errno));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if ((statbuf.st_mode & S_IFMT) != S_IFCHR)
|
||||||
|
continue;
|
||||||
|
if ((statbuf.st_rdev >> 8) == major &&
|
||||||
|
(statbuf.st_rdev & 0xff) == minor) {
|
||||||
|
strcpy(devname, devpath);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
closedir(dirp);
|
||||||
|
if (errno != 0) {
|
||||||
|
Warn2("failed to read dir \"%s\": %s", dirname, strerror(errno));
|
||||||
|
snprintf(devname, PATH_MAX, "device %u, %u", major, minor);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Pass 2: search sub dirs */
|
||||||
|
dirp = opendir(dirname);
|
||||||
|
if (dirp == NULL) {
|
||||||
|
Warn2("failed to open dir \"%s\": %s", dirname, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
while ((errno = 0) || (dirent = readdir(dirp))) {
|
||||||
|
char dirpath[PATH_MAX];
|
||||||
|
#if HAVE_DIRENT_D_TYPE
|
||||||
|
if (dirent->d_type != DT_DIR)
|
||||||
|
continue;
|
||||||
|
#else /* Solaris */
|
||||||
|
{
|
||||||
|
struct stat statbuf;
|
||||||
|
if (Stat(dirent->d_name, &statbuf) < 0)
|
||||||
|
continue;
|
||||||
|
if ((statbuf.st_mode & S_IFMT) != S_IFDIR)
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (!strcmp(dirent->d_name, ".") || !strcmp(dirent->d_name, ".."))
|
||||||
|
continue;
|
||||||
|
snprintf(dirpath, PATH_MAX, "%s/%s", dirname, dirent->d_name);
|
||||||
|
rc = find_devpath(dirpath, major, minor, devname);
|
||||||
|
if (rc == 0) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
closedir(dirp);
|
||||||
|
if (dirent == NULL) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Tries to determine the name of the controlling terminal.
|
||||||
|
Returns 0 on success, the name in cttyname;
|
||||||
|
returns 1 when only the device numbers are in cttyname;
|
||||||
|
returns -1 when it failed to determine ctty. */
|
||||||
|
static int controlling_term(
|
||||||
|
FILE *outfile)
|
||||||
|
{
|
||||||
|
char cttypath[PATH_MAX+1];
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
{ /* On Linux this just gives "/dev/tty" */
|
||||||
|
char s[L_ctermid+1];
|
||||||
|
fprintf(outfile, "controlling terminal by ctermid(): \"%s\"\n", ctermid(s));
|
||||||
|
}
|
||||||
|
|
||||||
|
{ /* Check if there is a controlling terminal */
|
||||||
|
int fd;
|
||||||
|
|
||||||
|
if ((fd = Open("/dev/tty", O_NOCTTY, 0)) >= 0)
|
||||||
|
/* On Linux this just gives "/dev/tty" */
|
||||||
|
fprintf(outfile, "controlling terminal by /dev/tty, ttyname(): \"%s\"\n", Ttyname(fd));
|
||||||
|
else
|
||||||
|
fprintf(outfile, "controlling terminal by /dev/tty, ttyname(): (none)\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
#if HAVE_PROC_DIR
|
||||||
|
do { /* Linux: derive ctty from info in /proc */
|
||||||
|
const char procpath[] = "/proc/self/stat";
|
||||||
|
FILE *procstat;
|
||||||
|
unsigned int dev;
|
||||||
|
int n = 0;
|
||||||
|
unsigned int maj, min;
|
||||||
|
|
||||||
|
/* Linux: get device ids from /proc */
|
||||||
|
if ((procstat = fopen(procpath, "r")) == NULL) {
|
||||||
|
Warn1("failed to open \"%s\" for process info", procpath);
|
||||||
|
rc = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
n = fscanf(procstat, "%*s %*s %*s %*s %*s %*s %u", &dev);
|
||||||
|
if (n != 1) {
|
||||||
|
Warn1("failed to read ctty info from \"%s\"", procpath);
|
||||||
|
rc = -1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
maj = (dev>>8)&0xff;
|
||||||
|
min = ((dev>>12)&0xfff00)|(dev&0xff);
|
||||||
|
rc = find_devpath("/dev" /* _PATH_DEV has trailing "/" */, maj, min, cttypath);
|
||||||
|
if (rc < 0) {
|
||||||
|
snprintf(cttypath, PATH_MAX, "device %u, %u", maj, min);
|
||||||
|
rc = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
rc = 0;
|
||||||
|
} while (false);
|
||||||
|
#else /* !HAVE_PROC_DIR */
|
||||||
|
rc = -1;
|
||||||
|
#endif /* !HAVE_PROC_DIR */
|
||||||
|
if (rc >= 0)
|
||||||
|
fprintf(outfile, "controlling terminal by /proc/<pid>/: \"%s\"\n", cttypath);
|
||||||
|
else
|
||||||
|
fprintf(outfile, "controlling terminal by /proc/<pid>/: (none)\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int procan(FILE *outfile) {
|
int procan(FILE *outfile) {
|
||||||
|
|
||||||
/*filan(0, outfile);*/
|
/*filan(0, outfile);*/
|
||||||
|
|
||||||
/* controlling terminal */
|
|
||||||
fprintf(outfile, "process id = "F_pid"\n", Getpid());
|
fprintf(outfile, "process id = "F_pid"\n", Getpid());
|
||||||
fprintf(outfile, "process parent id = "F_pid"\n", Getppid());
|
fprintf(outfile, "process parent id = "F_pid"\n", Getppid());
|
||||||
{
|
controlling_term(outfile);
|
||||||
int fd;
|
|
||||||
if ((fd = Open("/dev/tty", O_NOCTTY, 0)) < 0) {
|
|
||||||
fprintf(outfile, "controlling terminal: -\n");
|
|
||||||
} else {
|
|
||||||
#if 1
|
|
||||||
fprintf(outfile, "controlling terminal: \"%s\"\n", Ttyname(fd));
|
|
||||||
#else
|
|
||||||
char procpath[PATH_MAX], devpath[PATH_MAX+1];
|
|
||||||
int devlen;
|
|
||||||
sprintf(procpath, "/proc/"F_pid"/fd/%d", Getpid(), 0 /*! fd*/);
|
|
||||||
if ((devlen = Readlink(procpath, devpath, sizeof(devpath))) < 0) {
|
|
||||||
;
|
|
||||||
} else {
|
|
||||||
devpath[devlen] = '\0';
|
|
||||||
fprintf(outfile, "controlling terminal: \"%s\"\n", devpath);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fprintf(outfile, "process group id = "F_pid"\n", Getpgrp());
|
fprintf(outfile, "process group id = "F_pid"\n", Getpgrp());
|
||||||
#if HAVE_GETSID
|
#if HAVE_GETSID
|
||||||
fprintf(outfile, "process session id = "F_pid"\n", Getsid(0));
|
fprintf(outfile, "process session id = "F_pid"\n", Getsid(0));
|
||||||
|
@ -55,15 +185,6 @@ int procan(FILE *outfile) {
|
||||||
fprintf(outfile, "process group id if fg process / stdin = "F_pid"\n", Tcgetpgrp(0));
|
fprintf(outfile, "process group id if fg process / stdin = "F_pid"\n", Tcgetpgrp(0));
|
||||||
fprintf(outfile, "process group id if fg process / stdout = "F_pid"\n", Tcgetpgrp(1));
|
fprintf(outfile, "process group id if fg process / stdout = "F_pid"\n", Tcgetpgrp(1));
|
||||||
fprintf(outfile, "process group id if fg process / stderr = "F_pid"\n", Tcgetpgrp(2));
|
fprintf(outfile, "process group id if fg process / stderr = "F_pid"\n", Tcgetpgrp(2));
|
||||||
{
|
|
||||||
int fd;
|
|
||||||
if ((fd = Open("/dev/tty", O_RDWR, 0600)) >= 0) {
|
|
||||||
fprintf(outfile, "process has a controlling terminal\n");
|
|
||||||
Close(fd);
|
|
||||||
} else {
|
|
||||||
fprintf(outfile, "process does not have a controlling terminal\n");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* process owner, groups */
|
/* process owner, groups */
|
||||||
fprintf(outfile, "user id = "F_uid"\n", Getuid());
|
fprintf(outfile, "user id = "F_uid"\n", Getuid());
|
||||||
|
|
140
test.sh
140
test.sh
|
@ -1148,6 +1148,90 @@ waitip4proto () {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
# Perform a couple of checks to make sure the test has a chance of a useful
|
||||||
|
# result:
|
||||||
|
# platform is supported, features compiled in, addresses and options
|
||||||
|
# available; needs root; is allowed to access the internet
|
||||||
|
checkconds() {
|
||||||
|
local unames="$(echo "$1")" # must be one of... exa: "Linux,FreeBSD"
|
||||||
|
local root="$2" # "root" or ""
|
||||||
|
local progs="$(echo "$3" |tr 'A-Z,' 'a-z ')" # exa: "nslookup"
|
||||||
|
local feats="$(echo "$4" |tr 'a-z,' 'A-Z ')" # list of req.features (socat -V)
|
||||||
|
local addrs="$(echo "$5" |tr 'a-z,' 'A-Z ')" # list of req.addresses (socat -h)
|
||||||
|
local opts="$(echo "$6" |tr 'A-Z,' 'a-z ')" # list of req.options (socat -hhh)
|
||||||
|
local runs="$(echo "$7" |tr , ' ')" # list of req.protocols, exa: "sctp6"
|
||||||
|
local inet="$8" # when "internet": needs allowance
|
||||||
|
local i
|
||||||
|
|
||||||
|
if [ "$unames" ]; then
|
||||||
|
local uname="$(echo $UNAME |tr 'A-Z' 'a-z')"
|
||||||
|
for i in $unames; do
|
||||||
|
if [ "$uname" = "$(echo "$i" |tr 'A-Z,' 'a-z ')" ]; then
|
||||||
|
# good, mark as passed
|
||||||
|
i=
|
||||||
|
break;
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
[ "$i" ] && { echo "Only on (one of) $unames"; return -1; }
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$root" = "root" ]; then
|
||||||
|
if [ $(id -u) -ne 0 -a "$withroot" -eq 0 ]; then
|
||||||
|
echo "Must be root"
|
||||||
|
return -1;
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$progs" ]; then
|
||||||
|
for i in $progs; do
|
||||||
|
if ! type >/dev/null 2>&1; then
|
||||||
|
echo "Program $i not available"
|
||||||
|
return -1
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$feats" ]; then
|
||||||
|
if ! F=$(testfeats $feats); then
|
||||||
|
echo "Feature $F not configured in $SOCAT"
|
||||||
|
return -1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$addrs" ]; then
|
||||||
|
if ! A=$(testaddrs - $addrs); then
|
||||||
|
echo "Address $A not available in $SOCAT"
|
||||||
|
return -1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$opts" ]; then
|
||||||
|
if ! o=$(testoptions $opts); then
|
||||||
|
echo "Option $o not available in $SOCAT"
|
||||||
|
return -1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$runs" ]; then
|
||||||
|
for i in $runs; do
|
||||||
|
if ! runs$i >/dev/null; then
|
||||||
|
echo "$i not available on host"
|
||||||
|
return -1;
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$inet" ]; then
|
||||||
|
if [ -z "$FOREIGN" ]; then
|
||||||
|
echo "Use test.sh option -internet"
|
||||||
|
return -1
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
# we need this misleading function name for canonical reasons
|
# we need this misleading function name for canonical reasons
|
||||||
waitip4port () {
|
waitip4port () {
|
||||||
waitip4proto "$1" "$2" "$3"
|
waitip4proto "$1" "$2" "$3"
|
||||||
|
@ -17567,7 +17651,7 @@ tdiff="$td/test$N.diff"
|
||||||
da="$(echo test$N $(date) $RANDOM |tr ' :' '-')"
|
da="$(echo test$N $(date) $RANDOM |tr ' :' '-')"
|
||||||
echo "$da" >"$td/test$N.da"
|
echo "$da" >"$td/test$N.da"
|
||||||
newport udp4 # or whatever proto, or drop this line
|
newport udp4 # or whatever proto, or drop this line
|
||||||
CMD0="$TRACE $SOCAT $opts -u UDP-RECVFROM:$PORT -"
|
CMD0="$TRACE $SOCAT $opts -u UDP4-RECVFROM:$PORT -"
|
||||||
CMD1="$TRACE $SOCAT $opts - TCP4:$da:0,res-nsaddr=$LOCALHOST:$PORT"
|
CMD1="$TRACE $SOCAT $opts - TCP4:$da:0,res-nsaddr=$LOCALHOST:$PORT"
|
||||||
printf "test $F_n $TEST... " $N
|
printf "test $F_n $TEST... " $N
|
||||||
$CMD0 >/dev/null 2>"${te}0" >"${tf}0" &
|
$CMD0 >/dev/null 2>"${te}0" >"${tf}0" &
|
||||||
|
@ -18700,6 +18784,60 @@ UDPLITE6 UDPLITE udplite [::1] PORT shut-null
|
||||||
"
|
"
|
||||||
|
|
||||||
|
|
||||||
|
# Test the procan controlling terminal output
|
||||||
|
NAME=PROCAN_CTTY
|
||||||
|
case "$TESTS" in
|
||||||
|
*%$N%*|*%functions%*|*%procan%*|*%$NAME%*)
|
||||||
|
TEST="$NAME: test procan controlling terminal output"
|
||||||
|
# Run procan and compare its controlling terminal output with tty (oops)"
|
||||||
|
if ! eval $NUMCOND; then :
|
||||||
|
elif ! cond=$(checkconds \
|
||||||
|
"" \
|
||||||
|
"" \
|
||||||
|
"tty" \
|
||||||
|
"" \
|
||||||
|
"" \
|
||||||
|
"" \
|
||||||
|
"" ); then
|
||||||
|
$PRINTF "test $F_n $TEST... ${YELLOW}$cond${NORMAL}\n" $N
|
||||||
|
numCANT=$((numCANT+1))
|
||||||
|
listCANT="$listCANT $N"
|
||||||
|
else
|
||||||
|
tf="$td/test$N.stdout"
|
||||||
|
te="$td/test$N.stderr"
|
||||||
|
tdiff="$td/test$N.diff"
|
||||||
|
CMD0="$TRACE $PROCAN"
|
||||||
|
printf "test $F_n $TEST... " $N
|
||||||
|
$CMD0 >"${tf}0" 2>"${te}0"
|
||||||
|
rc0=$?
|
||||||
|
if [ "$rc0" -ne 0 ]; then
|
||||||
|
$PRINTF "$FAILED\n"
|
||||||
|
echo "$CMD0"
|
||||||
|
cat "${te}0" >&2
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
namesFAIL="$namesFAIL $NAME"
|
||||||
|
elif ! tty |diff - <(cat ${tf}0 |grep "controlling terminal" |grep -v -e '"/dev/tty"' -e none |head -n 1 |sed -e 's/controlling terminal by .*:[[:space:]]*//' -e 's/"//g') >$tdiff; then
|
||||||
|
$PRINTF "$FAILED\n"
|
||||||
|
echo "$CMD0"
|
||||||
|
cat "${te}0" >&2
|
||||||
|
echo "// diff:" >&2
|
||||||
|
cat "$tdiff" >&2
|
||||||
|
numFAIL=$((numFAIL+1))
|
||||||
|
listFAIL="$listFAIL $N"
|
||||||
|
namesFAIL="$namesFAIL $NAME"
|
||||||
|
else
|
||||||
|
$PRINTF "$OK\n"
|
||||||
|
if [ "$VERBOSE" ]; then echo "$CMD0"; fi
|
||||||
|
if [ "$DEBUG" ]; then cat "${te}0" >&2; fi
|
||||||
|
numOK=$((numOK+1))
|
||||||
|
fi
|
||||||
|
fi # NUMCOND
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
N=$((N+1))
|
||||||
|
|
||||||
|
|
||||||
# end of common tests
|
# end of common tests
|
||||||
|
|
||||||
##################################################################################
|
##################################################################################
|
||||||
|
|
Loading…
Reference in a new issue