ra@is.uu.no (Robert Andersson) (09/04/89)
I have spent today getting bash 1.03 up and running on my NCR Tower running SYSV.2. It was *not* as easy as I hoped. Anyway, here's various comments and questions that arised from the exercise. At the end you will also find some diff's. Bash is really promising, but still needs some work. Not surprising, given its young age. Keep up the good work Brian. 1. Some files had names > 14 chars, SYSV doesn't handle this :-( Not a big deal, but you might want to rename them. longest_signal_name.c (What's the point in this program anyway?) readline/*.texinfo 2. readline/readline.c Signal handling is disabled for SYSV , ie. SIGINT and SIGQUIT is turned off at the terminal driver level. Why? I can fix this easily but wondered if there was any real reason for this. If FIONREAD was not defined rl_gather_tyi failed to compile. Definitions of getpwuid() and getpwent() were wrong. readline_default_binding did not have code for SYSV termio-style ioctls. See context diffs at the end. I still have one unresolved problem in readline: rl_gather_tyi loses every second character of typeahead if FIONREAD is not defined. I believe it is caused by the two lines, if (tem < ibuffer_len) char_avail = 0; but it's not quite clear what should be done instead. 3. builtins.c The helptexts for 'test' and 'set' break the limit on text literal length in my C-compiler. I expect the same to happen on a number of other compilers. What does the pANS say about this? Anyway, you might consider doing this differently for maximum portability. 4. builtins.c Neither of the two 'echo' implementations are SYSV compatible. 5. general.c Should not define the functions bcopy, index and rindex for SYSV. Use macros mapping them to memcpy, strchr and strrchr in one of the .h files instead. jobs.c makes an attempt at this, but does it based on a USG #if conditional, and USG is defined nowhere. 6. jobs.h The #if's should probably be rearranged so that SYSV machines as a default defines union wait etc. 7. Makefile The rule for $(TERMCAP) caused make to enter an endless loop. I simply removed the dependencies and rules for this target. 8. documentation/bash.texinfo Emacs 18.54 texinfo-format-buffer fails to format this one. The line "foo @result{} bar" gives the error message: @result is not handled by texinfo 9. nojobs.c Only had BSD-style ioctls in get_tty_state and set_tty_state. Merged in a lot of changes that apperead to only have been done in jobs.c. See context diffs at the end. -- Robert Andersson, International Systems, Oslo, Norway Internet: ra@is.uu.no UUCP: ...!{uunet,mcvax,ifi}!is.uu.no!ra *** orig/nojobs.c Sat Sep 2 18:54:08 1989 --- ./nojobs.c Sun Sep 3 21:18:30 1989 *************** *** 26,37 **** --- 26,47 ---- #include "config.h" #include "general.h" #include "jobs.h" + #include "quit.h" #ifndef SIGABRT #define SIGABRT SIGIOT #endif + #define NEW_TTY_DRIVER + #if defined (SYSV) || defined(hpux) + #undef NEW_TTY_DRIVER + #include <termio.h> + #else + #include <sgtty.h> + #endif + #ifndef SYSV + #include <sys/file.h> #include <sys/time.h> #include <sys/resource.h> /* The total amount of system time spent running processes for me. */ *************** *** 43,48 **** --- 53,60 ---- struct timeval total_usertime = {0, 0}; long user_minutes_used = 0; int user_seconds_used = 0; + #else + #include <fcntl.h> #endif int last_made_pid; *************** *** 53,58 **** --- 65,71 ---- */ initialize_jobs () { + get_tty_state (); } /* *************** *** 92,100 **** --- 105,125 ---- int async_p; { int pid; + #ifdef SYSV + SigHandler *old_int; + #else + int oldmask; + #endif /* Discard saved memory. */ free (command); + command = (char *)NULL; + + #ifdef SYSV + old_int = signal (SIGINT, SIG_IGN); + #else + oldmask = sigblock (sigmask (SIGINT)); + #endif /* Make new environment array if neccessary. */ maybe_make_export_env (); *************** *** 102,107 **** --- 127,139 ---- /* Create the child, handle severe errors. */ if ((pid = fork ()) < 0) { + sighandler throw_to_top_level (); + + #ifdef SYSV + (void) signal (SIGINT, old_int); + #else + sigsetmask (oldmask); + #endif report_error ("Memory exhausted or process overflow!"); throw_to_top_level (); } *************** *** 108,113 **** --- 140,147 ---- if (!pid) { + signal (SIGTERM, SIG_DFL); + /* * Ignore INT and QUIT in asynchronous children. */ *************** *** 129,142 **** * In the parent. */ last_made_pid = pid; - remember_pid (pid); - if (async_p) last_asynchronous_pid = pid; } return (pid); } /* * Wait for pid (one of our children) to terminate. */ --- 163,213 ---- * In the parent. */ last_made_pid = pid; if (async_p) last_asynchronous_pid = pid; + #ifdef SYSV + (void) signal (SIGINT, old_int); + #endif } + #ifndef SYSV + sigsetmask (oldmask); + #endif return (pid); } + wait_for_single_pid (pid) + int pid; + { + int got_pid; + union wait status; + + while ((got_pid = wait (&status)) != pid) + { + if (got_pid < 0) + { + if (errno != EINTR && errno != ECHILD) + file_error ("wait"); + break; + } + QUIT; + } + QUIT; + } + + wait_for_background_pids () + { + int got_pid; + union wait status; + + got_pid = wait (&status); + if (got_pid < 0) + { + if (errno != EINTR && errno != ECHILD) + file_error ("wait"); + } + QUIT; + } + /* * Wait for pid (one of our children) to terminate. */ *************** *** 143,175 **** wait_for (pid) int pid; { ! int got_pid, return_val, oldmask; union wait status; - #ifndef SYSV - SigHandler *old_int, *old_quit; - #endif - - #ifdef SYSV - oldmask = sigignore (SIGINT); - #else - oldmask = sigblock (sigmask (SIGINT)); - #endif while ((got_pid = wait (&status)) != pid) { if (got_pid < 0 && errno != EINTR) ! programming_error ("got errno %d while waiting for %d", errno, pid); } - #ifdef SYSV - sigrelse (oldmask); - #else - sigsetmask (oldmask); - #endif - /* Default return value. */ return_val = status.w_retcode & 0x7f; if (status.w_termsig != 0 && status.w_termsig != WSTOPPED) { extern char *sys_siglist[]; --- 214,239 ---- wait_for (pid) int pid; { ! int got_pid, return_val; union wait status; while ((got_pid = wait (&status)) != pid) { if (got_pid < 0 && errno != EINTR) ! file_error ("wait"); } /* Default return value. */ return_val = status.w_retcode & 0x7f; + /* If the command did not exit cleanly, or the job is just + being stopped, then reset the tty state back to what it + was before this command. */ + if (status.w_termsig != 0 || WIFSTOPPED (status)) + set_tty_state (); + else + get_tty_state (); + if (status.w_termsig != 0 && status.w_termsig != WSTOPPED) { extern char *sys_siglist[]; *************** *** 178,184 **** fprintf (stderr, " (core dumped)"); fprintf (stderr, "\n"); return_val = status.w_termsig + 128; - get_tty_state (); } return (return_val); } --- 242,247 ---- *************** *** 186,192 **** --- 249,259 ---- /* When we end a job abnormally, or if we stop a job, we set the tty to the state kept in here. When a job ends normally, we set the state in here to the state of the tty. */ + #ifdef NEW_TTY_DRIVER static struct sgttyb shell_tty_info; + #else + static struct termio shell_tty_info; + #endif /* Fill the contents of shell_tty_info with the current tty info. */ get_tty_state () *************** *** 194,200 **** --- 261,271 ---- int tty = open ("/dev/tty", O_RDONLY); if (tty != -1) { + #ifdef NEW_TTY_DRIVER ioctl (tty, TIOCGETP, &shell_tty_info); + #else + ioctl (tty, TCGETA, &shell_tty_info); + #endif close (tty); } } *************** *** 205,211 **** --- 276,286 ---- int tty = open ("/dev/tty", O_RDONLY); if (tty != -1) { + #ifdef NEW_TTY_DRIVER ioctl (tty, TIOCSETN, &shell_tty_info); + #else + ioctl (tty, TCSETAW, &shell_tty_info); + #endif close (tty); } } *** orig/readline.c Sat Sep 2 18:54:16 1989 --- readline/readline.c Sat Sep 2 19:31:55 1989 *************** *** 60,66 **** #include <pwd.h> #ifdef SYSV ! struct pwd *getpwuid (), *getpwent (); #endif #define HACK_TERMCAP_MOTION --- 60,66 ---- #include <pwd.h> #ifdef SYSV ! struct passwd *getpwuid (), *getpwent (); #endif #define HACK_TERMCAP_MOTION *************** *** 526,536 **** #ifdef FIONREAD ioctl (tty, FIONREAD, &chars_avail); #else ! fcntl (tty, F_SETFL, O_NDELAY); chars_avail = read (tty, &input, 1); ! if (chars_avail == -1 && errno == EAGAIN) return; - fcntl (fileno (stdin), F_SETFL, 0); #endif tem = ibuffer_space (); --- 526,536 ---- #ifdef FIONREAD ioctl (tty, FIONREAD, &chars_avail); #else ! fcntl (tty, F_SETFL, fcntl(tty, F_GETFL, 0) | O_NDELAY); chars_avail = read (tty, &input, 1); ! fcntl (tty, F_SETFL, fcntl(tty, F_GETFL, 0) & ~O_NDELAY); ! if (chars_avail < 1) return; #endif tem = ibuffer_space (); *************** *** 686,691 **** --- 686,692 ---- equivalents. */ readline_default_bindings () { + #ifdef NEW_TTY_DRIVER #ifdef TIOCGETP struct sgttyb ttybuff; int tty = fileno (rl_instream); *************** *** 708,713 **** --- 709,725 ---- } #endif /* TIOCGLTC */ #endif /* TIOCGETP */ + #else /* !defined (NEW_TTY_DRIVER) */ + struct termio ttybuff; + int tty = fileno (rl_instream); + + if (ioctl (tty, TCGETA, &ttybuff) != -1) + { + keymap[ttybuff.c_cc[VERASE]] = rl_rubout; + keymap[ttybuff.c_cc[VKILL]] = rl_unix_line_discard; + } + + #endif /* NEW_TTY_DRIVER */ }