Well, I have zsh-3.1.6 in (at least some kind of) working state under BeOS R4.5, and I'm attaching the patches I've done so far. BeOS is supposed to be POSIX.1 compliant, but as of yet several features are missing, and others have bugs. In particular: - there is not sufficient support yet for job control; in particular, tcsetpgrp() is there, but does not work. - kill(pid, 0), where pid does not exist, sets errno to EINVAL rather than ESRCH. - sigsuspend() is broken, in some manner. It looks like it does apply the temporary signal mask, and sets whatever internal flag to indicate a signal's arrival, but doesn't actually _deliver_ the signal. The sigsuspend returns, but the handler wasn't called, nor was the internal flag cleared, so subsequent sigsuspend's still think there's a signal to deliver, but it can't, so it just loops. - getpwnam() is faked, so to speak. Since the OS is not multiuser (yet), there's only one user, and only one corresponding passwd entry. Calling getpwnam(), with as far as I can tell _any_ string, is always successful, returning that one/only passwd entry. - link() doesn't work, as the filesystem doesn't support hard links (yet). Similarly, ln doesn't work without -s. - select() and fd_set are defined in <sys/socket.h> Here's what I did to try and work around them: - in signals.c, used sigprocmask/pause/sigprocmask to emulate the sigsuspend. - in signals.c and jobs.c, where it checked for errno=ESRCH, also checked for errno=EINVAL when sig=0. - in options.c, disabled option "monitor" if job control isn't supported, and disabled "cdablevars" if getpwnam() is faked (else it never reports "command not found", and instead just cds to $HOME). - in system.h, include <sys/socket.h> if necessary, and disable job control if a working tcsetpgrp() isn't found. - in hist.c, tried to handle history file locking when link() doesn't work. I did what seemed to make sense at the time, but I'm really not sure it's sufficient for good locking. - in Makefile, used "cp" for "make install" when "ln" isn't available. I added tests for the problems to configure.in (and the corresponding defines to acconfig.h), rather than just #ifdef'ing for BEOS, so that the workarounds are not used when the problems are fixed (assumedly) in later releases. I tried very hard to code the tests so that they won't fail incorrecly under other OS's, and I've tested them successfully under SunOS 4.1.1, 5.4, and 5.6; AIX 4.1.5, 4.2.1, and 4.3.2; linux 2.2.3; and Irix 6.5, but that's all I have access to. I also added an AC_PROG_LN macro to aclocal.m4, for configure.in to test for Makefile's ln, as that seemed like the easiest way to add it. In any case, there it is. I'm almost certain there are other POSIX incompatibilities in BeOS, but those are the only ones I've come across so far with zsh. Unfortunately, as the makefile said, "zsh test suite not available yet" so I couldn't do a big test. At least I have _some_ of my favorite shell now, and I'm not bitching at bash everytime I sit down at Be. :) -- Will Day <PGP mail preferred> OIT / O&E / Technical Support willday@xxxxxxxxxxxxxxxxxx Georgia Tech, Atlanta 30332-0715 -> Opinions expressed are mine alone and do not reflect OIT policy <- Those who would give up essential Liberty, to purchase a little temporary Safety, deserve neither Liberty nor Safety. Benjamin Franklin, Pennsylvania Assembly, Nov. 11, 1755
diff -rC2 zsh-3.1.6.orig/Src/Makefile.in zsh-3.1.6/Src/Makefile.in *** zsh-3.1.6.orig/Src/Makefile.in Tue Jun 29 12:39:30 1999 --- zsh-3.1.6/Src/Makefile.in Wed Aug 4 01:20:34 1999 *************** *** 36,39 **** --- 36,40 ---- sdir_top = @top_srcdir@ INSTALL = @INSTALL@ + LN = @LN@ @DEFS_MK@ *************** *** 164,171 **** if test -f $(bindir)/zsh; then \ rm -f $(bindir)/zsh.old; \ ! ln $(bindir)/zsh $(bindir)/zsh.old; \ else :; fi rm -f $(bindir)/zsh.new ! ln $(bindir)/zsh-$(VERSION) $(bindir)/zsh.new mv $(bindir)/zsh.new $(bindir)/zsh --- 165,172 ---- if test -f $(bindir)/zsh; then \ rm -f $(bindir)/zsh.old; \ ! $(LN) $(bindir)/zsh $(bindir)/zsh.old; \ else :; fi rm -f $(bindir)/zsh.new ! $(LN) $(bindir)/zsh-$(VERSION) $(bindir)/zsh.new mv $(bindir)/zsh.new $(bindir)/zsh diff -rC2 zsh-3.1.6.orig/Src/hist.c zsh-3.1.6/Src/hist.c *** zsh-3.1.6.orig/Src/hist.c Sat Jul 31 07:53:28 1999 --- zsh-3.1.6/Src/hist.c Wed Aug 4 01:20:34 1999 *************** *** 1948,1951 **** --- 1948,1952 ---- char *tmpfile, *lockfile; + #ifdef HAVE_LINK tmpfile = zalloc(len + 10 + 1); sprintf(tmpfile, "%s.%ld", fn, (long)mypid); *************** *** 1974,1977 **** --- 1975,1993 ---- unlink(tmpfile); free(tmpfile); + #else /* not HAVE_LINK */ + lockfile = zalloc(len + 5 + 1); + sprintf(lockfile, "%s.LOCK", fn); + while ((fd = open(lockfile, O_CREAT|O_EXCL, 0644)) < 0) { + if (errno == EEXIST) continue; + else if (keep_trying) { + if (time(NULL) - sb.st_mtime < 10) + sleep(1); + continue; + } + lockhistct--; + break; + } + free(lockfile); + #endif /* HAVE_LINK */ } return ct != lockhistct; diff -rC2 zsh-3.1.6.orig/Src/jobs.c zsh-3.1.6/Src/jobs.c *** zsh-3.1.6.orig/Src/jobs.c Mon Jul 5 05:36:37 1999 --- zsh-3.1.6/Src/jobs.c Wed Aug 4 01:20:35 1999 *************** *** 836,840 **** --- 836,844 ---- /* child_block() around this loop in case #ifndef WNOHANG */ child_block(); /* unblocked in child_suspend() */ + #ifdef BROKEN_KILL_ESRCH + while (!errflag && (kill(pid, 0) >= 0 || (errno != ESRCH && errno != EINVAL))) { + #else /* not BROKEN_KILL_ESRCH */ while (!errflag && (kill(pid, 0) >= 0 || errno != ESRCH)) { + #endif /* BROKEN_KILL_ESRCH */ if (first) first = 0; diff -rC2 zsh-3.1.6.orig/Src/options.c zsh-3.1.6/Src/options.c *** options.c.orig Fri Jul 16 03:47:19 1999 --- options.c Thu Aug 5 00:44:59 1999 *************** *** 654,657 **** --- 654,665 ---- setgid(getgid()); #endif /* HAVE_SETUID */ + #ifndef JOB_CONTROL + } else if(optno == MONITOR && value) { + return -1; + #endif /* not JOB_CONTROL */ + #ifdef GETPWNAM_FAKED + } else if(optno == CDABLEVARS && value) { + return -1; + #endif /* GETPWNAM_FAKED */ } opts[optno] = value; diff -rC2 zsh-3.1.6.orig/Src/signals.c zsh-3.1.6/Src/signals.c *** zsh-3.1.6.orig/Src/signals.c Thu Jul 1 07:37:16 1999 --- zsh-3.1.6/Src/signals.c Wed Aug 4 16:40:37 1999 *************** *** 327,330 **** --- 327,333 ---- #ifdef POSIX_SIGNALS sigset_t set; + #ifdef BROKEN_POSIX_SIGSUSPEND + sigset_t oset; + #endif /* BROKEN_POSIX_SIGSUSPEND */ sigfillset(&set); *************** *** 333,338 **** if (sig2) sigdelset(&set, sig2); ret = sigsuspend(&set); ! #else # ifdef BSD_SIGNALS sigset_t set; --- 336,347 ---- if (sig2) sigdelset(&set, sig2); + #ifdef BROKEN_POSIX_SIGSUSPEND + sigprocmask(SIG_SETMASK, &set, &oset); + pause(); + sigprocmask(SIG_SETMASK, &oset, NULL); + #else /* not BROKEN_POSIX_SIGSUSPEND */ ret = sigsuspend(&set); ! #endif /* BROKEN_POSIX_SIGSUSPEND */ ! #else /* not POSIX_SIGNALS */ # ifdef BSD_SIGNALS sigset_t set; *************** *** 602,605 **** --- 611,617 ---- for (pn = jn->procs; pn; pn = pn->next) if ((err = kill(pn->pid, sig)) == -1 && errno != ESRCH) + #ifdef BROKEN_KILL_ESRCH + if(errno != EINVAL || sig != 0) + #endif /* BROKEN_KILL_ESRCH */ return -1; return err; diff -rC2 zsh-3.1.6.orig/Src/system.h zsh-3.1.6/Src/system.h *** zsh-3.1.6.orig/Src/system.h Sun May 16 11:20:52 1999 --- zsh-3.1.6/Src/system.h Wed Aug 4 01:20:35 1999 *************** *** 268,271 **** --- 268,273 ---- # include <sys/select.h> # endif + #elif defined(SELECT_IN_SYS_SOCKET_H) + # include <sys/socket.h> #endif *************** *** 614,615 **** --- 616,622 ---- #endif #endif + + /* Can't support job control without working tcsetgrp() */ + #ifdef BROKEN_TCSETPGRP + #undef JOB_CONTROL + #endif /* BROKEN_TCSETPGRP */ diff -rC2 zsh-3.1.6.orig/acconfig.h zsh-3.1.6/acconfig.h *** zsh-3.1.6.orig/acconfig.h Mon Jun 14 10:08:10 1999 --- zsh-3.1.6/acconfig.h Wed Aug 4 01:22:54 1999 *************** *** 199,202 **** --- 199,205 ---- #undef HAVE_IOCTL_PROTO + /* Define to 1 if select() is defined in <sys/socket.h>, ie BeOS R4.51*/ + #undef SELECT_IN_SYS_SOCKET_H + /* Define to 1 if system has working FIFO's */ #undef HAVE_FIFOS *************** *** 216,219 **** --- 219,237 ---- /* Define to 1 if /bin/sh does not interpret \ escape sequences */ #undef SH_USE_BSD_ECHO + + /* Define to 1 if system has working link() */ + #undef HAVE_LINK + + /* Define to 1 if kill(pid, 0) doesn't return ESRCH, ie BeOS R4.51 */ + #undef BROKEN_KILL_ESRCH + + /* Define to 1 if sigsuspend() is broken, ie BeOS R4.51 */ + #undef BROKEN_POSIX_SIGSUSPEND + + /* Define to 1 if getpwnam() is faked, ie BeOS R4.51 */ + #undef GETPWNAM_FAKED + + /* Define to 1 if tcsetpgrp() doesn't work, ie BeOS R4.51 */ + #undef BROKEN_TCSETPGRP /* Define to 1 if an underscore has to be prepended to dlsym() argument */ diff -rC2 zsh-3.1.6.orig/aclocal.m4 zsh-3.1.6/aclocal.m4 *** zsh-3.1.6.orig/aclocal.m4 Tue Jul 27 12:13:42 1999 --- zsh-3.1.6/aclocal.m4 Wed Aug 4 01:22:54 1999 *************** *** 53,55 **** --- 53,77 ---- ]) + AC_DEFUN(AC_PROG_LN, + [AC_MSG_CHECKING(whether ln works) + AC_CACHE_VAL(ac_cv_prog_LN, + [rm -f conftestdata conftestlink + echo > conftestdata + if ln conftestdata conftestlink 2>/dev/null + then + rm -f conftestdata conftestlink + ac_cv_prog_LN="ln" + else + rm -f conftestdata + ac_cv_prog_LN="cp" + fi])dnl + LN="$ac_cv_prog_LN" + if test "$ac_cv_prog_LN" = "ln"; then + AC_MSG_RESULT(yes) + else + AC_MSG_RESULT(no) + fi + AC_SUBST(LN)dnl + ]) + builtin(include, aczsh.m4) diff -rC2 zsh-3.1.6.orig/configure.in zsh-3.1.6/configure.in *** configure.in.orig Tue Jul 27 11:09:40 1999 --- configure.in Wed Aug 4 20:47:27 1999 *************** *** 381,384 **** --- 381,385 ---- AC_PROG_INSTALL dnl Check for BSD compatible `install' AC_PROG_AWK dnl Check for mawk,gawk,nawk, then awk. + AC_PROG_LN dnl Check for working ln, for "make install" AC_CHECK_PROGS([YODL], [yodl], [:]) *************** *** 1047,1050 **** --- 1048,1065 ---- fi + dnl ------------------- + dnl select() defined in <sys/socket.h>, ie BeOS R4.51 + dnl ------------------- + if test $ac_cv_header_sys_select_h != yes; then + AC_CACHE_CHECK(for select() in <sys/socket.h>, + zsh_cv_header_socket_h_select_proto, + [AC_TRY_COMPILE([#include <sys/socket.h>], [fd_set fd;], + zsh_cv_header_socket_h_select_proto=yes, + zsh_cv_header_socket_h_select_proto=no)]) + if test $zsh_cv_header_socket_h_select_proto = yes; then + AC_DEFINE(SELECT_IN_SYS_SOCKET_H) + fi + fi + dnl ----------- dnl named FIFOs *************** *** 1098,1101 **** --- 1113,1266 ---- if test $zsh_cv_prog_sh_echo_escape = no; then AC_DEFINE(SH_USE_BSD_ECHO) + fi + + dnl ----------- + dnl test for whether link() works + dnl for instance, BeOS R4.51 doesn't support hard links yet + dnl ----------- + AC_CACHE_CHECK(if link() works, + zsh_cv_sys_link, + [AC_TRY_RUN([ + #include <unistd.h> + #include <fcntl.h> + main() + { + int ret; + char *tmpfile, *newfile; + tmpfile="/tmp/zsh.linktest$$"; + newfile="/tmp/zsh.linktest2$$"; + unlink(tmpfile); + unlink(newfile); + if(creat(tmpfile, 0644) < 0) + exit(1); + ret = link(tmpfile, newfile); + unlink(tmpfile); + unlink(newfile); + exit(ret<0); + } + ], + zsh_cv_sys_link=yes, + zsh_cv_sys_link=no, + zsh_cv_sys_link=yes)]) + if test $zsh_cv_sys_link = yes; then + AC_DEFINE(HAVE_LINK) + fi + + dnl ----------- + dnl test for whether kill(pid, 0) where pid doesn't exit + dnl should set errno to ESRCH, but some like BeOS R4.51 set to EINVAL + dnl ----------- + AC_CACHE_CHECK(if kill(pid, 0) returns ESRCH correctly, + zsh_cv_sys_killesrch, + [AC_TRY_RUN([ + #include <unistd.h> + #include <signal.h> + #include <errno.h> + main() + { + int pid, ret; + pid=getpid() + 10000; + ret=kill(pid, 0); + exit(ret<0 && errno!=ESRCH); + } + ], + zsh_cv_sys_killesrch=yes, + zsh_cv_sys_killesrch=no, + zsh_cv_sys_killesrch=yes)]) + if test $zsh_cv_sys_killesrch = no; then + AC_DEFINE(BROKEN_KILL_ESRCH) + fi + + dnl ----------- + dnl if POSIX, test for working sigsuspend(). + dnl for instance, BeOS R4.51 is broken. + dnl ----------- + if test $signals_style=POSIX_SIGNALS; then + AC_CACHE_CHECK(if POSIX sigsuspend() works, + zsh_cv_sys_sigsuspend, + [AC_TRY_RUN([ + #include <signal.h> + #include <unistd.h> + int child=0; + void handler(sig) + int sig; + {if(sig==SIGCHLD) child=1;} + main() { + struct sigaction act; + sigset_t set; + int pid, ret; + act.sa_handler = &handler; + sigfillset(&act.sa_mask); + act.sa_flags = 0; + sigaction(SIGCHLD, &act, 0); + sigfillset(&set); + sigprocmask(SIG_SETMASK, &set, 0); + pid=fork(); + if(pid==0) return 0; + if(pid>0) { + sigemptyset(&set); + ret=sigsuspend(&set); + exit(child==0); + } + } + ], + zsh_cv_sys_sigsuspend=yes, + zsh_cv_sys_sigsuspend=no, + zsh_cv_sys_sigsuspend=yes)]) + if test $zsh_cv_sys_sigsuspend = no; then + AC_DEFINE(BROKEN_POSIX_SIGSUSPEND) + fi + fi + + dnl ----------- + dnl if found tcsetpgrp, test to see if it actually works + dnl for instance, BeOS R4.51 does not support it yet + dnl ----------- + if test $ac_cv_func_tcsetpgrp=yes; then + AC_CACHE_CHECK(if tcsetpgrp() actually works, + zsh_cv_sys_tcsetpgrp, + [AC_TRY_RUN([ + #include <sys/types.h> + #include <unistd.h> + main() { + int ret; + ret=tcsetpgrp(0, tcgetpgrp(0)); + exit(ret<0); + } + ], + zsh_cv_sys_tcsetpgrp=yes, + zsh_cv_sys_tcsetpgrp=no, + zsh_cv_sys_tcsetpgrp=yes)]) + if test $zsh_cv_sys_tcsetpgrp = no; then + AC_DEFINE(BROKEN_TCSETPGRP) + fi + fi + + dnl ----------- + dnl test for faked getpwnam() entry, ie a single entry returned for any username + dnl for instance, BeOS R4.51 is not multiuser yet, and fakes getpwnam() + dnl test by looking up two usernames that shouldn't succeed, and compare entry + dnl ----------- + if test $ac_cv_func_getpwnam=yes; then + AC_CACHE_CHECK(if getpwnam() is faked, + zsh_cv_sys_getpwnam_faked, + [AC_TRY_RUN([ + #include <pwd.h> + main() { + struct passwd *pw1, *pw2; + char buf[1024]; + sprintf(buf, "%d:%d", getpid(), rand()); + pw1=getpwnam(buf); + sprintf(buf, "%d:%d", rand(), getpid()); + pw2=getpwnam(buf); + exit(pw1!=0 && pw2!=0 && !strcmp(pw1->pw_name, pw2->pw_name)); + } + ], + zsh_cv_sys_getpwnam_faked=no, + zsh_cv_sys_getpwnam_faked=yes, + zsh_cv_sys_getpwnam_faked=no)]) + if test $zsh_cv_sys_getpwnam_faked = yes; then + AC_DEFINE(GETPWNAM_FAKED) + fi fi
Attachment:
pgp7WMJpW5vHk.pgp
Description: PGP signature