From 33d6bc609c8497b4090088ef10b8ee79c2e4c24e Mon Sep 17 00:00:00 2001 From: LEVAI Daniel Date: Sun, 16 Jun 2013 15:59:35 -0500 Subject: system/ksh-openbsd: Updated for version 20130611. Signed-off-by: Robby Workman --- system/ksh-openbsd/ksh-openbsd.SlackBuild | 2 +- system/ksh-openbsd/ksh-openbsd.info | 8 +- system/ksh-openbsd/patches/02-remove_fp.diff | 12 +- ...compensate-for-cursor-move-on-command-mode.diff | 55 ++ ...m-the-list-of-characters-blocking-addition.diff | 37 ++ ...compensate-for-cursor-move-on-command-mode.diff | 55 -- ...m-the-list-of-characters-blocking-addition.diff | 37 -- .../patches/08-new_history_implementation.diff | 584 +++++++++++++++++++++ system/ksh-openbsd/patches/09-escape_colon.diff | 11 - system/ksh-openbsd/patches/09-nobeep_option.diff | 330 ++++++++++++ .../patches/10-new_history_implementation.diff | 584 --------------------- system/ksh-openbsd/patches/11-nobeep_option.diff | 330 ------------ 12 files changed, 1016 insertions(+), 1029 deletions(-) create mode 100644 system/ksh-openbsd/patches/06-ksh-vi-compensate-for-cursor-move-on-command-mode.diff create mode 100644 system/ksh-openbsd/patches/07-Remove-from-the-list-of-characters-blocking-addition.diff delete mode 100644 system/ksh-openbsd/patches/07-ksh-vi-compensate-for-cursor-move-on-command-mode.diff delete mode 100644 system/ksh-openbsd/patches/08-Remove-from-the-list-of-characters-blocking-addition.diff create mode 100644 system/ksh-openbsd/patches/08-new_history_implementation.diff delete mode 100644 system/ksh-openbsd/patches/09-escape_colon.diff create mode 100644 system/ksh-openbsd/patches/09-nobeep_option.diff delete mode 100644 system/ksh-openbsd/patches/10-new_history_implementation.diff delete mode 100644 system/ksh-openbsd/patches/11-nobeep_option.diff diff --git a/system/ksh-openbsd/ksh-openbsd.SlackBuild b/system/ksh-openbsd/ksh-openbsd.SlackBuild index 60eab211a9..4a18364fb2 100644 --- a/system/ksh-openbsd/ksh-openbsd.SlackBuild +++ b/system/ksh-openbsd/ksh-openbsd.SlackBuild @@ -28,7 +28,7 @@ # Build script for the Linux port of OpenBSD's ksh PRGNAM=ksh-openbsd -VERSION=20130311 +VERSION=20130611 BUILD=${BUILD:-1} TAG=${TAG:-_SBo} diff --git a/system/ksh-openbsd/ksh-openbsd.info b/system/ksh-openbsd/ksh-openbsd.info index d45763ddde..3540e0a5b2 100644 --- a/system/ksh-openbsd/ksh-openbsd.info +++ b/system/ksh-openbsd/ksh-openbsd.info @@ -1,8 +1,8 @@ PRGNAM="ksh-openbsd" -VERSION="20130311" -HOMEPAGE="http://leva.ecentrum.hu/slackbuilds/distfiles/ksh-openbsd-20130311.tar.gz" -DOWNLOAD="http://leva.ecentrum.hu/slackbuilds/distfiles/ksh-openbsd-20130311.tar.gz" -MD5SUM="c2856fe310627f7c3ad2f87985badc2d" +VERSION="20130611" +HOMEPAGE="http://leva.ecentrum.hu/slackbuilds/distfiles/ksh-openbsd-20130611.tar.gz" +DOWNLOAD="http://leva.ecentrum.hu/slackbuilds/distfiles/ksh-openbsd-20130611.tar.gz" +MD5SUM="788a91d47164f3cb87c0b3ca698f85b8" DOWNLOAD_x86_64="" MD5SUM_x86_64="" REQUIRES="libbsd" diff --git a/system/ksh-openbsd/patches/02-remove_fp.diff b/system/ksh-openbsd/patches/02-remove_fp.diff index 25817d0a56..06f586e5c8 100644 --- a/system/ksh-openbsd/patches/02-remove_fp.diff +++ b/system/ksh-openbsd/patches/02-remove_fp.diff @@ -78,11 +78,10 @@ diff -u -p -r1.15 shf.c if (!fmt) return 0; -@@ -946,134 +915,6 @@ shf_vfprintf(struct shf *shf, const char - precision = len; /* no loss */ +@@ -922,134 +922,6 @@ shf_vfprintf(struct shf *shf, const char } break; -- + -#ifdef FP - case 'e': - case 'g': @@ -102,7 +101,7 @@ diff -u -p -r1.15 shf.c - /* - * Assumes doubles are pushed on - * the stack. If this is not so, then -- * FL_LONG/FL_SHORT should be checked. +- * FL_LLONG/FL_LONG/FL_SHORT should be checked. - */ - fpnum = va_arg(args, double); - s = fpbuf; @@ -210,8 +209,7 @@ diff -u -p -r1.15 shf.c - break; - } -#endif /* FP */ - +- case 's': if (!(s = va_arg(args, char *))) - - + s = "(null %s)"; diff --git a/system/ksh-openbsd/patches/06-ksh-vi-compensate-for-cursor-move-on-command-mode.diff b/system/ksh-openbsd/patches/06-ksh-vi-compensate-for-cursor-move-on-command-mode.diff new file mode 100644 index 0000000000..ce51064a01 --- /dev/null +++ b/system/ksh-openbsd/patches/06-ksh-vi-compensate-for-cursor-move-on-command-mode.diff @@ -0,0 +1,55 @@ +From fc2058b4b6a64d66fe1ee318bccea42b4569d31f Mon Sep 17 00:00:00 2001 +From: Alexander Polakov +Date: Sun, 29 May 2011 19:23:17 +0400 +Subject: [PATCH 7/8] ksh/vi: compensate for cursor move on command mode + + * move completion cursor one position right if the + character is space + * when we enter command mode, cursor is moved one + position left, and the space on the end is "lost". + So we are trying to complete "ls" instead of file + while having "ls " and "file.c" when having "file.c ". +--- + vi.c | 15 ++++++++++++++- + 1 files changed, 14 insertions(+), 1 deletions(-) + +diff --git vi.c vi.c +index 95d192c..0bac6be 100644 +--- vi.c ++++ vi.c +@@ -1956,6 +1956,7 @@ complete_word(int command, int count, int flags) + int match_len; + int is_unique; + int is_command; ++ int pos; + + /* Undo previous completion */ + if (command == 0 && expanded == COMPLETE && buf) { +@@ -1974,11 +1975,23 @@ complete_word(int command, int count, int flags) + buf = 0; + } + ++ /* XXX: hack. When we enter command mode, the cursor is moved ++ * one position left. This means that the space at the end is ++ * eaten and file completion becomes command completion. ++ * (see x_locate_word() for more on this) ++ */ ++ pos = es->cursor; ++ if (command) { ++ pos += (isspace(es->cbuf[es->cursor]) ? 1 : 0); ++ if (pos > es->linelen) ++ pos = es->linelen; ++ } ++ + /* XCF_FULLPATH for count 'cause the menu printed by print_expansions() + * was done this way. + */ + nwords = x_cf_glob(XCF_COMMAND_FILE | (count ? XCF_FULLPATH : 0) | flags, +- es->cbuf, es->linelen, es->cursor, ++ es->cbuf, es->linelen, pos, + &start, &end, &words, &is_command); + if (nwords == 0) { + vi_error(); +-- +1.7.5 + diff --git a/system/ksh-openbsd/patches/07-Remove-from-the-list-of-characters-blocking-addition.diff b/system/ksh-openbsd/patches/07-Remove-from-the-list-of-characters-blocking-addition.diff new file mode 100644 index 0000000000..9326e8072d --- /dev/null +++ b/system/ksh-openbsd/patches/07-Remove-from-the-list-of-characters-blocking-addition.diff @@ -0,0 +1,37 @@ +From 5fc8a0ae3c807bd57c8e8d55531770914ea6670a Mon Sep 17 00:00:00 2001 +From: Alexander Polakov +Date: Mon, 20 Jun 2011 00:35:46 +0400 +Subject: [PATCH 8/8] Remove $ from the list of characters blocking * + addition. + +This allows things like $HOME/bi complete to /home/username/bin. +--- + edit.c | 8 ++++---- + 1 files changed, 4 insertions(+), 4 deletions(-) + +diff --git edit.c edit.c +index 01c2fe6..2702dab 100644 +--- edit.c ++++ edit.c +@@ -627,14 +627,14 @@ add_glob(const char *str, int slen) + + /* + * If the pathname contains a wildcard (an unquoted '*', +- * '?', or '[') or parameter expansion ('$'), or a ~username +- * with no trailing slash, then it is globbed based on that +- * value (i.e., without the appended '*'). ++ * '?', or '[') or a ~username with no trailing slash, ++ * then it is globbed based on that value (i.e., without ++ * the appended '*'). + */ + for (s = toglob; *s; s++) { + if (*s == '\\' && s[1]) + s++; +- else if (*s == '*' || *s == '[' || *s == '?' || *s == '$' || ++ else if ((*s == '*' || *s == '[' || *s == '?') || + (s[1] == '(' /*)*/ && strchr("+@!", *s))) + break; + else if (*s == '/') +-- +1.7.5 + diff --git a/system/ksh-openbsd/patches/07-ksh-vi-compensate-for-cursor-move-on-command-mode.diff b/system/ksh-openbsd/patches/07-ksh-vi-compensate-for-cursor-move-on-command-mode.diff deleted file mode 100644 index ce51064a01..0000000000 --- a/system/ksh-openbsd/patches/07-ksh-vi-compensate-for-cursor-move-on-command-mode.diff +++ /dev/null @@ -1,55 +0,0 @@ -From fc2058b4b6a64d66fe1ee318bccea42b4569d31f Mon Sep 17 00:00:00 2001 -From: Alexander Polakov -Date: Sun, 29 May 2011 19:23:17 +0400 -Subject: [PATCH 7/8] ksh/vi: compensate for cursor move on command mode - - * move completion cursor one position right if the - character is space - * when we enter command mode, cursor is moved one - position left, and the space on the end is "lost". - So we are trying to complete "ls" instead of file - while having "ls " and "file.c" when having "file.c ". ---- - vi.c | 15 ++++++++++++++- - 1 files changed, 14 insertions(+), 1 deletions(-) - -diff --git vi.c vi.c -index 95d192c..0bac6be 100644 ---- vi.c -+++ vi.c -@@ -1956,6 +1956,7 @@ complete_word(int command, int count, int flags) - int match_len; - int is_unique; - int is_command; -+ int pos; - - /* Undo previous completion */ - if (command == 0 && expanded == COMPLETE && buf) { -@@ -1974,11 +1975,23 @@ complete_word(int command, int count, int flags) - buf = 0; - } - -+ /* XXX: hack. When we enter command mode, the cursor is moved -+ * one position left. This means that the space at the end is -+ * eaten and file completion becomes command completion. -+ * (see x_locate_word() for more on this) -+ */ -+ pos = es->cursor; -+ if (command) { -+ pos += (isspace(es->cbuf[es->cursor]) ? 1 : 0); -+ if (pos > es->linelen) -+ pos = es->linelen; -+ } -+ - /* XCF_FULLPATH for count 'cause the menu printed by print_expansions() - * was done this way. - */ - nwords = x_cf_glob(XCF_COMMAND_FILE | (count ? XCF_FULLPATH : 0) | flags, -- es->cbuf, es->linelen, es->cursor, -+ es->cbuf, es->linelen, pos, - &start, &end, &words, &is_command); - if (nwords == 0) { - vi_error(); --- -1.7.5 - diff --git a/system/ksh-openbsd/patches/08-Remove-from-the-list-of-characters-blocking-addition.diff b/system/ksh-openbsd/patches/08-Remove-from-the-list-of-characters-blocking-addition.diff deleted file mode 100644 index 9326e8072d..0000000000 --- a/system/ksh-openbsd/patches/08-Remove-from-the-list-of-characters-blocking-addition.diff +++ /dev/null @@ -1,37 +0,0 @@ -From 5fc8a0ae3c807bd57c8e8d55531770914ea6670a Mon Sep 17 00:00:00 2001 -From: Alexander Polakov -Date: Mon, 20 Jun 2011 00:35:46 +0400 -Subject: [PATCH 8/8] Remove $ from the list of characters blocking * - addition. - -This allows things like $HOME/bi complete to /home/username/bin. ---- - edit.c | 8 ++++---- - 1 files changed, 4 insertions(+), 4 deletions(-) - -diff --git edit.c edit.c -index 01c2fe6..2702dab 100644 ---- edit.c -+++ edit.c -@@ -627,14 +627,14 @@ add_glob(const char *str, int slen) - - /* - * If the pathname contains a wildcard (an unquoted '*', -- * '?', or '[') or parameter expansion ('$'), or a ~username -- * with no trailing slash, then it is globbed based on that -- * value (i.e., without the appended '*'). -+ * '?', or '[') or a ~username with no trailing slash, -+ * then it is globbed based on that value (i.e., without -+ * the appended '*'). - */ - for (s = toglob; *s; s++) { - if (*s == '\\' && s[1]) - s++; -- else if (*s == '*' || *s == '[' || *s == '?' || *s == '$' || -+ else if ((*s == '*' || *s == '[' || *s == '?') || - (s[1] == '(' /*)*/ && strchr("+@!", *s))) - break; - else if (*s == '/') --- -1.7.5 - diff --git a/system/ksh-openbsd/patches/08-new_history_implementation.diff b/system/ksh-openbsd/patches/08-new_history_implementation.diff new file mode 100644 index 0000000000..d083b42554 --- /dev/null +++ b/system/ksh-openbsd/patches/08-new_history_implementation.diff @@ -0,0 +1,584 @@ +From: Marco Peereboom +To: tech@openbsd.org +Subject: ksh history corruption + +I have had enough of corrupt ksh history so I had a look at the code to +try to fix it. The magical code was very magical so I basically deleted +most of it and made ksh history into a flat text file. It handles +multiple ksh instances writing to the same text file with locks just +like the current ksh does. I haven't noticed any differences in +behavior running this. + +Code is much simpler and it shaves ~4k of the binary too. + +Index: alloc.c +=================================================================== +RCS file: /cvs/src/bin/ksh/alloc.c,v +retrieving revision 1.8 +diff -u -p -r1.8 alloc.c +--- alloc.c 21 Jul 2008 17:30:08 -0000 1.8 ++++ alloc.c 30 Aug 2011 18:05:47 -0000 +@@ -62,7 +62,7 @@ alloc(size_t size, Area *ap) + { + struct link *l; + +- l = malloc(sizeof(struct link) + size); ++ l = calloc(1, sizeof(struct link) + size); + if (l == NULL) + internal_errorf(1, "unable to allocate memory"); + l->next = ap->freelist; +Index: history.c +=================================================================== +RCS file: /cvs/src/bin/ksh/history.c,v +retrieving revision 1.39 +diff -u -p -r1.39 history.c +--- history.c 19 May 2010 17:36:08 -0000 1.39 ++++ history.c 31 Aug 2011 19:33:24 -0000 +@@ -11,8 +11,7 @@ + * a) the original in-memory history mechanism + * b) a more complicated mechanism done by pc@hillside.co.uk + * that more closely follows the real ksh way of doing +- * things. You need to have the mmap system call for this +- * to work on your system ++ * things. + */ + + #include "sh.h" +@@ -22,19 +21,10 @@ + # include + # include + +-/* +- * variables for handling the data file +- */ +-static int histfd; +-static int hsize; +- +-static int hist_count_lines(unsigned char *, int); +-static int hist_shrink(unsigned char *, int); +-static unsigned char *hist_skip_back(unsigned char *,int *,int); +-static void histload(Source *, unsigned char *, int); +-static void histinsert(Source *, int, unsigned char *); +-static void writehistfile(int, char *); +-static int sprinkle(int); ++static void writehistfile(FILE *); ++static FILE *history_open(int *); ++static int history_load(FILE *, Source *); ++static void history_close(FILE *); + + static int hist_execute(char *); + static int hist_replace(char **, const char *, const char *, int); +@@ -45,8 +35,8 @@ static void histbackup(void); + static char **current; /* current position in history[] */ + static char *hname; /* current name of history file */ + static int hstarted; /* set after hist_init() called */ +-static Source *hist_source; +- ++static Source *hist_source; ++static struct stat last_sb; + + int + c_fc(char **wp) +@@ -529,15 +519,10 @@ sethistfile(const char *name) + /* if the name is the same as the name we have */ + if (hname && strcmp(hname, name) == 0) + return; +- + /* + * its a new name - possibly + */ +- if (histfd) { +- /* yes the file is open */ +- (void) close(histfd); +- histfd = 0; +- hsize = 0; ++ if (hname) { + afree(hname, APERM); + hname = NULL; + /* let's reset the history */ +@@ -577,18 +562,26 @@ init_histvec(void) + void + histsave(int lno, const char *cmd, int dowrite) + { +- char **hp; +- char *c, *cp; ++ char **hp; ++ char *c, *cp; ++ int changed; ++ FILE *f = NULL; ++ ++ if (dowrite) { ++ f = history_open(&changed); ++ if (f && changed) { ++ /* reset history */ ++ histptr = history - 1; ++ hist_source->line = 0; ++ history_load(f, hist_source); ++ } ++ } + + c = str_save(cmd, APERM); + if ((cp = strchr(c, '\n')) != NULL) + *cp = '\0'; + +- if (histfd && dowrite) +- writehistfile(lno, c); +- + hp = histptr; +- + if (++hp >= history + histsize) { /* remove oldest command */ + afree((void*)*history, APERM); + for (hp = history; hp < history + histsize - 1; hp++) +@@ -596,371 +589,125 @@ histsave(int lno, const char *cmd, int d + } + *hp = c; + histptr = hp; +-} +- +-/* +- * Write history data to a file nominated by HISTFILE +- * if HISTFILE is unset then history still happens, but +- * the data is not written to a file +- * All copies of ksh looking at the file will maintain the +- * same history. This is ksh behaviour. +- * +- * This stuff uses mmap() +- * if your system ain't got it - then you'll have to undef HISTORYFILE +- */ + +-/* +- * Open a history file +- * Format is: +- * Bytes 1, 2: HMAGIC - just to check that we are dealing with +- * the correct object +- * Then follows a number of stored commands +- * Each command is +- * +- */ +-#define HMAGIC1 0xab +-#define HMAGIC2 0xcd +-#define COMMAND 0xff ++ if (dowrite && f) { ++ writehistfile(f); ++ history_close(f); ++ } ++} + +-void +-hist_init(Source *s) ++static FILE * ++history_open(int *changed) + { +- unsigned char *base; +- int lines; +- int fd; +- +- if (Flag(FTALKING) == 0) +- return; +- +- hstarted = 1; +- +- hist_source = s; +- +- hname = str_val(global("HISTFILE")); +- if (hname == NULL) +- return; +- hname = str_save(hname, APERM); ++ int fd; ++ FILE *f = NULL; ++ struct stat sb; + +- retry: +- /* we have a file and are interactive */ +- if ((fd = open(hname, O_RDWR|O_CREAT|O_APPEND, 0600)) < 0) +- return; +- +- histfd = savefd(fd); +- if (histfd != fd) ++ if ((fd = open(hname, O_RDWR | O_CREAT | O_EXLOCK, 0600)) == -1) ++ return (NULL); ++ f = fdopen(fd, "r+"); ++ if (f == NULL) { + close(fd); ++ goto bad; ++ } + +- (void) flock(histfd, LOCK_EX); ++ if (fstat(fileno(f), &sb) == -1) ++ goto bad; ++ if (timespeccmp(&sb.st_mtim, &last_sb.st_mtim, ==)) ++ *changed = 0; ++ else ++ *changed = 1; + +- hsize = lseek(histfd, 0L, SEEK_END); ++ return (f); ++bad: ++ if (f) ++ fclose(f); + +- if (hsize == 0) { +- /* add magic */ +- if (sprinkle(histfd)) { +- hist_finish(); +- return; +- } +- } +- else if (hsize > 0) { +- /* +- * we have some data +- */ +- base = (unsigned char *)mmap(0, hsize, PROT_READ, +- MAP_FILE|MAP_PRIVATE, histfd, 0); +- /* +- * check on its validity +- */ +- if (base == MAP_FAILED || *base != HMAGIC1 || base[1] != HMAGIC2) { +- if (base != MAP_FAILED) +- munmap((caddr_t)base, hsize); +- hist_finish(); +- if (unlink(hname) != 0) +- return; +- goto retry; +- } +- if (hsize > 2) { +- lines = hist_count_lines(base+2, hsize-2); +- if (lines > histsize) { +- /* we need to make the file smaller */ +- if (hist_shrink(base, hsize)) +- if (unlink(hname) != 0) +- return; +- munmap((caddr_t)base, hsize); +- hist_finish(); +- goto retry; +- } +- } +- histload(hist_source, base+2, hsize-2); +- munmap((caddr_t)base, hsize); +- } +- (void) flock(histfd, LOCK_UN); +- hsize = lseek(histfd, 0L, SEEK_END); ++ return (NULL); + } + +-typedef enum state { +- shdr, /* expecting a header */ +- sline, /* looking for a null byte to end the line */ +- sn1, /* bytes 1 to 4 of a line no */ +- sn2, sn3, sn4 +-} State; ++static void ++history_close(FILE *f) ++{ ++ fflush(f); ++ fstat(fileno(f), &last_sb); ++ fclose(f); ++} + + static int +-hist_count_lines(unsigned char *base, int bytes) ++history_load(FILE *f, Source *s) + { +- State state = shdr; +- int lines = 0; ++ char *p, line[LINE + 1]; ++ uint32_t i; + +- while (bytes--) { +- switch (state) { +- case shdr: +- if (*base == COMMAND) +- state = sn1; ++ /* just read it all; will auto resize history upon next command */ ++ for (i = 1; ; i++) { ++ p = fgets(line, sizeof line, f); ++ if (p == NULL || feof(f) || ferror(f)) + break; +- case sn1: +- state = sn2; break; +- case sn2: +- state = sn3; break; +- case sn3: +- state = sn4; break; +- case sn4: +- state = sline; break; +- case sline: +- if (*base == '\0') +- lines++, state = shdr; ++ if ((p = strchr(line, '\n')) == NULL) { ++ bi_errorf("history file is corrupt"); ++ return (1); + } +- base++; ++ *p = '\0'; ++ ++ s->line = i; ++ s->cmd_offset = i; ++ histsave(i, (char *)line, 0); + } +- return lines; ++ ++ return (0); + } + +-/* +- * Shrink the history file to histsize lines +- */ +-static int +-hist_shrink(unsigned char *oldbase, int oldbytes) ++void ++hist_init(Source *s) + { +- int fd; +- char nfile[1024]; +- struct stat statb; +- unsigned char *nbase = oldbase; +- int nbytes = oldbytes; +- +- nbase = hist_skip_back(nbase, &nbytes, histsize); +- if (nbase == NULL) +- return 1; +- if (nbase == oldbase) +- return 0; +- +- /* +- * create temp file +- */ +- (void) shf_snprintf(nfile, sizeof(nfile), "%s.%d", hname, procpid); +- if ((fd = open(nfile, O_CREAT | O_TRUNC | O_WRONLY, 0600)) < 0) +- return 1; ++ FILE *f = NULL; ++ int changed; + +- if (sprinkle(fd)) { +- close(fd); +- unlink(nfile); +- return 1; +- } +- if (write(fd, nbase, nbytes) != nbytes) { +- close(fd); +- unlink(nfile); +- return 1; +- } +- /* +- * worry about who owns this file +- */ +- if (fstat(histfd, &statb) >= 0) +- fchown(fd, statb.st_uid, statb.st_gid); +- close(fd); ++ if (Flag(FTALKING) == 0) ++ return; + +- /* +- * rename +- */ +- if (rename(nfile, hname) < 0) +- return 1; +- return 0; +-} ++ hstarted = 1; + ++ hist_source = s; + +-/* +- * find a pointer to the data `no' back from the end of the file +- * return the pointer and the number of bytes left +- */ +-static unsigned char * +-hist_skip_back(unsigned char *base, int *bytes, int no) +-{ +- int lines = 0; +- unsigned char *ep; ++ hname = str_val(global("HISTFILE")); ++ if (hname == NULL) ++ return; ++ hname = str_save(hname, APERM); + +- for (ep = base + *bytes; --ep > base; ) { +- /* this doesn't really work: the 4 byte line number that is +- * encoded after the COMMAND byte can itself contain the +- * COMMAND byte.... +- */ +- for (; ep > base && *ep != COMMAND; ep--) +- ; +- if (ep == base) +- break; +- if (++lines == no) { +- *bytes = *bytes - ((char *)ep - (char *)base); +- return ep; +- } +- } +- return NULL; +-} ++ f = history_open(&changed); ++ if (f == NULL) ++ return; + +-/* +- * load the history structure from the stored data +- */ +-static void +-histload(Source *s, unsigned char *base, int bytes) +-{ +- State state; +- int lno = 0; +- unsigned char *line = NULL; +- +- for (state = shdr; bytes-- > 0; base++) { +- switch (state) { +- case shdr: +- if (*base == COMMAND) +- state = sn1; +- break; +- case sn1: +- lno = (((*base)&0xff)<<24); +- state = sn2; +- break; +- case sn2: +- lno |= (((*base)&0xff)<<16); +- state = sn3; +- break; +- case sn3: +- lno |= (((*base)&0xff)<<8); +- state = sn4; +- break; +- case sn4: +- lno |= (*base)&0xff; +- line = base+1; +- state = sline; +- break; +- case sline: +- if (*base == '\0') { +- /* worry about line numbers */ +- if (histptr >= history && lno-1 != s->line) { +- /* a replacement ? */ +- histinsert(s, lno, line); +- } +- else { +- s->line = lno; +- s->cmd_offset = lno; +- histsave(lno, (char *)line, 0); +- } +- state = shdr; +- } +- } +- } ++ history_load(f, s); ++ history_close(f); + } + +-/* +- * Insert a line into the history at a specified number +- */ + static void +-histinsert(Source *s, int lno, unsigned char *line) ++writehistfile(FILE *f) + { +- char **hp; ++ int i; ++ char *cmd; + +- if (lno >= s->line-(histptr-history) && lno <= s->line) { +- hp = &histptr[lno-s->line]; +- if (*hp) +- afree((void*)*hp, APERM); +- *hp = str_save((char *)line, APERM); +- } +-} ++ if (ftruncate(fileno(f), 0) == -1) ++ return; ++ rewind(f); + +-/* +- * write a command to the end of the history file +- * This *MAY* seem easy but it's also necessary to check +- * that the history file has not changed in size. +- * If it has - then some other shell has written to it +- * and we should read those commands to update our history +- */ +-static void +-writehistfile(int lno, char *cmd) +-{ +- int sizenow; +- unsigned char *base; +- unsigned char *new; +- int bytes; +- unsigned char hdr[5]; +- +- (void) flock(histfd, LOCK_EX); +- sizenow = lseek(histfd, 0L, SEEK_END); +- if (sizenow != hsize) { +- /* +- * Things have changed +- */ +- if (sizenow > hsize) { +- /* someone has added some lines */ +- bytes = sizenow - hsize; +- base = (unsigned char *)mmap(0, sizenow, +- PROT_READ, MAP_FILE|MAP_PRIVATE, histfd, 0); +- if (base == MAP_FAILED) +- goto bad; +- new = base + hsize; +- if (*new != COMMAND) { +- munmap((caddr_t)base, sizenow); +- goto bad; +- } +- hist_source->line--; +- histload(hist_source, new, bytes); +- hist_source->line++; +- lno = hist_source->line; +- munmap((caddr_t)base, sizenow); +- hsize = sizenow; +- } else { +- /* it has shrunk */ +- /* but to what? */ +- /* we'll give up for now */ +- goto bad; +- } ++ for (i = 0; i < histsize; i++) { ++ cmd = history[i]; ++ if (cmd == NULL) ++ break; ++ if (fprintf(f, "%s\n", cmd) == -1) ++ return; + } +- /* +- * we can write our bit now +- */ +- hdr[0] = COMMAND; +- hdr[1] = (lno>>24)&0xff; +- hdr[2] = (lno>>16)&0xff; +- hdr[3] = (lno>>8)&0xff; +- hdr[4] = lno&0xff; +- (void) write(histfd, hdr, 5); +- (void) write(histfd, cmd, strlen(cmd)+1); +- hsize = lseek(histfd, 0L, SEEK_END); +- (void) flock(histfd, LOCK_UN); +- return; +-bad: +- hist_finish(); + } + + void + hist_finish(void) + { +- (void) flock(histfd, LOCK_UN); +- (void) close(histfd); +- histfd = 0; + } +- +-/* +- * add magic to the history file +- */ +-static int +-sprinkle(int fd) +-{ +- static unsigned char mag[] = { HMAGIC1, HMAGIC2 }; +- +- return(write(fd, mag, 2) != 2); +-} +- + #else /* HISTORY */ + + /* No history to be compiled in: dummy routines to avoid lots more ifdefs */ + diff --git a/system/ksh-openbsd/patches/09-escape_colon.diff b/system/ksh-openbsd/patches/09-escape_colon.diff deleted file mode 100644 index 77145e1505..0000000000 --- a/system/ksh-openbsd/patches/09-escape_colon.diff +++ /dev/null @@ -1,11 +0,0 @@ ---- edit.c.orig 2012-10-31 19:21:31.742319303 +0100 -+++ edit.c 2012-10-31 19:21:44.031181937 +0100 -@@ -809,7 +809,7 @@ - int rval = 0; - - for (add = 0, wlen = len; wlen - add > 0; add++) { -- if (strchr("\"#$&'()*;<=>?[\\]`{|}", s[add]) || -+ if (strchr("\"#$&'()*:;<=>?[\\]`{|}", s[add]) || - strchr(ifs, s[add])) { - if (putbuf_func(s, add) != 0) { - rval = -1; diff --git a/system/ksh-openbsd/patches/09-nobeep_option.diff b/system/ksh-openbsd/patches/09-nobeep_option.diff new file mode 100644 index 0000000000..d34a43d634 --- /dev/null +++ b/system/ksh-openbsd/patches/09-nobeep_option.diff @@ -0,0 +1,330 @@ +Index: emacs.c +=================================================================== +RCS file: /cvs/src/bin/ksh/emacs.c,v +retrieving revision 1.46 +diff -p -u -r1.46 emacs.c +--- emacs.c 10 Jun 2012 10:15:01 -0000 1.46 ++++ emacs.c 26 Nov 2012 14:25:51 -0000 +@@ -399,7 +399,8 @@ x_insert(int c) + * Should allow tab and control chars. + */ + if (c == 0) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return KSTD; + } + str[0] = c; +@@ -421,7 +422,8 @@ static int + x_do_ins(const char *cp, int len) + { + if (xep+len >= xend) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return -1; + } + +@@ -477,7 +479,8 @@ x_del_back(int c) + int col = xcp - xbuf; + + if (col == 0) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return KSTD; + } + if (x_arg > col) +@@ -493,7 +496,8 @@ x_del_char(int c) + int nleft = xep - xcp; + + if (!nleft) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return KSTD; + } + if (x_arg > nleft) +@@ -592,7 +596,8 @@ x_bword(void) + char *cp = xcp; + + if (cp == xbuf) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return 0; + } + while (x_arg--) { +@@ -616,7 +621,8 @@ x_fword(void) + char *cp = xcp; + + if (cp == xep) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return 0; + } + while (x_arg--) { +@@ -706,7 +712,8 @@ x_mv_back(int c) + int col = xcp - xbuf; + + if (col == 0) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return KSTD; + } + if (x_arg > col) +@@ -721,7 +728,8 @@ x_mv_forw(int c) + int nleft = xep - xcp; + + if (!nleft) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return KSTD; + } + if (x_arg > nleft) +@@ -741,7 +749,8 @@ x_search_char_forw(int c) + if (c < 0 || + ((cp = (cp == xep) ? NULL : strchr(cp + 1, c)) == NULL && + (cp = strchr(xbuf, c)) == NULL)) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return KSTD; + } + } +@@ -760,7 +769,8 @@ x_search_char_back(int c) + if (p-- == xbuf) + p = xep; + if (c < 0 || p == cp) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return KSTD; + } + if (*p == c) +@@ -818,7 +828,8 @@ x_load_hist(char **hp) + int oldsize; + + if (hp < history || hp > histptr) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return; + } + x_histp = hp; +@@ -902,7 +913,8 @@ x_search_hist(int c) + /* add char to pattern */ + /* overflow check... */ + if (p >= &pat[sizeof(pat) - 1]) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + continue; + } + *p++ = c, *p = '\0'; +@@ -943,7 +955,8 @@ x_search(char *pat, int sameline, int of + return i; + } + } +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + x_histp = histptr; + return -1; + } +@@ -1082,11 +1095,13 @@ x_transpose(int c) + * to the one they want. + */ + if (xcp == xbuf) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return KSTD; + } else if (xcp == xep || Flag(FGMACS)) { + if (xcp - xbuf == 1) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return KSTD; + } + /* Gosling/Unipress emacs style: Swap two characters before the +@@ -1207,7 +1222,8 @@ x_abort(int c) + static int + x_error(int c) + { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return KSTD; + } + +@@ -1624,7 +1640,8 @@ x_kill_region(int c) + char *xr; + + if (xmp == NULL) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return KSTD; + } + if (xmp > xcp) { +@@ -1646,7 +1663,8 @@ x_xchg_point_mark(int c) + char *tmp; + + if (xmp == NULL) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return KSTD; + } + tmp = xmp; +@@ -1749,7 +1767,8 @@ x_expand(int c) + &start, &end, &words, &is_command); + + if (nwords == 0) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return KSTD; + } + +@@ -1758,7 +1777,8 @@ x_expand(int c) + for (i = 0; i < nwords;) { + if (x_escape(words[i], strlen(words[i]), x_emacs_putbuf) < 0 || + (++i < nwords && x_ins(space) < 0)) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return KSTD; + } + } +@@ -1782,7 +1802,8 @@ do_complete(int flags, /* XCF_{COMMAND,F + &start, &end, &words, &is_command); + /* no match */ + if (nwords == 0) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return; + } + +@@ -1947,7 +1968,8 @@ x_set_arg(int c) + for (; c >= 0 && isdigit(c); c = x_e_getc(), first = 0) + n = n * 10 + (c - '0'); + if (c < 0 || first) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + x_arg = 1; + x_arg_defaulted = 1; + } else { +@@ -1969,7 +1991,8 @@ x_comment(int c) + int ret = x_do_comment(xbuf, xend - xbuf, &len); + + if (ret < 0) +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + else { + xep = xbuf + len; + *xep = '\0'; +@@ -2005,7 +2028,8 @@ x_prev_histword(int c) + + cp = *histptr; + if (!cp) +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + else if (x_arg_defaulted) { + rcp = &cp[strlen(cp) - 1]; + /* +@@ -2082,7 +2106,8 @@ x_fold_case(int c) + char *cp = xcp; + + if (cp == xep) { +- x_e_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_e_putc(BEL); + return KSTD; + } + while (x_arg--) { +Index: misc.c +=================================================================== +RCS file: /cvs/src/bin/ksh/misc.c,v +retrieving revision 1.37 +diff -p -u -r1.37 misc.c +--- misc.c 19 Apr 2009 20:34:05 -0000 1.37 ++++ misc.c 26 Nov 2012 14:25:51 -0000 +@@ -140,6 +140,7 @@ const struct option options[] = { + #else /* JOBS */ + { (char *) 0, 'm', 0 }, /* so FMONITOR not ifdef'd */ + #endif /* JOBS */ ++ { "nobeep", 0, OF_ANY }, + { "noclobber", 'C', OF_ANY }, + { "noexec", 'n', OF_ANY }, + { "noglob", 'f', OF_ANY }, +Index: sh.h +=================================================================== +RCS file: /cvs/src/bin/ksh/sh.h,v +retrieving revision 1.31 +diff -p -u -r1.31 sh.h +--- sh.h 10 Sep 2012 01:25:30 -0000 1.31 ++++ sh.h 26 Nov 2012 14:25:51 -0000 +@@ -185,6 +185,7 @@ enum sh_flag { + FLOGIN, /* -l: a login shell */ + FMARKDIRS, /* mark dirs with / in file name completion */ + FMONITOR, /* -m: job control monitoring */ ++ FNOBEEP, /* don't beep on bell */ + FNOCLOBBER, /* -C: don't overwrite existing files */ + FNOEXEC, /* -n: don't execute any commands */ + FNOGLOB, /* -f: don't do file globbing */ +Index: vi.c +=================================================================== +RCS file: /cvs/src/bin/ksh/vi.c,v +retrieving revision 1.26 +diff -p -u -r1.26 vi.c +--- vi.c 29 Jun 2009 22:50:19 -0000 1.26 ++++ vi.c 26 Nov 2012 14:25:51 -0000 +@@ -575,7 +575,12 @@ vi_insert(int ch) + es->cbuf[es->cursor] = undo->cbuf[es->cursor]; + } else { + if (es->cursor == 0) { +- /* x_putc(BEL); no annoying bell here */ ++ /* ++ * no annoying bell here ++ * ++ if (!Flag(FNOBEEP)) ++ x_putc(BEL); ++ */ + return 0; + } + if (inslen > 0) +@@ -2105,7 +2110,8 @@ vi_error(void) + { + /* Beem out of any macros as soon as an error occurs */ + vi_macro_reset(); +- x_putc(BEL); ++ if (!Flag(FNOBEEP)) ++ x_putc(BEL); + x_flush(); + } + +Index: ksh.1 +=================================================================== +RCS file: /cvs/src/bin/ksh/ksh.1,v +retrieving revision 1.144 +diff -p -u -r1.144 ksh.1 +--- ksh.1 8 Jul 2012 08:13:20 -0000 1.144 ++++ ksh.1 26 Nov 2012 19:44:32 -0000 +@@ -3705,6 +3704,8 @@ See above for a description of what this + The shell is a login shell. + This option can only be used when the shell is invoked. + See above for a description of what this means. ++.It Ic nobeep ++Do not beep on bell. + .It Ic nohup + Do not kill running jobs with a + .Dv SIGHUP diff --git a/system/ksh-openbsd/patches/10-new_history_implementation.diff b/system/ksh-openbsd/patches/10-new_history_implementation.diff deleted file mode 100644 index d083b42554..0000000000 --- a/system/ksh-openbsd/patches/10-new_history_implementation.diff +++ /dev/null @@ -1,584 +0,0 @@ -From: Marco Peereboom -To: tech@openbsd.org -Subject: ksh history corruption - -I have had enough of corrupt ksh history so I had a look at the code to -try to fix it. The magical code was very magical so I basically deleted -most of it and made ksh history into a flat text file. It handles -multiple ksh instances writing to the same text file with locks just -like the current ksh does. I haven't noticed any differences in -behavior running this. - -Code is much simpler and it shaves ~4k of the binary too. - -Index: alloc.c -=================================================================== -RCS file: /cvs/src/bin/ksh/alloc.c,v -retrieving revision 1.8 -diff -u -p -r1.8 alloc.c ---- alloc.c 21 Jul 2008 17:30:08 -0000 1.8 -+++ alloc.c 30 Aug 2011 18:05:47 -0000 -@@ -62,7 +62,7 @@ alloc(size_t size, Area *ap) - { - struct link *l; - -- l = malloc(sizeof(struct link) + size); -+ l = calloc(1, sizeof(struct link) + size); - if (l == NULL) - internal_errorf(1, "unable to allocate memory"); - l->next = ap->freelist; -Index: history.c -=================================================================== -RCS file: /cvs/src/bin/ksh/history.c,v -retrieving revision 1.39 -diff -u -p -r1.39 history.c ---- history.c 19 May 2010 17:36:08 -0000 1.39 -+++ history.c 31 Aug 2011 19:33:24 -0000 -@@ -11,8 +11,7 @@ - * a) the original in-memory history mechanism - * b) a more complicated mechanism done by pc@hillside.co.uk - * that more closely follows the real ksh way of doing -- * things. You need to have the mmap system call for this -- * to work on your system -+ * things. - */ - - #include "sh.h" -@@ -22,19 +21,10 @@ - # include - # include - --/* -- * variables for handling the data file -- */ --static int histfd; --static int hsize; -- --static int hist_count_lines(unsigned char *, int); --static int hist_shrink(unsigned char *, int); --static unsigned char *hist_skip_back(unsigned char *,int *,int); --static void histload(Source *, unsigned char *, int); --static void histinsert(Source *, int, unsigned char *); --static void writehistfile(int, char *); --static int sprinkle(int); -+static void writehistfile(FILE *); -+static FILE *history_open(int *); -+static int history_load(FILE *, Source *); -+static void history_close(FILE *); - - static int hist_execute(char *); - static int hist_replace(char **, const char *, const char *, int); -@@ -45,8 +35,8 @@ static void histbackup(void); - static char **current; /* current position in history[] */ - static char *hname; /* current name of history file */ - static int hstarted; /* set after hist_init() called */ --static Source *hist_source; -- -+static Source *hist_source; -+static struct stat last_sb; - - int - c_fc(char **wp) -@@ -529,15 +519,10 @@ sethistfile(const char *name) - /* if the name is the same as the name we have */ - if (hname && strcmp(hname, name) == 0) - return; -- - /* - * its a new name - possibly - */ -- if (histfd) { -- /* yes the file is open */ -- (void) close(histfd); -- histfd = 0; -- hsize = 0; -+ if (hname) { - afree(hname, APERM); - hname = NULL; - /* let's reset the history */ -@@ -577,18 +562,26 @@ init_histvec(void) - void - histsave(int lno, const char *cmd, int dowrite) - { -- char **hp; -- char *c, *cp; -+ char **hp; -+ char *c, *cp; -+ int changed; -+ FILE *f = NULL; -+ -+ if (dowrite) { -+ f = history_open(&changed); -+ if (f && changed) { -+ /* reset history */ -+ histptr = history - 1; -+ hist_source->line = 0; -+ history_load(f, hist_source); -+ } -+ } - - c = str_save(cmd, APERM); - if ((cp = strchr(c, '\n')) != NULL) - *cp = '\0'; - -- if (histfd && dowrite) -- writehistfile(lno, c); -- - hp = histptr; -- - if (++hp >= history + histsize) { /* remove oldest command */ - afree((void*)*history, APERM); - for (hp = history; hp < history + histsize - 1; hp++) -@@ -596,371 +589,125 @@ histsave(int lno, const char *cmd, int d - } - *hp = c; - histptr = hp; --} -- --/* -- * Write history data to a file nominated by HISTFILE -- * if HISTFILE is unset then history still happens, but -- * the data is not written to a file -- * All copies of ksh looking at the file will maintain the -- * same history. This is ksh behaviour. -- * -- * This stuff uses mmap() -- * if your system ain't got it - then you'll have to undef HISTORYFILE -- */ - --/* -- * Open a history file -- * Format is: -- * Bytes 1, 2: HMAGIC - just to check that we are dealing with -- * the correct object -- * Then follows a number of stored commands -- * Each command is -- * -- */ --#define HMAGIC1 0xab --#define HMAGIC2 0xcd --#define COMMAND 0xff -+ if (dowrite && f) { -+ writehistfile(f); -+ history_close(f); -+ } -+} - --void --hist_init(Source *s) -+static FILE * -+history_open(int *changed) - { -- unsigned char *base; -- int lines; -- int fd; -- -- if (Flag(FTALKING) == 0) -- return; -- -- hstarted = 1; -- -- hist_source = s; -- -- hname = str_val(global("HISTFILE")); -- if (hname == NULL) -- return; -- hname = str_save(hname, APERM); -+ int fd; -+ FILE *f = NULL; -+ struct stat sb; - -- retry: -- /* we have a file and are interactive */ -- if ((fd = open(hname, O_RDWR|O_CREAT|O_APPEND, 0600)) < 0) -- return; -- -- histfd = savefd(fd); -- if (histfd != fd) -+ if ((fd = open(hname, O_RDWR | O_CREAT | O_EXLOCK, 0600)) == -1) -+ return (NULL); -+ f = fdopen(fd, "r+"); -+ if (f == NULL) { - close(fd); -+ goto bad; -+ } - -- (void) flock(histfd, LOCK_EX); -+ if (fstat(fileno(f), &sb) == -1) -+ goto bad; -+ if (timespeccmp(&sb.st_mtim, &last_sb.st_mtim, ==)) -+ *changed = 0; -+ else -+ *changed = 1; - -- hsize = lseek(histfd, 0L, SEEK_END); -+ return (f); -+bad: -+ if (f) -+ fclose(f); - -- if (hsize == 0) { -- /* add magic */ -- if (sprinkle(histfd)) { -- hist_finish(); -- return; -- } -- } -- else if (hsize > 0) { -- /* -- * we have some data -- */ -- base = (unsigned char *)mmap(0, hsize, PROT_READ, -- MAP_FILE|MAP_PRIVATE, histfd, 0); -- /* -- * check on its validity -- */ -- if (base == MAP_FAILED || *base != HMAGIC1 || base[1] != HMAGIC2) { -- if (base != MAP_FAILED) -- munmap((caddr_t)base, hsize); -- hist_finish(); -- if (unlink(hname) != 0) -- return; -- goto retry; -- } -- if (hsize > 2) { -- lines = hist_count_lines(base+2, hsize-2); -- if (lines > histsize) { -- /* we need to make the file smaller */ -- if (hist_shrink(base, hsize)) -- if (unlink(hname) != 0) -- return; -- munmap((caddr_t)base, hsize); -- hist_finish(); -- goto retry; -- } -- } -- histload(hist_source, base+2, hsize-2); -- munmap((caddr_t)base, hsize); -- } -- (void) flock(histfd, LOCK_UN); -- hsize = lseek(histfd, 0L, SEEK_END); -+ return (NULL); - } - --typedef enum state { -- shdr, /* expecting a header */ -- sline, /* looking for a null byte to end the line */ -- sn1, /* bytes 1 to 4 of a line no */ -- sn2, sn3, sn4 --} State; -+static void -+history_close(FILE *f) -+{ -+ fflush(f); -+ fstat(fileno(f), &last_sb); -+ fclose(f); -+} - - static int --hist_count_lines(unsigned char *base, int bytes) -+history_load(FILE *f, Source *s) - { -- State state = shdr; -- int lines = 0; -+ char *p, line[LINE + 1]; -+ uint32_t i; - -- while (bytes--) { -- switch (state) { -- case shdr: -- if (*base == COMMAND) -- state = sn1; -+ /* just read it all; will auto resize history upon next command */ -+ for (i = 1; ; i++) { -+ p = fgets(line, sizeof line, f); -+ if (p == NULL || feof(f) || ferror(f)) - break; -- case sn1: -- state = sn2; break; -- case sn2: -- state = sn3; break; -- case sn3: -- state = sn4; break; -- case sn4: -- state = sline; break; -- case sline: -- if (*base == '\0') -- lines++, state = shdr; -+ if ((p = strchr(line, '\n')) == NULL) { -+ bi_errorf("history file is corrupt"); -+ return (1); - } -- base++; -+ *p = '\0'; -+ -+ s->line = i; -+ s->cmd_offset = i; -+ histsave(i, (char *)line, 0); - } -- return lines; -+ -+ return (0); - } - --/* -- * Shrink the history file to histsize lines -- */ --static int --hist_shrink(unsigned char *oldbase, int oldbytes) -+void -+hist_init(Source *s) - { -- int fd; -- char nfile[1024]; -- struct stat statb; -- unsigned char *nbase = oldbase; -- int nbytes = oldbytes; -- -- nbase = hist_skip_back(nbase, &nbytes, histsize); -- if (nbase == NULL) -- return 1; -- if (nbase == oldbase) -- return 0; -- -- /* -- * create temp file -- */ -- (void) shf_snprintf(nfile, sizeof(nfile), "%s.%d", hname, procpid); -- if ((fd = open(nfile, O_CREAT | O_TRUNC | O_WRONLY, 0600)) < 0) -- return 1; -+ FILE *f = NULL; -+ int changed; - -- if (sprinkle(fd)) { -- close(fd); -- unlink(nfile); -- return 1; -- } -- if (write(fd, nbase, nbytes) != nbytes) { -- close(fd); -- unlink(nfile); -- return 1; -- } -- /* -- * worry about who owns this file -- */ -- if (fstat(histfd, &statb) >= 0) -- fchown(fd, statb.st_uid, statb.st_gid); -- close(fd); -+ if (Flag(FTALKING) == 0) -+ return; - -- /* -- * rename -- */ -- if (rename(nfile, hname) < 0) -- return 1; -- return 0; --} -+ hstarted = 1; - -+ hist_source = s; - --/* -- * find a pointer to the data `no' back from the end of the file -- * return the pointer and the number of bytes left -- */ --static unsigned char * --hist_skip_back(unsigned char *base, int *bytes, int no) --{ -- int lines = 0; -- unsigned char *ep; -+ hname = str_val(global("HISTFILE")); -+ if (hname == NULL) -+ return; -+ hname = str_save(hname, APERM); - -- for (ep = base + *bytes; --ep > base; ) { -- /* this doesn't really work: the 4 byte line number that is -- * encoded after the COMMAND byte can itself contain the -- * COMMAND byte.... -- */ -- for (; ep > base && *ep != COMMAND; ep--) -- ; -- if (ep == base) -- break; -- if (++lines == no) { -- *bytes = *bytes - ((char *)ep - (char *)base); -- return ep; -- } -- } -- return NULL; --} -+ f = history_open(&changed); -+ if (f == NULL) -+ return; - --/* -- * load the history structure from the stored data -- */ --static void --histload(Source *s, unsigned char *base, int bytes) --{ -- State state; -- int lno = 0; -- unsigned char *line = NULL; -- -- for (state = shdr; bytes-- > 0; base++) { -- switch (state) { -- case shdr: -- if (*base == COMMAND) -- state = sn1; -- break; -- case sn1: -- lno = (((*base)&0xff)<<24); -- state = sn2; -- break; -- case sn2: -- lno |= (((*base)&0xff)<<16); -- state = sn3; -- break; -- case sn3: -- lno |= (((*base)&0xff)<<8); -- state = sn4; -- break; -- case sn4: -- lno |= (*base)&0xff; -- line = base+1; -- state = sline; -- break; -- case sline: -- if (*base == '\0') { -- /* worry about line numbers */ -- if (histptr >= history && lno-1 != s->line) { -- /* a replacement ? */ -- histinsert(s, lno, line); -- } -- else { -- s->line = lno; -- s->cmd_offset = lno; -- histsave(lno, (char *)line, 0); -- } -- state = shdr; -- } -- } -- } -+ history_load(f, s); -+ history_close(f); - } - --/* -- * Insert a line into the history at a specified number -- */ - static void --histinsert(Source *s, int lno, unsigned char *line) -+writehistfile(FILE *f) - { -- char **hp; -+ int i; -+ char *cmd; - -- if (lno >= s->line-(histptr-history) && lno <= s->line) { -- hp = &histptr[lno-s->line]; -- if (*hp) -- afree((void*)*hp, APERM); -- *hp = str_save((char *)line, APERM); -- } --} -+ if (ftruncate(fileno(f), 0) == -1) -+ return; -+ rewind(f); - --/* -- * write a command to the end of the history file -- * This *MAY* seem easy but it's also necessary to check -- * that the history file has not changed in size. -- * If it has - then some other shell has written to it -- * and we should read those commands to update our history -- */ --static void --writehistfile(int lno, char *cmd) --{ -- int sizenow; -- unsigned char *base; -- unsigned char *new; -- int bytes; -- unsigned char hdr[5]; -- -- (void) flock(histfd, LOCK_EX); -- sizenow = lseek(histfd, 0L, SEEK_END); -- if (sizenow != hsize) { -- /* -- * Things have changed -- */ -- if (sizenow > hsize) { -- /* someone has added some lines */ -- bytes = sizenow - hsize; -- base = (unsigned char *)mmap(0, sizenow, -- PROT_READ, MAP_FILE|MAP_PRIVATE, histfd, 0); -- if (base == MAP_FAILED) -- goto bad; -- new = base + hsize; -- if (*new != COMMAND) { -- munmap((caddr_t)base, sizenow); -- goto bad; -- } -- hist_source->line--; -- histload(hist_source, new, bytes); -- hist_source->line++; -- lno = hist_source->line; -- munmap((caddr_t)base, sizenow); -- hsize = sizenow; -- } else { -- /* it has shrunk */ -- /* but to what? */ -- /* we'll give up for now */ -- goto bad; -- } -+ for (i = 0; i < histsize; i++) { -+ cmd = history[i]; -+ if (cmd == NULL) -+ break; -+ if (fprintf(f, "%s\n", cmd) == -1) -+ return; - } -- /* -- * we can write our bit now -- */ -- hdr[0] = COMMAND; -- hdr[1] = (lno>>24)&0xff; -- hdr[2] = (lno>>16)&0xff; -- hdr[3] = (lno>>8)&0xff; -- hdr[4] = lno&0xff; -- (void) write(histfd, hdr, 5); -- (void) write(histfd, cmd, strlen(cmd)+1); -- hsize = lseek(histfd, 0L, SEEK_END); -- (void) flock(histfd, LOCK_UN); -- return; --bad: -- hist_finish(); - } - - void - hist_finish(void) - { -- (void) flock(histfd, LOCK_UN); -- (void) close(histfd); -- histfd = 0; - } -- --/* -- * add magic to the history file -- */ --static int --sprinkle(int fd) --{ -- static unsigned char mag[] = { HMAGIC1, HMAGIC2 }; -- -- return(write(fd, mag, 2) != 2); --} -- - #else /* HISTORY */ - - /* No history to be compiled in: dummy routines to avoid lots more ifdefs */ - diff --git a/system/ksh-openbsd/patches/11-nobeep_option.diff b/system/ksh-openbsd/patches/11-nobeep_option.diff deleted file mode 100644 index d34a43d634..0000000000 --- a/system/ksh-openbsd/patches/11-nobeep_option.diff +++ /dev/null @@ -1,330 +0,0 @@ -Index: emacs.c -=================================================================== -RCS file: /cvs/src/bin/ksh/emacs.c,v -retrieving revision 1.46 -diff -p -u -r1.46 emacs.c ---- emacs.c 10 Jun 2012 10:15:01 -0000 1.46 -+++ emacs.c 26 Nov 2012 14:25:51 -0000 -@@ -399,7 +399,8 @@ x_insert(int c) - * Should allow tab and control chars. - */ - if (c == 0) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return KSTD; - } - str[0] = c; -@@ -421,7 +422,8 @@ static int - x_do_ins(const char *cp, int len) - { - if (xep+len >= xend) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return -1; - } - -@@ -477,7 +479,8 @@ x_del_back(int c) - int col = xcp - xbuf; - - if (col == 0) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return KSTD; - } - if (x_arg > col) -@@ -493,7 +496,8 @@ x_del_char(int c) - int nleft = xep - xcp; - - if (!nleft) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return KSTD; - } - if (x_arg > nleft) -@@ -592,7 +596,8 @@ x_bword(void) - char *cp = xcp; - - if (cp == xbuf) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return 0; - } - while (x_arg--) { -@@ -616,7 +621,8 @@ x_fword(void) - char *cp = xcp; - - if (cp == xep) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return 0; - } - while (x_arg--) { -@@ -706,7 +712,8 @@ x_mv_back(int c) - int col = xcp - xbuf; - - if (col == 0) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return KSTD; - } - if (x_arg > col) -@@ -721,7 +728,8 @@ x_mv_forw(int c) - int nleft = xep - xcp; - - if (!nleft) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return KSTD; - } - if (x_arg > nleft) -@@ -741,7 +749,8 @@ x_search_char_forw(int c) - if (c < 0 || - ((cp = (cp == xep) ? NULL : strchr(cp + 1, c)) == NULL && - (cp = strchr(xbuf, c)) == NULL)) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return KSTD; - } - } -@@ -760,7 +769,8 @@ x_search_char_back(int c) - if (p-- == xbuf) - p = xep; - if (c < 0 || p == cp) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return KSTD; - } - if (*p == c) -@@ -818,7 +828,8 @@ x_load_hist(char **hp) - int oldsize; - - if (hp < history || hp > histptr) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return; - } - x_histp = hp; -@@ -902,7 +913,8 @@ x_search_hist(int c) - /* add char to pattern */ - /* overflow check... */ - if (p >= &pat[sizeof(pat) - 1]) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - continue; - } - *p++ = c, *p = '\0'; -@@ -943,7 +955,8 @@ x_search(char *pat, int sameline, int of - return i; - } - } -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - x_histp = histptr; - return -1; - } -@@ -1082,11 +1095,13 @@ x_transpose(int c) - * to the one they want. - */ - if (xcp == xbuf) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return KSTD; - } else if (xcp == xep || Flag(FGMACS)) { - if (xcp - xbuf == 1) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return KSTD; - } - /* Gosling/Unipress emacs style: Swap two characters before the -@@ -1207,7 +1222,8 @@ x_abort(int c) - static int - x_error(int c) - { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return KSTD; - } - -@@ -1624,7 +1640,8 @@ x_kill_region(int c) - char *xr; - - if (xmp == NULL) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return KSTD; - } - if (xmp > xcp) { -@@ -1646,7 +1663,8 @@ x_xchg_point_mark(int c) - char *tmp; - - if (xmp == NULL) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return KSTD; - } - tmp = xmp; -@@ -1749,7 +1767,8 @@ x_expand(int c) - &start, &end, &words, &is_command); - - if (nwords == 0) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return KSTD; - } - -@@ -1758,7 +1777,8 @@ x_expand(int c) - for (i = 0; i < nwords;) { - if (x_escape(words[i], strlen(words[i]), x_emacs_putbuf) < 0 || - (++i < nwords && x_ins(space) < 0)) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return KSTD; - } - } -@@ -1782,7 +1802,8 @@ do_complete(int flags, /* XCF_{COMMAND,F - &start, &end, &words, &is_command); - /* no match */ - if (nwords == 0) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return; - } - -@@ -1947,7 +1968,8 @@ x_set_arg(int c) - for (; c >= 0 && isdigit(c); c = x_e_getc(), first = 0) - n = n * 10 + (c - '0'); - if (c < 0 || first) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - x_arg = 1; - x_arg_defaulted = 1; - } else { -@@ -1969,7 +1991,8 @@ x_comment(int c) - int ret = x_do_comment(xbuf, xend - xbuf, &len); - - if (ret < 0) -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - else { - xep = xbuf + len; - *xep = '\0'; -@@ -2005,7 +2028,8 @@ x_prev_histword(int c) - - cp = *histptr; - if (!cp) -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - else if (x_arg_defaulted) { - rcp = &cp[strlen(cp) - 1]; - /* -@@ -2082,7 +2106,8 @@ x_fold_case(int c) - char *cp = xcp; - - if (cp == xep) { -- x_e_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_e_putc(BEL); - return KSTD; - } - while (x_arg--) { -Index: misc.c -=================================================================== -RCS file: /cvs/src/bin/ksh/misc.c,v -retrieving revision 1.37 -diff -p -u -r1.37 misc.c ---- misc.c 19 Apr 2009 20:34:05 -0000 1.37 -+++ misc.c 26 Nov 2012 14:25:51 -0000 -@@ -140,6 +140,7 @@ const struct option options[] = { - #else /* JOBS */ - { (char *) 0, 'm', 0 }, /* so FMONITOR not ifdef'd */ - #endif /* JOBS */ -+ { "nobeep", 0, OF_ANY }, - { "noclobber", 'C', OF_ANY }, - { "noexec", 'n', OF_ANY }, - { "noglob", 'f', OF_ANY }, -Index: sh.h -=================================================================== -RCS file: /cvs/src/bin/ksh/sh.h,v -retrieving revision 1.31 -diff -p -u -r1.31 sh.h ---- sh.h 10 Sep 2012 01:25:30 -0000 1.31 -+++ sh.h 26 Nov 2012 14:25:51 -0000 -@@ -185,6 +185,7 @@ enum sh_flag { - FLOGIN, /* -l: a login shell */ - FMARKDIRS, /* mark dirs with / in file name completion */ - FMONITOR, /* -m: job control monitoring */ -+ FNOBEEP, /* don't beep on bell */ - FNOCLOBBER, /* -C: don't overwrite existing files */ - FNOEXEC, /* -n: don't execute any commands */ - FNOGLOB, /* -f: don't do file globbing */ -Index: vi.c -=================================================================== -RCS file: /cvs/src/bin/ksh/vi.c,v -retrieving revision 1.26 -diff -p -u -r1.26 vi.c ---- vi.c 29 Jun 2009 22:50:19 -0000 1.26 -+++ vi.c 26 Nov 2012 14:25:51 -0000 -@@ -575,7 +575,12 @@ vi_insert(int ch) - es->cbuf[es->cursor] = undo->cbuf[es->cursor]; - } else { - if (es->cursor == 0) { -- /* x_putc(BEL); no annoying bell here */ -+ /* -+ * no annoying bell here -+ * -+ if (!Flag(FNOBEEP)) -+ x_putc(BEL); -+ */ - return 0; - } - if (inslen > 0) -@@ -2105,7 +2110,8 @@ vi_error(void) - { - /* Beem out of any macros as soon as an error occurs */ - vi_macro_reset(); -- x_putc(BEL); -+ if (!Flag(FNOBEEP)) -+ x_putc(BEL); - x_flush(); - } - -Index: ksh.1 -=================================================================== -RCS file: /cvs/src/bin/ksh/ksh.1,v -retrieving revision 1.144 -diff -p -u -r1.144 ksh.1 ---- ksh.1 8 Jul 2012 08:13:20 -0000 1.144 -+++ ksh.1 26 Nov 2012 19:44:32 -0000 -@@ -3705,6 +3704,8 @@ See above for a description of what this - The shell is a login shell. - This option can only be used when the shell is invoked. - See above for a description of what this means. -+.It Ic nobeep -+Do not beep on bell. - .It Ic nohup - Do not kill running jobs with a - .Dv SIGHUP -- cgit v1.2.3