[gnu.bash.bug] bash 1.03 misc on SYSV.3 386

tony@UUNET.UU.NET (10/06/89)

Howdy;

    (I've just started using bash, so some of my comments may have already
    been discussed on gnu.bash.bug [which I've just begun reading]).

    My environment is:

    	bash 1.03
    	386 UNIX V.3  (essentially 386/ix 1.0.6) on a Multibus I 386
    	    machine -- For all intents and purposes equiv to an AT-386.
    	gcc 1.36 (tho not using gas)

    I now have bash up and running.  I encountered several problems that
    seem to all be SYSV related, and especially related to job control.

      . terminal mode handling is not SYSV appropriate.  TIOC[SG]ETP
    	    are used exclusively, instead of the SYSV ioctl TCSETAW, et.al.
    	    This wasn't much of a problem as our UNIX port emulates
    	    TIOC[SG]ETP.  Others might not be so lucky.  The readline code
    	    seems to use TCSETAW as appropriate.

      . file nojobs.c missing include's for 'sgtty.h' and 'fcntl.h'

      . file jobs.c missing include's for 'sys/types.h', 'sys/times.h',
    	    and 'fcntl.h'

      . file nojobs.c basically wouldn't compile/link due to
    	    functions missing:

    	    - remember_pid() doesn't exist
    	    - builtins.c ref's wait_for_background_pids() and
    	    	wait_for_single_pid() which aren't provided in nojobs.c

      . make clean doesn't descend into readline subdir properly

      . SIGCHLD is SIGCLD on SYSV (no 'H')

      . sigblock, sigsetmask were #ifdef'd SYSV to sighold() and
    	    sigrelse().

      . since nojobs.c wouldn't work, I decided to use jobs.c and just
    	    init job_control variable to 0 instead of 1.  This prevents
    	    the code from doing all the job control activity that isn't
    	    supported (unfortunately) on SYSV.  So then it just became a
    	    matter of getting the stuff to compile.  I did that by adding
    	    to config.h the following:

		#ifdef sci386   	    -- my machine
		#define JOB_CONTROL
		#define SIGCHLD SIGCLD
		#define SIGCONT (-99)
		#define SIGTSTP (-100)
		#define SIGTTOU (-101)
		#define SIGTTIN (-102)
		#define TIOCSETN TIOCSETP
		#define TIOCSPGRP (-299)
		#define TIOCGETD (-300)
		#define TIOCSETD (-301)
		#define NTTYDISC (-400)
		#define killpg  kill
		#endif

    	    [I probably should have also dealt with wait3(), sigblock(),
    	    and sigsetmask() here.]

    	    This allowed it to compile, and it seems to work fine.

       .  'times' builtin isn't correct for SYSV.
    	    Code in builtins.c seems to assume that times(2) (for SYSV)
    	    returns values in seconds.  On V.3, it returns values in
    	    clock ticks (HZ from param.h).  I decided to fix this in
    	    add_times() so as to update {user,system}_{minutes,seconds}_used
    	    as per:

    	    	#ifdef sci386
		    struct tms total_times;
		    time_t seconds;

		    (void) times(&total_times);
		    total_times.tms_utime += total_times.tms_cutime;
		    total_times.tms_stime += total_times.tms_cstime;

		    seconds = total_times.tms_cstime;
		    seconds += HZ - 1;
		    seconds /= HZ;
		    system_minutes_used = seconds / 60;
		    system_seconds_used = seconds % 60;

		    seconds = total_times.tms_cutime;
		    seconds += HZ - 1;
		    seconds /= HZ;
		    user_minutes_used = seconds / 60;
		    user_seconds_used = seconds % 60;
    	    	#endif

    	    Then times_builtin() became as follows (just removed old
    	    times(2) stuff:

	    times_builtin (list)
		 WORD_LIST *list;
	    {
	      extern long system_minutes_used, user_minutes_used;
	      extern int system_seconds_used, user_seconds_used;

	      no_args ("times", list);

	    #ifdef SYSV
	      /*
	       * For SYSV we can call add_times() at any time since the
    	       *  kernel does the child time summations for us.
	       */
	      add_times();	    	    /* SYSV version has no arg */
	    #endif

	      printf ("%0dm%0ds %0dm%0ds\n", system_minutes_used,
    	    	    	    	    	     system_seconds_used,
					     user_minutes_used,
    	    	    	    	    	     user_seconds_used);
	    }


    	. In glob.c, were missing a check for __GNUC__'s
    	    	__builtin_alloca.  The line 'extern char *alloca();'
    	    	caused a problem.

    	. jobs.c calls wait3() which doesn't exist on SYSV.  Changed
    	    	to wait().  [flush_child is never called, since job_control
    	    	is 0, however]

    	. readline/readline.c needed #include <errno.h>

    	. on SYSV.3 signal handlers return void function pointers.
    	    	(changed in general.h)

    	. initialized 'do_v9' in echo_builtin() to 1 to be more compatible
    	    	with SYSV /bin/echo.

    Overall, bash looks really good.  Minor complaints are that it is 
    somewhat slower on shell script interpretation than /bin/sh and it
    is much bigger (3x code size).  A sample timing for my .profile
    (which is overly complex):

    	time /bin/sh .profile
    	    real        4.0
    	    user        0.8
    	    sys         1.7

    	time bin/bash .profile
    	    real       14.2
    	    user        6.5
    	    sys         5.8

    Not sure what to attribute the time diffs to.  I tried running prof(1),
    with mixed results.  Our version of prof seemed to chop up long routine
    names, so I don't really trust it, but here are the first few lines 
    from a prof(1) session corresponding to the time'd results above:

       %Time Seconds Cumsecs  #Calls   msec/call  Name
	21.1    0.04    0.04     307      0.14    malloc
	19.0    0.04    0.08       2     20.      fork
	 9.5    0.02    0.10    2513      0.008   strcmp
	 9.5    0.02    0.12       2     10.      stat
	 4.8    0.01    0.13       1     10.      initialize_hash_table
	 4.8    0.01    0.14                      brk
	 4.8    0.01    0.15       2      5.      et_next_history
	 4.8    0.01    0.16       2      5.      sighold
	 4.8    0.01    0.17       2      5.      pipe
	 4.8    0.01    0.18      85      0.1     free
	 4.8    0.01    0.19     130      0.08    ase_version
	 2.7    0.01    0.20                      malloc_usable_size

    My guess is that fork() of a larger proc is what is making shell
    scripts slower.

    Minor, tentative, wish list:

    	visible bell in ding()
    	filename completion should expand shell variables, ie:
    	    $s/gnu/b<TAB>
    	should expand to either:
    	    $s/gnu/bash
    	or to:
    	    /ut/tony/src/gnu/bash

    Gets error on SYSV basename which is a shellscript using expr(1).
    Haven't looked into this much yet, but the execve() fails with
    errno == ENOEXEC and bash proceeds to determine that expr (?) is
    binary and thus can't be interpreted.
    Here is the line from basename that seems to be the problem:
    	 /bin/expr \
	    "/${1:-.}" : '\(.*[^/]\)/*$' : '.*/\(..*\)' : "\\(.*\\)$2\$"  \|  \
	    "/${1:-.}" : '\(.*[^/]\)/*$' : '.*/\(..*\)'    \|  \
	    "/${1:-.}" : '.*/\(..*\)'

    Running expr with a simpler argument works ok.

    Please let me know if I can provide any help or more information.

    Thanks.

--tony	 ...!uunet!h-three!tony	 (919) 549-8334	 h-three  Systems  Corporation
	 h-three!tony@uunet.uu.net		 POB 12557; RTP, NC 27709; USA
	 t. e. bennett				 FAX: (919) 549-9868

tony@UUNET.UU.NET (10/06/89)

[retransmission, mail didn't go thru uunet!ai.mit.edu --tony]

Howdy;

    (I've just started using bash, so some of my comments may have already
    been discussed on gnu.bash.bug [which I've just begun reading]).

    My environment is:

    	bash 1.03
    	386 UNIX V.3  (essentially 386/ix 1.0.6) on a Multibus I 386
    	    machine -- For all intents and purposes equiv to an AT-386.
    	gcc 1.36 (tho not using gas)

    I now have bash up and running.  I encountered several problems that
    seem to all be SYSV related, and especially related to job control.

      . terminal mode handling is not SYSV appropriate.  TIOC[SG]ETP
    	    are used exclusively, instead of the SYSV ioctl TCSETAW, et.al.
    	    This wasn't much of a problem as our UNIX port emulates
    	    TIOC[SG]ETP.  Others might not be so lucky.  The readline code
    	    seems to use TCSETAW as appropriate.

      . file nojobs.c missing include's for 'sgtty.h' and 'fcntl.h'

      . file jobs.c missing include's for 'sys/types.h', 'sys/times.h',
    	    and 'fcntl.h'

      . file nojobs.c basically wouldn't compile/link due to
    	    functions missing:

    	    - remember_pid() doesn't exist
    	    - builtins.c ref's wait_for_background_pids() and
    	    	wait_for_single_pid() which aren't provided in nojobs.c

      . make clean doesn't descend into readline subdir properly

      . SIGCHLD is SIGCLD on SYSV (no 'H')

      . sigblock, sigsetmask were #ifdef'd SYSV to sighold() and
    	    sigrelse().

      . since nojobs.c wouldn't work, I decided to use jobs.c and just
    	    init job_control variable to 0 instead of 1.  This prevents
    	    the code from doing all the job control activity that isn't
    	    supported (unfortunately) on SYSV.  So then it just became a
    	    matter of getting the stuff to compile.  I did that by adding
    	    to config.h the following:

		#ifdef sci386   	    -- my machine
		#define JOB_CONTROL
		#define SIGCHLD SIGCLD
		#define SIGCONT (-99)
		#define SIGTSTP (-100)
		#define SIGTTOU (-101)
		#define SIGTTIN (-102)
		#define TIOCSETN TIOCSETP
		#define TIOCSPGRP (-299)
		#define TIOCGETD (-300)
		#define TIOCSETD (-301)
		#define NTTYDISC (-400)
		#define killpg  kill
		#endif

    	    [I probably should have also dealt with wait3(), sigblock(),
    	    and sigsetmask() here.]

    	    This allowed it to compile, and it seems to work fine.

       .  'times' builtin isn't correct for SYSV.
    	    Code in builtins.c seems to assume that times(2) (for SYSV)
    	    returns values in seconds.  On V.3, it returns values in
    	    clock ticks (HZ from param.h).  I decided to fix this in
    	    add_times() so as to update {user,system}_{minutes,seconds}_used
    	    as per:

    	    	#ifdef sci386
		    struct tms total_times;
		    time_t seconds;

		    (void) times(&total_times);
		    total_times.tms_utime += total_times.tms_cutime;
		    total_times.tms_stime += total_times.tms_cstime;

		    seconds = total_times.tms_cstime;
		    seconds += HZ - 1;
		    seconds /= HZ;
		    system_minutes_used = seconds / 60;
		    system_seconds_used = seconds % 60;

		    seconds = total_times.tms_cutime;
		    seconds += HZ - 1;
		    seconds /= HZ;
		    user_minutes_used = seconds / 60;
		    user_seconds_used = seconds % 60;
    	    	#endif

    	    Then times_builtin() became as follows (just removed old
    	    times(2) stuff:

	    times_builtin (list)
		 WORD_LIST *list;
	    {
	      extern long system_minutes_used, user_minutes_used;
	      extern int system_seconds_used, user_seconds_used;

	      no_args ("times", list);

	    #ifdef SYSV
	      /*
	       * For SYSV we can call add_times() at any time since the
    	       *  kernel does the child time summations for us.
	       */
	      add_times();	    	    /* SYSV version has no arg */
	    #endif

	      printf ("%0dm%0ds %0dm%0ds\n", system_minutes_used,
    	    	    	    	    	     system_seconds_used,
					     user_minutes_used,
    	    	    	    	    	     user_seconds_used);
	    }


    	. In glob.c, were missing a check for __GNUC__'s
    	    	__builtin_alloca.  The line 'extern char *alloca();'
    	    	caused a problem.

    	. jobs.c calls wait3() which doesn't exist on SYSV.  Changed
    	    	to wait().  [flush_child is never called, since job_control
    	    	is 0, however]

    	. readline/readline.c needed #include <errno.h>

    	. on SYSV.3 signal handlers return void function pointers.
    	    	(changed in general.h)

    	. initialized 'do_v9' in echo_builtin() to 1 to be more compatible
    	    	with SYSV /bin/echo.

    Overall, bash looks really good.  Minor complaints are that it is 
    somewhat slower on shell script interpretation than /bin/sh and it
    is much bigger (3x code size).  A sample timing for my .profile
    (which is overly complex):

    	time /bin/sh .profile
    	    real        4.0
    	    user        0.8
    	    sys         1.7

    	time bin/bash .profile
    	    real       14.2
    	    user        6.5
    	    sys         5.8

    Not sure what to attribute the time diffs to.  I tried running prof(1),
    with mixed results.  Our version of prof seemed to chop up long routine
    names, so I don't really trust it, but here are the first few lines 
    from a prof(1) session corresponding to the time'd results above:

       %Time Seconds Cumsecs  #Calls   msec/call  Name
	21.1    0.04    0.04     307      0.14    malloc
	19.0    0.04    0.08       2     20.      fork
	 9.5    0.02    0.10    2513      0.008   strcmp
	 9.5    0.02    0.12       2     10.      stat
	 4.8    0.01    0.13       1     10.      initialize_hash_table
	 4.8    0.01    0.14                      brk
	 4.8    0.01    0.15       2      5.      et_next_history
	 4.8    0.01    0.16       2      5.      sighold
	 4.8    0.01    0.17       2      5.      pipe
	 4.8    0.01    0.18      85      0.1     free
	 4.8    0.01    0.19     130      0.08    ase_version
	 2.7    0.01    0.20                      malloc_usable_size

    My guess is that fork() of a larger proc is what is making shell
    scripts slower.

    Minor, tentative, wish list:

    	visible bell in ding()
    	filename completion should expand shell variables, ie:
    	    $s/gnu/b<TAB>
    	should expand to either:
    	    $s/gnu/bash
    	or to:
    	    /ut/tony/src/gnu/bash

    Gets error on SYSV basename which is a shellscript using expr(1).
    Haven't looked into this much yet, but the execve() fails with
    errno == ENOEXEC and bash proceeds to determine that expr (?) is
    binary and thus can't be interpreted.
    Here is the line from basename that seems to be the problem:
    	 /bin/expr \
	    "/${1:-.}" : '\(.*[^/]\)/*$' : '.*/\(..*\)' : "\\(.*\\)$2\$"  \|  \
	    "/${1:-.}" : '\(.*[^/]\)/*$' : '.*/\(..*\)'    \|  \
	    "/${1:-.}" : '.*/\(..*\)'

    Running expr with a simpler argument works ok.

    Please let me know if I can provide any help or more information.

    Thanks.

- --tony	 ...!uunet!h-three!tony	 (919) 549-8334	 h-three  Systems  Corporation
	 h-three!tony@uunet.uu.net		 POB 12557; RTP, NC 27709; USA
	 t. e. bennett				 FAX: (919) 549-9868
------- End of forwarded message -------