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 -------