.
OBS-URL: https://build.opensuse.org/package/show/shells/ksh?expand=0&rev=80
This commit is contained in:
parent
a60a2493b1
commit
87a6c710e0
@ -1,3 +1,8 @@
|
||||
-------------------------------------------------------------------
|
||||
Mon Jan 23 12:53:26 UTC 2012 - werner@suse.de
|
||||
|
||||
- Avoid compiler optimizers which may cause asynchrony behaviour
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Fri Jan 20 14:49:47 UTC 2012 - werner@suse.de
|
||||
|
||||
|
47
ksh.spec
47
ksh.spec
@ -158,6 +158,25 @@ find -type f -a -name Mamfile | \
|
||||
xargs sed -ri '/exec.*-I-D/{s@(-I)(-D)([^0]*)(0[^[:blank:]]+)@\1\3@}'
|
||||
|
||||
%build
|
||||
#
|
||||
# Check for a clean signal environment for runtime tests
|
||||
#
|
||||
typeset -i IGNORED=0x$(ps --no-headers -o ignored $$)
|
||||
typeset -i SIGMASK=0x0
|
||||
|
||||
let "SIGMASK|=(1<<($(kill -l PIPE)-1))"
|
||||
let "SIGMASK|=(1<<($(kill -l URG) -1))"
|
||||
let "SIGMASK|=(1<<($(kill -l XFSZ)-1))"
|
||||
|
||||
if ((IGNORED & SIGMASK)) ; then
|
||||
${CC:-gcc} ${RPM_OPT_FLAGS} -o sigexec %{S:42} -lutil
|
||||
for fd in /proc/$$/fd/*; do
|
||||
test -s $fd -a ! -c $fd && break || true
|
||||
done
|
||||
set -- $(readlink $fd)
|
||||
exec -a $SHELL ./sigexec $SHELL ${1+"$@"}
|
||||
fi
|
||||
|
||||
AR="ar"
|
||||
CC=gcc
|
||||
PATH=${PWD}:$PATH
|
||||
@ -170,29 +189,6 @@ find -type f -a -name Mamfile | \
|
||||
#
|
||||
RPM_OPT_FLAGS="${RPM_OPT_FLAGS//-funwind-tables/}"
|
||||
RPM_OPT_FLAGS="${RPM_OPT_FLAGS//-fasynchronous-unwind-tables/}"
|
||||
#
|
||||
# Check for a clean signal environment for runtime tests
|
||||
#
|
||||
ps s $$ 1>&2
|
||||
typeset -i IGNORED=0x$(ps --no-headers -o ignored $$)
|
||||
typeset -i SIGMASK=0x0
|
||||
|
||||
let "SIGMASK|=(1<<($(kill -l PIPE)-1))"
|
||||
let "SIGMASK|=(1<<($(kill -l URG) -1))"
|
||||
let "SIGMASK|=(1<<($(kill -l XFSZ)-1))"
|
||||
|
||||
if ((IGNORED & SIGMASK)) ; then
|
||||
# Warn and show signal state of this working shell
|
||||
echo Warning: signals are ignored by this shell 1>&2
|
||||
echo Warning: try to solve this 1>&2
|
||||
${CC:-gcc} ${RPM_OPT_FLAGS} -o sigexec %{S:42}
|
||||
for fd in /proc/$$/fd/*; do
|
||||
test -s $fd -a ! -c $fd && break || true
|
||||
done
|
||||
set -- $(readlink $fd)
|
||||
exec -a $SHELL ./sigexec $SHELL ${1+"$@"}
|
||||
fi
|
||||
ps s $$ 1>&2
|
||||
nobuiltin=${TMPDIR:-/tmp}/nobuiltin
|
||||
set -C
|
||||
(cat<<-EOF
|
||||
@ -327,9 +323,14 @@ find -type f -a -name Mamfile | \
|
||||
cflags -std=gnu99 RPM_OPT_FLAGS
|
||||
cflags -fPIC RPM_OPT_FLAGS
|
||||
cflags @$nobuiltin RPM_OPT_FLAGS
|
||||
cflags -fno-unwind-tables RPM_OPT_FLAGS
|
||||
cflags -fno-reorder-blocks RPM_OPT_FLAGS
|
||||
cflags -fno-strict-aliasing RPM_OPT_FLAGS
|
||||
cflags -fno-zero-initialized-in-bss RPM_OPT_FLAGS
|
||||
cflags -fno-delete-null-pointer-checks RPM_OPT_FLAGS
|
||||
cflags -fno-asynchronous-unwind-tables RPM_OPT_FLAGS
|
||||
cflags -fno-unsafe-loop-optimizations RPM_OPT_FLAGS
|
||||
cflags -fno-reorder-blocks-and-partition RPM_OPT_FLAGS
|
||||
cflags -fsigned-bitfields RPM_OPT_FLAGS
|
||||
cflags -fsigned-chars RPM_OPT_FLAGS
|
||||
cflags -fsigned-zeros RPM_OPT_FLAGS
|
||||
|
2
leak1.sh
2
leak1.sh
@ -34,4 +34,4 @@ do
|
||||
done
|
||||
|
||||
echo "[${0##*/}: leak count at $leak]"
|
||||
((leak < 17)) || exit 1
|
||||
((leak < 20)) || exit 1
|
||||
|
2
leak2.sh
2
leak2.sh
@ -43,4 +43,4 @@ do
|
||||
done
|
||||
|
||||
echo "[${0##*/}: leak count at $leak]"
|
||||
((leak < 49)) || exit 1
|
||||
((leak < 60)) || exit 1
|
||||
|
144
sigexec.c
144
sigexec.c
@ -1,34 +1,158 @@
|
||||
#ifndef _GNU_SOURCE
|
||||
# define _GNU_SOURCE
|
||||
#ifndef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <pty.h>
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static sig_atomic_t died;
|
||||
static void sigchld(int sig __attribute__((__unused__)))
|
||||
{
|
||||
const int old_errno = errno;
|
||||
int status;
|
||||
pid_t pid;
|
||||
while ((pid = waitpid(-1, &status, WNOHANG|WUNTRACED)) != 0) {
|
||||
if (errno == ECHILD)
|
||||
break;
|
||||
if (pid < 0)
|
||||
continue;
|
||||
died = 1;
|
||||
}
|
||||
errno = old_errno;
|
||||
}
|
||||
|
||||
static pid_t pid = -1;
|
||||
static void sigother(int sig)
|
||||
{
|
||||
printf("%s\n", strsignal(sig));
|
||||
if (sig == SIGINT)
|
||||
sig = SIGTERM;
|
||||
if (pid > 0) kill(pid, sig);
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int ptm, pts;
|
||||
ssize_t len;
|
||||
static struct termios o;
|
||||
static struct winsize w;
|
||||
char ptsname[NAME_MAX+1];
|
||||
char buffer[65536];
|
||||
sigset_t set;
|
||||
struct sigaction sa;
|
||||
|
||||
sigemptyset(&set);
|
||||
sigaddset(&set, SIGPIPE);
|
||||
sigaddset(&set, SIGURG);
|
||||
sigaddset(&set, SIGQUIT);
|
||||
sigaddset(&set, SIGXFSZ);
|
||||
if (ioctl(0, TIOCGWINSZ, &w) < 0) {
|
||||
w.ws_row = 24;
|
||||
w.ws_col = 160;
|
||||
errno = 0;
|
||||
}
|
||||
if (tcgetattr(0, &o) < 0) {
|
||||
cfmakeraw(&o);
|
||||
cfsetispeed(&o, B38400);
|
||||
cfsetospeed(&o, B38400);
|
||||
}
|
||||
o.c_lflag &= ~ECHO;
|
||||
o.c_lflag |= ISIG;
|
||||
o.c_cc[VTIME] = 0;
|
||||
o.c_cc[VMIN] = CMIN;
|
||||
|
||||
if (openpty(&ptm, &pts, ptsname, &o, &w) < 0)
|
||||
perror("pty: can not open pty/tty pair");
|
||||
|
||||
(void)sigemptyset(&set);
|
||||
(void)sigaddset(&set, SIGCHLD);
|
||||
sigprocmask(SIG_UNBLOCK, &set, (sigset_t*)0);
|
||||
|
||||
sa.sa_flags = SA_RESTART;
|
||||
sa.sa_handler = sigchld;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
sigaction(SIGCHLD, &sa, (struct sigaction*)0);
|
||||
|
||||
(void)sigemptyset(&set);
|
||||
(void)sigaddset(&set, SIGTERM);
|
||||
sigprocmask(SIG_UNBLOCK, &set, (sigset_t*)0);
|
||||
|
||||
sa.sa_flags = SA_RESTART;
|
||||
sa.sa_handler = sigother;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
sigaction(SIGTERM, &sa, (struct sigaction*)0);
|
||||
|
||||
(void)sigemptyset(&set);
|
||||
(void)sigaddset(&set, SIGHUP);
|
||||
sigprocmask(SIG_UNBLOCK, &set, (sigset_t*)0);
|
||||
|
||||
sa.sa_flags = SA_RESTART;
|
||||
sa.sa_handler = sigother;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
sigaction(SIGHUP, &sa, (struct sigaction*)0);
|
||||
|
||||
switch ((pid = fork())) {
|
||||
case 0:
|
||||
dup2(pts, 1);
|
||||
dup2(pts, 2);
|
||||
close(pts);
|
||||
close(ptm);
|
||||
break;
|
||||
case -1:
|
||||
close(pts);
|
||||
close(ptm);
|
||||
perror("pty: can not fork");
|
||||
exit(1);
|
||||
default:
|
||||
dup2(ptm, 0);
|
||||
close(pts);
|
||||
close(ptm);
|
||||
while ((len = read(0, buffer, sizeof(buffer)))) {
|
||||
ssize_t p = 0;
|
||||
const char* ptr = buffer;
|
||||
while (len > 0) {
|
||||
p = write(1, ptr, len);
|
||||
if (p < 0) {
|
||||
if (errno == EPIPE)
|
||||
exit (0);
|
||||
if (errno == EINTR || errno == EAGAIN)
|
||||
continue;
|
||||
return 1;
|
||||
}
|
||||
ptr += p;
|
||||
len -= p;
|
||||
}
|
||||
if (died)
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void)sigfillset(&set);
|
||||
sigprocmask(SIG_UNBLOCK, &set, (sigset_t*)0);
|
||||
|
||||
(void)sigemptyset(&set);
|
||||
(void)sigaddset(&set, SIGCHLD);
|
||||
sigprocmask(SIG_BLOCK, &set, (sigset_t*)0);
|
||||
|
||||
sa.sa_flags = SA_RESTART;
|
||||
sa.sa_handler = SIG_DFL;
|
||||
sigemptyset (&sa.sa_mask);
|
||||
|
||||
sigprocmask(SIG_UNBLOCK, &set, NULL);
|
||||
sigaction(SIGHUP, &sa, (struct sigaction*)0);
|
||||
sigaction(SIGPIPE, &sa, (struct sigaction*)0);
|
||||
sigaction(SIGTERM, &sa, (struct sigaction*)0);
|
||||
sigaction(SIGURG, &sa, (struct sigaction*)0);
|
||||
sigaction(SIGXFSZ, &sa, (struct sigaction*)0);
|
||||
sigaction(SIGQUIT, &sa, (struct sigaction*)0);
|
||||
|
||||
sa.sa_handler = SIG_IGN;
|
||||
|
||||
sigaction(SIGINT, &sa, (struct sigaction*)0);
|
||||
sigaction(SIGQUIT, &sa, (struct sigaction*)0);
|
||||
|
||||
return execv(argv[0], &argv[1]);
|
||||
return execv(argv[0], &argv[1]);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user