15155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* $OpenBSD: history.c,v 1.39 2010/05/19 17:36:08 jasper Exp $ */ 25155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* $OpenBSD: trap.c,v 1.23 2010/05/19 17:36:08 jasper Exp $ */ 35155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 45155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*- 55155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Copyright (c) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010 65155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Thorsten Glaser <tg@mirbsd.org> 75155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 85155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Provided that these terms and disclaimer and all copyright notices 95155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * are retained or reproduced in an accompanying document, permission 105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * is granted to deal in this work without restriction, including un- 115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * limited rights to use, publicly perform, distribute, sell, modify, 125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * merge, give away, or sublicence. 135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This work is provided "AS IS" and WITHOUT WARRANTY of any kind, to 155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the utmost extent permitted by applicable law, neither express nor 165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * implied; without malicious intent or gross negligence. In no event 175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * may a licensor, author or contributor be held liable for indirect, 185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * direct, other damage, loss, or other issues arising in any way out 195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of dealing in the work, even if advised of the possibility of such 205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * damage or existence of a defect, except proven that it results out 215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * of said person's immediate fault when using the work as intended. 225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include "sh.h" 255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_PERSISTENT_HISTORY 265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include <sys/file.h> 275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru__RCSID("$MirOS: src/bin/mksh/histrap.c,v 1.98 2010/07/24 17:08:29 tg Exp $"); 305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/*- 325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * MirOS: This is the default mapping type, and need not be specified. 335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * IRIX doesn't have this constant. 345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#ifndef MAP_FILE 365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define MAP_FILE 0 375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste QueruTrap sigtraps[NSIG + 1]; 405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic struct sigaction Sigact_ign; 415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_PERSISTENT_HISTORY 435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int hist_count_lines(unsigned char *, int); 445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int hist_shrink(unsigned char *, int); 455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic unsigned char *hist_skip_back(unsigned char *,int *,int); 465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void histload(Source *, unsigned char *, int); 475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void histinsert(Source *, int, const char *); 485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void writehistfile(int, char *); 495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int sprinkle(int); 505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int hist_execute(char *); 535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int hist_replace(char **, const char *, const char *, bool); 545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char **hist_get(const char *, bool, bool); 555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char **hist_get_oldest(void); 565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void histbackup(void); 575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char **current; /* current position in history[] */ 595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int hstarted; /* set after hist_init() called */ 605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic Source *hist_source; 615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_PERSISTENT_HISTORY 635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char *hname; /* current name of history file */ 645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int histfd; 655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int hsize; 665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruc_fc(const char **wp) 705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct shf *shf; 725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct temp *tf; 735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *p; 745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *editor = NULL; 755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool gflag = false, lflag = false, nflag = false, rflag = false, 765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sflag = false; 775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int optc; 785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *first = NULL, *last = NULL; 795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char **hfirst, **hlast, **hp; 805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!Flag(FTALKING_I)) { 825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("history functions not available"); 835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((optc = ksh_getopt(wp, &builtin_opt, 875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru "e:glnrs0,1,2,3,4,5,6,7,8,9,")) != -1) 885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (optc) { 895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'e': 905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = builtin_opt.optarg; 915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_isdash(p)) 925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sflag = true; 935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru size_t len = strlen(p); 955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru editor = alloc(len + 4, ATEMP); 965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(editor, p, len); 975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(editor + len, " $_", 4); 985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 1005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'g': /* non-AT&T ksh */ 1015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru gflag = true; 1025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 1035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'l': 1045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru lflag = true; 1055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 1065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'n': 1075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nflag = true; 1085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 1095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 'r': 1105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rflag = true; 1115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 1125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case 's': /* POSIX version of -e - */ 1135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sflag = true; 1145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 1155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* kludge city - accept -num as -- -num (kind of) */ 1165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '0': case '1': case '2': case '3': case '4': 1175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '5': case '6': case '7': case '8': case '9': 1185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p = shf_smprintf("-%c%s", 1195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru optc, builtin_opt.optarg); 1205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!first) 1215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru first = p; 1225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (!last) 1235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru last = p; 1245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 1255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("too many arguments"); 1265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 1275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 1295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case '?': 1305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 1315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp += builtin_opt.optind; 1335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Substitute and execute command */ 1355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (sflag) { 1365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *pat = NULL, *rep = NULL; 1375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (editor || lflag || nflag || rflag) { 1395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("can't use -e, -l, -n, -r with -s (-e -)"); 1405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 1415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Check for pattern replacement argument */ 1445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp && **wp && (p = cstrchr(*wp + 1, '='))) { 1455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(pat, *wp, ATEMP); 1465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rep = pat + (p - *wp); 1475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *rep++ = '\0'; 1485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 1495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Check for search prefix */ 1515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!first && (first = *wp)) 1525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 1535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (last || *wp) { 1545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("too many arguments"); 1555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 1565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hp = first ? hist_get(first, false, false) : 1595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_get_newest(false); 1605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!hp) 1615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 1625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (hist_replace(hp, pat, rep, gflag)); 1635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (editor && (lflag || nflag)) { 1665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("can't use -l, -n with -e"); 1675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 1685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 1705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!first && (first = *wp)) 1715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 1725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!last && (last = *wp)) 1735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru wp++; 1745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*wp) { 1755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("too many arguments"); 1765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 1775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!first) { 1795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hfirst = lflag ? hist_get("-16", true, true) : 1805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_get_newest(false); 1815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!hfirst) 1825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 1835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* can't fail if hfirst didn't fail */ 1845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hlast = hist_get_newest(false); 1855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 1865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* POSIX says not an error if first/last out of bounds 1875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * when range is specified; AT&T ksh and pdksh allow out of 1885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * bounds for -l as well. 1895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 1905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hfirst = hist_get(first, (lflag || last) ? true : false, lflag); 1915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!hfirst) 1925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 1935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hlast = last ? hist_get(last, true, lflag) : 1945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (lflag ? hist_get_newest(false) : hfirst); 1955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!hlast) 1965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 1975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 1985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (hfirst > hlast) { 1995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char **temp; 2005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru temp = hfirst; hfirst = hlast; hlast = temp; 2025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rflag = !rflag; /* POSIX */ 2035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* List history */ 2065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (lflag) { 2075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *s, *t; 2085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (hp = rflag ? hlast : hfirst; 2105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hp >= hfirst && hp <= hlast; hp += rflag ? -1 : 1) { 2115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!nflag) 2125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fprintf(shl_stdout, "%d", 2135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_source->line - (int)(histptr - hp)); 2145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_putc('\t', shl_stdout); 2155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* print multi-line commands correctly */ 2165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = *hp; 2175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((t = strchr(s, '\n'))) { 2185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *t = '\0'; 2195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fprintf(shl_stdout, "%s\n\t", s); 2205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *t++ = '\n'; 2215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = t; 2225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fprintf(shl_stdout, "%s\n", s); 2245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_flush(shl_stdout); 2265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 2275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Run editor on selected lines, then run resulting commands */ 2305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tf = maketemp(ATEMP, TT_HIST_EDIT, &e->temps); 2325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(shf = tf->shf)) { 2335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("cannot create temp file %s - %s", 2345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tf->name, strerror(errno)); 2355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 2365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (hp = rflag ? hlast : hfirst; 2385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hp >= hfirst && hp <= hlast; hp += rflag ? -1 : 1) 2395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_fprintf(shf, "%s\n", *hp); 2405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (shf_close(shf) == EOF) { 2415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("error writing temporary file - %s", strerror(errno)); 2425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 2435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Ignore setstr errors here (arbitrary) */ 2465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setstr(local("_", false), tf->name, KSH_RETURN_ERROR); 2475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* XXX: source should not get trashed by this.. */ 2495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { 2505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *sold = source; 2515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int ret; 2525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ret = command(editor ? editor : "${FCEDIT:-/bin/ed} $_", 0); 2545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = sold; 2555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ret) 2565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (ret); 2575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { 2605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct stat statb; 2615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XString xs; 2625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xp; 2635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int n; 2645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(shf = shf_open(tf->name, O_RDONLY, 0, 0))) { 2665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("cannot open temp file %s", tf->name); 2675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 2685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n = stat(tf->name, &statb) < 0 ? 128 : statb.st_size + 1; 2715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xinit(xs, xp, n, hist_source->areap); 2725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((n = shf_read(xp, Xnleft(xs, xp), shf)) > 0) { 2735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp += n; 2745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Xnleft(xs, xp) <= 0) 2755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XcheckN(xs, xp, Xlength(xs, xp)); 2765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n < 0) { 2785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("error reading temp file %s - %s", 2795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru tf->name, strerror(shf_errno(shf))); 2805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_close(shf); 2815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 2825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shf_close(shf); 2845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *xp = '\0'; 2855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strip_nuls(Xstring(xs, xp), Xlength(xs, xp)); 2865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (hist_execute(Xstring(xs, xp))); 2875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 2885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 2895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Save cmd in history, execute cmd (cmd gets trashed) */ 2915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 2925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhist_execute(char *cmd) 2935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 2945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Source *sold; 2955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int ret; 2965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *p, *q; 2975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 2985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histbackup(); 2995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = cmd; p; p = q) { 3015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((q = strchr(p, '\n'))) { 3025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *q++ = '\0'; /* kill the newline */ 3035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!*q) /* ignore trailing newline */ 3045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru q = NULL; 3055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histsave(&hist_source->line, p, true, true); 3075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shellf("%s\n", p); /* POSIX doesn't say this is done... */ 3095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (q) /* restore \n (trailing \n not restored) */ 3105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru q[-1] = '\n'; 3115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 3145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Commands are executed here instead of pushing them onto the 3155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * input 'cause POSIX says the redirection and variable assignments 3165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * in 3175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * X=y fc -e - 42 2> /dev/null 3185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * are to effect the repeated commands environment. 3195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 3205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* XXX: source should not get trashed by this.. */ 3215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sold = source; 3225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ret = command(cmd, 0); 3235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru source = sold; 3245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (ret); 3255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 3265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 3285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhist_replace(char **hp, const char *pat, const char *rep, bool globr) 3295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 3305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *line; 3315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!pat) 3335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(line, *hp, ATEMP); 3345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 3355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *s, *s1; 3365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int pat_len = strlen(pat); 3375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rep_len = strlen(rep); 3385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int len; 3395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XString xs; 3405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *xp; 3415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool any_subst = false; 3425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Xinit(xs, xp, 128, ATEMP); 3445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (s = *hp; (s1 = strstr(s, pat)) && (!any_subst || globr); 3455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s = s1 + pat_len) { 3465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru any_subst = true; 3475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru len = s1 - s; 3485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XcheckN(xs, xp, len + rep_len); 3495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(xp, s, len); /* first part */ 3505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp += len; 3515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(xp, rep, rep_len); /* replacement */ 3525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp += rep_len; 3535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!any_subst) { 3555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("substitution failed"); 3565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 3575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru len = strlen(s) + 1; 3595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru XcheckN(xs, xp, len); 3605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memcpy(xp, s, len); 3615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru xp += len; 3625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru line = Xclose(xs, xp); 3635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (hist_execute(line)); 3655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 3665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 3685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * get pointer to history given pattern 3695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * pattern is a number or string 3705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 3715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char ** 3725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhist_get(const char *str, bool approx, bool allow_cur) 3735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 3745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char **hp = NULL; 3755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int n; 3765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 3775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (getn(str, &n)) { 3785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hp = histptr + (n < 0 ? n : (n - hist_source->line)); 3795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((ptrdiff_t)hp < (ptrdiff_t)history) { 3805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (approx) 3815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hp = hist_get_oldest(); 3825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 3835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("%s: not in history", str); 3845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hp = NULL; 3855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if ((ptrdiff_t)hp > (ptrdiff_t)histptr) { 3875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (approx) 3885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hp = hist_get_newest(allow_cur); 3895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 3905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("%s: not in history", str); 3915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hp = NULL; 3925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (!allow_cur && hp == histptr) { 3945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("%s: invalid range", str); 3955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hp = NULL; 3965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 3975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 3985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int anchored = *str == '?' ? (++str, 0) : 1; 3995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* the -1 is to avoid the current fc command */ 4015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((n = findhist(histptr - history - 1, 0, str, anchored)) < 0) 4025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("%s: not in history", str); 4035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 4045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hp = &history[n]; 4055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (hp); 4075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Return a pointer to the newest command in the history */ 4105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar ** 4115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhist_get_newest(bool allow_cur) 4125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (histptr < history || (!allow_cur && histptr == history)) { 4145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("no history (yet)"); 4155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 4165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (allow_cur ? histptr : histptr - 1); 4185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Return a pointer to the oldest command in the history */ 4215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic char ** 4225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhist_get_oldest(void) 4235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (histptr <= history) { 4255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("no history (yet)"); 4265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 4275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (history); 4295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/******************************/ 4325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Back up over last histsave */ 4335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/******************************/ 4345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 4355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhistbackup(void) 4365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru static int last_line = -1; 4385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (histptr >= history && last_line != hist_source->line) { 4405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_source->line--; 4415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(*histptr, APERM); 4425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histptr--; 4435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru last_line = hist_source->line; 4445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 4485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Return the current position. 4495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 4505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruchar ** 4515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhistpos(void) 4525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (current); 4545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 4575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhistnum(int n) 4585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int last = histptr - history; 4605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n < 0 || n >= last) { 4625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru current = histptr; 4635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (last); 4645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 4655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru current = &history[n]; 4665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (n); 4675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 4685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 4715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This will become unnecessary if hist_get is modified to allow 4725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * searching from positions other than the end, and in either 4735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * direction. 4745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 4755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 4765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querufindhist(int start, int fwd, const char *str, int anchored) 4775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char **hp; 4795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int maxhist = histptr - history; 4805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int incr = fwd ? 1 : -1; 4815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int len = strlen(str); 4825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (start < 0 || start >= maxhist) 4845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru start = maxhist; 4855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hp = &history[start]; 4875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; hp >= history && hp <= histptr; hp += incr) 4885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((anchored && strncmp(*hp, str, len) == 0) || 4895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (!anchored && strstr(*hp, str))) 4905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (hp - history); 4915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 4935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 4945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 4955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 4965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querufindhistrel(const char *str) 4975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 4985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int maxhist = histptr - history; 4995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int start = maxhist - 1; 5005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int rec; 5015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru getn(str, &rec); 5035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rec == 0) 5045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 5055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rec > 0) { 5065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rec > maxhist) 5075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 5085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rec - 1); 5095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rec > maxhist) 5115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (-1); 5125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (start + rec + 1); 5135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 5145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 5165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * set history 5175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this means reallocating the dataspace 5185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 5195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 5205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusethistsize(int n) 5215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 5225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n > 0 && n != histsize) { 5235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int cursize = histptr - history; 5245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* save most recent history */ 5265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (n < cursize) { 5275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru memmove(history, histptr - n, n * sizeof(char *)); 5285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cursize = n; 5295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru history = aresize(history, n * sizeof(char *), APERM); 5325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histsize = n; 5345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histptr = history + cursize; 5355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 5375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_PERSISTENT_HISTORY 5395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 5405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * set history file 5415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This can mean reloading/resetting/starting history file 5425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * maintenance 5435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 5445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 5455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusethistfile(const char *name) 5465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 5475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* if not started then nothing to do */ 5485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (hstarted == 0) 5495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 5505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* if the name is the same as the name we have */ 5525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (hname && strcmp(hname, name) == 0) 5535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 5545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 5565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * its a new name - possibly 5575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 5585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (histfd) { 5595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* yes the file is open */ 5605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (void)close(histfd); 5615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histfd = 0; 5625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hsize = 0; 5635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(hname, APERM); 5645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hname = NULL; 5655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* let's reset the history */ 5665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histptr = history - 1; 5675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_source->line = 0; 5685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_init(hist_source); 5715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 5725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 5735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 5755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * initialise the history vector 5765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 5775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 5785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruinit_histvec(void) 5795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 5805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (history == (char **)NULL) { 5815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histsize = HISTORYSIZE; 5825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru history = alloc(histsize * sizeof(char *), APERM); 5835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histptr = history - 1; 5845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 5855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 5865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 5895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Routines added by Peter Collinson BSDI(Europe)/Hillside Systems to 5905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * a) permit HISTSIZE to control number of lines of history stored 5915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * b) maintain a physical history file 5925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 5935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * It turns out that there is a lot of ghastly hackery here 5945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 5955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 5965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY 5975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* do not save command in history but possibly sync */ 5985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querubool 5995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhistsync(void) 6005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 6015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bool changed = false; 6025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (histfd) { 6045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int lno = hist_source->line; 6055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_source->line++; 6075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru writehistfile(0, NULL); 6085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_source->line--; 6095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (lno != hist_source->line) 6115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru changed = true; 6125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (changed); 6155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 6165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 6175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 6195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * save command in history 6205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 6225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhistsave(int *lnp, const char *cmd, bool dowrite MKSH_A_UNUSED, bool ignoredups) 6235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 6245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char **hp; 6255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *c, *cp; 6265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(c, cmd, APERM); 6285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cp = strchr(c, '\n')) != NULL) 6295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *cp = '\0'; 6305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ignoredups && !strcmp(c, *histptr) 6325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !defined(MKSH_SMALL) && HAVE_PERSISTENT_HISTORY 6335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru && !histsync() 6345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 6355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ) { 6365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(c, APERM); 6375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 6385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++*lnp; 6405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_PERSISTENT_HISTORY 6425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (histfd && dowrite) 6435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru writehistfile(*lnp, c); 6445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 6455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hp = histptr; 6475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (++hp >= history + histsize) { /* remove oldest command */ 6495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(*history, APERM); 6505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (hp = history; hp < history + histsize - 1; hp++) 6515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hp[0] = hp[1]; 6525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 6535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *hp = c; 6545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histptr = hp; 6555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 6565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 6585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Write history data to a file nominated by HISTFILE 6595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * if HISTFILE is unset then history still happens, but 6605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the data is not written to a file 6615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * All copies of ksh looking at the file will maintain the 6625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * same history. This is ksh behaviour. 6635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * 6645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This stuff uses mmap() 6655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * if your system ain't got it - then you'll have to undef HISTORYFILE 6665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 6695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Open a history file 6705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Format is: 6715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Bytes 1, 2: 6725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * HMAGIC - just to check that we are dealing with 6735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the correct object 6745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Then follows a number of stored commands 6755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Each command is 6765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * <command byte><command number(4 bytes)><bytes><null> 6775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 6785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define HMAGIC1 0xab 6795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define HMAGIC2 0xcd 6805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#define COMMAND 0xff 6815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 6835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhist_init(Source *s) 6845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 6855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_PERSISTENT_HISTORY 6865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char *base; 6875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int lines, fd, rv = 0; 6885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 6895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (Flag(FTALKING) == 0) 6915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 6925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hstarted = 1; 6945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_source = s; 6965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 6975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_PERSISTENT_HISTORY 6985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((hname = str_val(global("HISTFILE"))) == NULL) 6995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 7005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(hname, hname, APERM); 7015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru retry: 7035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* we have a file and are interactive */ 7045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((fd = open(hname, O_RDWR|O_CREAT|O_APPEND, 0600)) < 0) 7055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 7065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histfd = savefd(fd); 7085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (histfd != fd) 7095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(fd); 7105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (void)flock(histfd, LOCK_EX); 7125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hsize = lseek(histfd, (off_t)0, SEEK_END); 7145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (hsize == 0) { 7165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* add magic */ 7175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (sprinkle(histfd)) { 7185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_finish(); 7195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 7205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (hsize > 0) { 7225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 7235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * we have some data 7245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru base = (void *)mmap(NULL, hsize, PROT_READ, 7265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru MAP_FILE | MAP_PRIVATE, histfd, (off_t)0); 7275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 7285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * check on its validity 7295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 7305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (base == (unsigned char *)MAP_FAILED || 7315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *base != HMAGIC1 || base[1] != HMAGIC2) { 7325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (base != (unsigned char *)MAP_FAILED) 7335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru munmap((caddr_t)base, hsize); 7345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_finish(); 7355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (unlink(hname) /* fails */) 7365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto hiniterr; 7375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto retry; 7385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (hsize > 2) { 7405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru lines = hist_count_lines(base+2, hsize-2); 7415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (lines > histsize) { 7425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* we need to make the file smaller */ 7435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (hist_shrink(base, hsize)) 7445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = unlink(hname); 7455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru munmap((caddr_t)base, hsize); 7465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_finish(); 7475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rv) { 7485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hiniterr: 7495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bi_errorf("cannot unlink HISTFILE %s" 7505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru " - %s", hname, strerror(errno)); 7515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hsize = 0; 7525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 7535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto retry; 7555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histload(hist_source, base+2, hsize-2); 7585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru munmap((caddr_t)base, hsize); 7595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (void)flock(histfd, LOCK_UN); 7615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hsize = lseek(histfd, (off_t)0, SEEK_END); 7625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 7635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 7645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_PERSISTENT_HISTORY 7665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutypedef enum state { 7675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru shdr, /* expecting a header */ 7685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sline, /* looking for a null byte to end the line */ 7695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sn1, /* bytes 1 to 4 of a line no */ 7705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sn2, sn3, sn4 7715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} State; 7725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 7745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhist_count_lines(unsigned char *base, int bytes) 7755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 7765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru State state = shdr; 7775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int lines = 0; 7785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 7795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while (bytes--) { 7805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (state) { 7815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case shdr: 7825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*base == COMMAND) 7835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = sn1; 7845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 7855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case sn1: 7865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = sn2; break; 7875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case sn2: 7885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = sn3; break; 7895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case sn3: 7905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = sn4; break; 7915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case sn4: 7925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = sline; break; 7935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case sline: 7945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*base == '\0') { 7955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru lines++; 7965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = shdr; 7975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 7995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru base++; 8005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (lines); 8025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 8035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 8055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Shrink the history file to histsize lines 8065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 8085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhist_shrink(unsigned char *oldbase, int oldbytes) 8095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 8105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int fd, rv = 0; 8115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *nfile = NULL; 8125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct stat statb; 8135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char *nbase = oldbase; 8145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int nbytes = oldbytes; 8155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nbase = hist_skip_back(nbase, &nbytes, histsize); 8175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (nbase == NULL) 8185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 8195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (nbase == oldbase) 8205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 8215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 8235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * create temp file 8245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru nfile = shf_smprintf("%s.%d", hname, (int)procpid); 8265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((fd = open(nfile, O_CREAT | O_TRUNC | O_WRONLY, 0600)) < 0) 8275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto errout; 8285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fstat(histfd, &statb) >= 0 && 8295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru chown(nfile, statb.st_uid, statb.st_gid)) 8305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto errout; 8315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (sprinkle(fd) || write(fd, nbase, nbytes) != nbytes) 8335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto errout; 8345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(fd); 8355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fd = -1; 8365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 8385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * rename 8395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (rename(nfile, hname) < 0) { 8415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errout: 8425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (fd >= 0) { 8435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru close(fd); 8445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (nfile) 8455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unlink(nfile); 8465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru rv = 1; 8485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(nfile, ATEMP); 8505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (rv); 8515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 8525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 8545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * find a pointer to the data 'no' back from the end of the file 8555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * return the pointer and the number of bytes left 8565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic unsigned char * 8585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhist_skip_back(unsigned char *base, int *bytes, int no) 8595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 8605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int lines = 0; 8615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char *ep; 8625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (ep = base + *bytes; --ep > base; ) { 8645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 8655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * this doesn't really work: the 4 byte line number that 8665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * is encoded after the COMMAND byte can itself contain 8675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * the COMMAND byte.... 8685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (; ep > base && *ep != COMMAND; ep--) 8705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ; 8715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ep == base) 8725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (++lines == no) { 8745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru *bytes = *bytes - ((char *)ep - (char *)base); 8755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (ep); 8765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 8785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 8795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 8805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 8825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * load the history structure from the stored data 8835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 8845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 8855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhistload(Source *s, unsigned char *base, int bytes) 8865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 8875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru State state; 8885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int lno = 0; 8895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char *line = NULL; 8905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 8915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (state = shdr; bytes-- > 0; base++) { 8925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (state) { 8935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case shdr: 8945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*base == COMMAND) 8955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = sn1; 8965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 8975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case sn1: 8985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru lno = (((*base)&0xff)<<24); 8995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = sn2; 9005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 9015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case sn2: 9025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru lno |= (((*base)&0xff)<<16); 9035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = sn3; 9045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 9055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case sn3: 9065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru lno |= (((*base)&0xff)<<8); 9075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = sn4; 9085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 9095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case sn4: 9105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru lno |= (*base)&0xff; 9115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru line = base+1; 9125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = sline; 9135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 9145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case sline: 9155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*base == '\0') { 9165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* worry about line numbers */ 9175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (histptr >= history && lno-1 != s->line) { 9185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* a replacement ? */ 9195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histinsert(s, lno, (char *)line); 9205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 9215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru s->line = lno--; 9225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histsave(&lno, (char *)line, false, 9235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru false); 9245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru state = shdr; 9265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 9305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 9325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Insert a line into the history at a specified number 9335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 9355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhistinsert(Source *s, int lno, const char *line) 9365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 9375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char **hp; 9385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (lno >= s->line - (histptr - history) && lno <= s->line) { 9405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hp = &histptr[lno - s->line]; 9415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*hp) 9425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(*hp, APERM); 9435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(*hp, line, APERM); 9445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 9465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 9485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * write a command to the end of the history file 9495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This *MAY* seem easy but it's also necessary to check 9505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * that the history file has not changed in size. 9515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * If it has - then some other shell has written to it 9525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * and we should read those commands to update our history 9535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 9555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruwritehistfile(int lno, char *cmd) 9565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 9575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int sizenow; 9585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char *base; 9595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char *news; 9605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int bytes; 9615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unsigned char hdr[5]; 9625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 9635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (void)flock(histfd, LOCK_EX); 9645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sizenow = lseek(histfd, (off_t)0, SEEK_END); 9655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (sizenow != hsize) { 9665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 9675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Things have changed 9685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (sizenow > hsize) { 9705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* someone has added some lines */ 9715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bytes = sizenow - hsize; 9725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru base = (void *)mmap(NULL, sizenow, PROT_READ, 9735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru MAP_FILE | MAP_PRIVATE, histfd, (off_t)0); 9745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (base == (unsigned char *)MAP_FAILED) 9755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto bad; 9765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru news = base + hsize; 9775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (*news != COMMAND) { 9785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru munmap((caddr_t)base, sizenow); 9795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto bad; 9805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_source->line--; 9825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histload(hist_source, news, bytes); 9835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_source->line++; 9845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru lno = hist_source->line; 9855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru munmap((caddr_t)base, sizenow); 9865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hsize = sizenow; 9875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 9885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* it has shrunk */ 9895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* but to what? */ 9905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* we'll give up for now */ 9915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto bad; 9925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 9945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (cmd) { 9955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 9965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * we can write our bit now 9975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 9985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hdr[0] = COMMAND; 9995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hdr[1] = (lno>>24)&0xff; 10005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hdr[2] = (lno>>16)&0xff; 10015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hdr[3] = (lno>>8)&0xff; 10025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hdr[4] = lno&0xff; 10035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bytes = strlen(cmd) + 1; 10045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((write(histfd, hdr, 5) != 5) || 10055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (write(histfd, cmd, bytes) != bytes)) 10065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru goto bad; 10075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hsize = lseek(histfd, (off_t)0, SEEK_END); 10085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (void)flock(histfd, LOCK_UN); 10105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 10115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru bad: 10125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru hist_finish(); 10135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 10165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruhist_finish(void) 10175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (void)flock(histfd, LOCK_UN); 10195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (void)close(histfd); 10205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru histfd = 0; 10215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 10245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * add magic to the history file 10255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 10265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic int 10275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusprinkle(int fd) 10285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru static const unsigned char mag[] = { HMAGIC1, HMAGIC2 }; 10305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (write(fd, mag, 2) != 2); 10325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 10335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 10345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if !HAVE_SYS_SIGNAME 10365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic const struct mksh_sigpair { 10375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *const name; 10385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int nr; 10395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} mksh_sigpairs[] = { 10405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#include "signames.inc" 10415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru { NULL, 0 } 10425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru}; 10435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 10445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 10465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruinittraps(void) 10475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 10485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 10495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *cs; 10505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* Populate sigtraps based on sys_signame and sys_siglist. */ 10525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = 0; i <= NSIG; i++) { 10535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[i].signal = i; 10545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (i == SIGERR_) { 10555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[i].name = "ERR"; 10565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[i].mess = "Error handler"; 10575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else { 10585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_SYS_SIGNAME 10595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cs = sys_signame[i]; 10605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 10615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const struct mksh_sigpair *pair = mksh_sigpairs; 10625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((pair->nr != i) && (pair->name != NULL)) 10635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++pair; 10645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cs = pair->name; 10655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 10665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((cs == NULL) || 10675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (cs[0] == '\0')) 10685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[i].name = shf_smprintf("%d", i); 10695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else { 10705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *s; 10715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!strncasecmp(cs, "SIG", 3)) 10735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cs += 3; 10745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(s, cs, APERM); 10755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[i].name = s; 10765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru while ((*s = ksh_toupper(*s))) 10775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ++s; 10785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#if HAVE_SYS_SIGLIST 10805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[i].mess = sys_siglist[i]; 10815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#elif HAVE_STRSIGNAL 10825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[i].mess = strsignal(i); 10835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#else 10845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[i].mess = NULL; 10855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru#endif 10865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((sigtraps[i].mess == NULL) || 10875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (sigtraps[i].mess[0] == '\0')) 10885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[i].mess = shf_smprintf("Signal %d", i); 10895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 10915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[SIGEXIT_].name = "EXIT"; /* our name for signal 0 */ 10925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (void)sigemptyset(&Sigact_ign.sa_mask); 10945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Sigact_ign.sa_flags = 0; /* interruptible */ 10955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Sigact_ign.sa_handler = SIG_IGN; 10965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 10975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[SIGINT].flags |= TF_DFL_INTR | TF_TTY_INTR; 10985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[SIGQUIT].flags |= TF_DFL_INTR | TF_TTY_INTR; 10995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[SIGTERM].flags |= TF_DFL_INTR;/* not fatal for interactive */ 11005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[SIGHUP].flags |= TF_FATAL; 11015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[SIGCHLD].flags |= TF_SHELL_USES; 11025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* these are always caught so we can clean up any temporary files. */ 11045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setsig(&sigtraps[SIGINT], trapsig, SS_RESTORE_ORIG); 11055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setsig(&sigtraps[SIGQUIT], trapsig, SS_RESTORE_ORIG); 11065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setsig(&sigtraps[SIGTERM], trapsig, SS_RESTORE_ORIG); 11075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setsig(&sigtraps[SIGHUP], trapsig, SS_RESTORE_ORIG); 11085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void alarm_catcher(int sig); 11115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 11135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querualarm_init(void) 11145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigtraps[SIGALRM].flags |= TF_SHELL_USES; 11165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setsig(&sigtraps[SIGALRM], alarm_catcher, 11175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru SS_RESTORE_ORIG|SS_FORCE|SS_SHTRAP); 11185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* ARGSUSED */ 11215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querustatic void 11225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querualarm_catcher(int sig MKSH_A_UNUSED) 11235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* this runs inside interrupt context, with errno saved */ 11255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_tmout_state == TMOUT_READING) { 11275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int left = alarm(0); 11285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (left == 0) { 11305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_tmout_state = TMOUT_LEAVING; 11315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru intrsig = 1; 11325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 11335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru alarm(left); 11345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste QueruTrap * 11385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querugettrap(const char *name, int igncase) 11395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int n = NSIG + 1; 11415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Trap *p; 11425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru const char *n2; 11435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int (*cmpfunc)(const char *, const char *) = strcmp; 11445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_isdigit(*name)) { 11465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (getn(name, &n) && 0 <= n && n < NSIG) 11475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (&sigtraps[n]); 11485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 11495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 11505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru n2 = strncasecmp(name, "SIG", 3) ? NULL : name + 3; 11535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (igncase) 11545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru cmpfunc = strcasecmp; 11555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = sigtraps; --n >= 0; p++) 11565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!cmpfunc(p->name, name) || (n2 && !cmpfunc(p->name, n2))) 11575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p); 11585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (NULL); 11595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 11625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * trap signal handler 11635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 11645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 11655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutrapsig(int i) 11665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Trap *p = &sigtraps[i]; 11685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int errno_ = errno; 11695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru trap = p->set = 1; 11715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->flags & TF_DFL_INTR) 11725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru intrsig = 1; 11735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((p->flags & TF_FATAL) && !p->trap) { 11745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fatal_trap = 1; 11755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru intrsig = 1; 11765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 11775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->shtrap) 11785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (*p->shtrap)(i); 11795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru errno = errno_; 11805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 11835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * called when we want to allow the user to ^C out of something - won't 11845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * work if user has trapped SIGINT. 11855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 11865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 11875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruintrcheck(void) 11885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 11895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (intrsig) 11905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru runtraps(TF_DFL_INTR|TF_FATAL); 11915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 11925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 11935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 11945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * called after EINTR to check if a signal with normally causes process 11955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * termination has been received. 11965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 11975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 11985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querufatal_trap_check(void) 11995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 12015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Trap *p; 12025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* todo: should check if signal is fatal, not the TF_DFL_INTR flag */ 12045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = sigtraps, i = NSIG+1; --i >= 0; p++) 12055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->set && (p->flags & (TF_DFL_INTR|TF_FATAL))) 12065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* return value is used as an exit code */ 12075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (128 + p->signal); 12085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 12095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 12125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Returns the signal number of any pending traps: ie, a signal which has 12135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * occurred for which a trap has been set or for which the TF_DFL_INTR flag 12145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * is set. 12155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 12165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 12175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querutrap_pending(void) 12185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 12205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Trap *p; 12215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = sigtraps, i = NSIG+1; --i >= 0; p++) 12235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->set && ((p->trap && p->trap[0]) || 12245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ((p->flags & (TF_DFL_INTR|TF_FATAL)) && !p->trap))) 12255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (p->signal); 12265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 12275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 12305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * run any pending traps. If intr is set, only run traps that 12315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * can interrupt commands. 12325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 12335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruruntraps(int flag) 12355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 12375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Trap *p; 12385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (ksh_tmout_state == TMOUT_LEAVING) { 12405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_tmout_state = TMOUT_EXECUTING; 12415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru warningf(false, "timed out waiting for input"); 12425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(LEXIT); 12435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else 12445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 12455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * XXX: this means the alarm will have no effect if a trap 12465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * is caught after the alarm() was started...not good. 12475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 12485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ksh_tmout_state = TMOUT_EXECUTING; 12495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!flag) 12505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru trap = 0; 12515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flag & TF_DFL_INTR) 12525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru intrsig = 0; 12535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flag & TF_FATAL) 12545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fatal_trap = 0; 12555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (p = sigtraps, i = NSIG+1; --i >= 0; p++) 12565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->set && (!flag || 12575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru ((p->flags & flag) && p->trap == NULL))) 12585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru runtrap(p); 12595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 12605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 12625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruruntrap(Trap *p) 12635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 12645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i = p->signal; 12655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru char *trapstr = p->trap; 12665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int oexstat; 12675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int old_changed = 0; 12685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 12695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->set = 0; 12705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (trapstr == NULL) { /* SIG_DFL */ 12715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->flags & TF_FATAL) { 12725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* eg, SIGHUP */ 12735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exstat = 128 + i; 12745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(LLEAVE); 12755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->flags & TF_DFL_INTR) { 12775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* eg, SIGINT, SIGQUIT, SIGTERM, etc. */ 12785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exstat = 128 + i; 12795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru unwind(LINTR); 12805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 12825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (trapstr[0] == '\0') /* SIG_IGN */ 12845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 12855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (i == SIGEXIT_ || i == SIGERR_) { /* avoid recursion on these */ 12865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru old_changed = p->flags & TF_CHANGED; 12875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->flags &= ~TF_CHANGED; 12885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->trap = NULL; 12895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 12905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru oexstat = exstat; 12915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 12925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Note: trapstr is fully parsed before anything is executed, thus 12935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * no problem with afree(p->trap) in settrap() while still in use. 12945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 12955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru command(trapstr, current_lineno); 12965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru exstat = oexstat; 12975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (i == SIGEXIT_ || i == SIGERR_) { 12985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->flags & TF_CHANGED) 12995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* don't clear TF_CHANGED */ 13005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(trapstr, APERM); 13015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 13025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->trap = trapstr; 13035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->flags |= old_changed; 13045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* clear pending traps and reset user's trap handlers; used after fork(2) */ 13085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 13095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querucleartraps(void) 13105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 13125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Trap *p; 13135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru trap = 0; 13155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru intrsig = 0; 13165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru fatal_trap = 0; 13175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = NSIG+1, p = sigtraps; --i >= 0; p++) { 13185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->set = 0; 13195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((p->flags & TF_USER_SET) && (p->trap && p->trap[0])) 13205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru settrap(p, NULL); 13215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* restore signals just before an exec(2) */ 13255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 13265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querurestoresigs(void) 13275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int i; 13295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Trap *p; 13305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru for (i = NSIG+1, p = sigtraps; --i >= 0; p++) 13325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->flags & (TF_EXEC_IGN|TF_EXEC_DFL)) 13335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setsig(p, (p->flags & TF_EXEC_IGN) ? SIG_IGN : SIG_DFL, 13345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru SS_RESTORE_CURR|SS_FORCE); 13355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 13385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusettrap(Trap *p, const char *s) 13395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sig_t f; 13415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->trap) 13435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru afree(p->trap, APERM); 13445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru strdupx(p->trap, s, APERM); /* handles s == 0 */ 13455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->flags |= TF_CHANGED; 13465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru f = !s ? SIG_DFL : s[0] ? trapsig : SIG_IGN; 13475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->flags |= TF_USER_SET; 13495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((p->flags & (TF_DFL_INTR|TF_FATAL)) && f == SIG_DFL) 13505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru f = trapsig; 13515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else if (p->flags & TF_SHELL_USES) { 13525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(p->flags & TF_ORIG_IGN) || Flag(FTALKING)) { 13535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* do what user wants at exec time */ 13545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->flags &= ~(TF_EXEC_IGN|TF_EXEC_DFL); 13555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (f == SIG_IGN) 13565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->flags |= TF_EXEC_IGN; 13575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru else 13585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->flags |= TF_EXEC_DFL; 13595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 13625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * assumes handler already set to what shell wants it 13635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * (normally trapsig, but could be j_sigchld() or SIG_IGN) 13645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 13655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return; 13665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* todo: should we let user know signal is ignored? how? */ 13695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setsig(p, f, SS_RESTORE_CURR|SS_USER); 13705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 13735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Called by c_print() when writing to a co-process to ensure SIGPIPE won't 13745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * kill shell (unless user catches it and exits) 13755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 13765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 13775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querublock_pipe(void) 13785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru int restore_dfl = 0; 13805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru Trap *p = &sigtraps[SIGPIPE]; 13815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(p->flags & (TF_ORIG_IGN|TF_ORIG_DFL))) { 13835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setsig(p, SIG_IGN, SS_RESTORE_CURR); 13845155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->flags & TF_ORIG_DFL) 13855155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru restore_dfl = 1; 13865155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } else if (p->cursig == SIG_DFL) { 13875155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setsig(p, SIG_IGN, SS_RESTORE_CURR); 13885155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru restore_dfl = 1; /* restore to SIG_DFL */ 13895155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 13905155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (restore_dfl); 13915155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 13925155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 13935155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* Called by c_print() to undo whatever block_pipe() did */ 13945155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 13955155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querurestore_pipe(int restore_dfl) 13965155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 13975155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (restore_dfl) 13985155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setsig(&sigtraps[SIGPIPE], SIG_DFL, SS_RESTORE_CURR); 13995155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14005155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14015155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* 14025155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Set action for a signal. Action may not be set if original 14035155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * action was SIG_IGN, depending on the value of flags and FTALKING. 14045155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14055155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruint 14065155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusetsig(Trap *p, sig_t f, int flags) 14075155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14085155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru struct sigaction sigact; 14095155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14105155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->signal == SIGEXIT_ || p->signal == SIGERR_) 14115155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14125155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14135155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 14145155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * First time setting this signal? If so, get and note the current 14155155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * setting. 14165155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14175155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(p->flags & (TF_ORIG_IGN|TF_ORIG_DFL))) { 14185155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigaction(p->signal, &Sigact_ign, &sigact); 14195155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->flags |= sigact.sa_handler == SIG_IGN ? 14205155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru TF_ORIG_IGN : TF_ORIG_DFL; 14215155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->cursig = SIG_IGN; 14225155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14235155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14245155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /*- 14255155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * Generally, an ignored signal stays ignored, except if 14265155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * - the user of an interactive shell wants to change it 14275155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * - the shell wants for force a change 14285155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14295155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if ((p->flags & TF_ORIG_IGN) && !(flags & SS_FORCE) && 14305155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (!(flags & SS_USER) || !Flag(FTALKING))) 14315155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (0); 14325155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14335155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru setexecsig(p, flags & SS_RESTORE_MASK); 14345155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14355155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* 14365155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * This is here 'cause there should be a way of clearing 14375155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * shtraps, but don't know if this is a sane way of doing 14385155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * it. At the moment, all users of shtrap are lifetime 14395155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru * users (SIGALRM, SIGCHLD, SIGWINCH). 14405155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru */ 14415155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(flags & SS_USER)) 14425155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->shtrap = (sig_t)NULL; 14435155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (flags & SS_SHTRAP) { 14445155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->shtrap = f; 14455155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru f = trapsig; 14465155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14475155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14485155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (p->cursig != f) { 14495155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->cursig = f; 14505155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru (void)sigemptyset(&sigact.sa_mask); 14515155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigact.sa_flags = 0 /* interruptible */; 14525155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigact.sa_handler = f; 14535155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru sigaction(p->signal, &sigact, NULL); 14545155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14555155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14565155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru return (1); 14575155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 14585155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14595155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru/* control what signal is set to before an exec() */ 14605155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queruvoid 14615155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Querusetexecsig(Trap *p, int restore) 14625155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru{ 14635155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* XXX debugging */ 14645155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru if (!(p->flags & (TF_ORIG_IGN|TF_ORIG_DFL))) 14655155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru internal_errorf("setexecsig: unset signal %d(%s)", 14665155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->signal, p->name); 14675155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru 14685155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru /* restore original value for exec'd kids */ 14695155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->flags &= ~(TF_EXEC_IGN|TF_EXEC_DFL); 14705155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru switch (restore & SS_RESTORE_MASK) { 14715155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SS_RESTORE_CURR: /* leave things as they currently are */ 14725155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 14735155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SS_RESTORE_ORIG: 14745155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->flags |= p->flags & TF_ORIG_IGN ? TF_EXEC_IGN : TF_EXEC_DFL; 14755155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 14765155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SS_RESTORE_DFL: 14775155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->flags |= TF_EXEC_DFL; 14785155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 14795155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru case SS_RESTORE_IGN: 14805155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru p->flags |= TF_EXEC_IGN; 14815155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru break; 14825155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru } 14835155f1c7438ef540d7b25eb70aa1639579795b07Jean-Baptiste Queru} 1484