- Timestamp:
- Sep 3, 2020 1:52:14 PM (4 years ago)
- Location:
- trunk/src/kash
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kash/eval.c
r3435 r3437 458 458 args.backgnd = backgnd; 459 459 forkshell2(psh, jp, n, backgnd ? FORK_BG : FORK_FG, 460 evalsubshell_child, n, &args, sizeof(args) );460 evalsubshell_child, n, &args, sizeof(args), NULL); 461 461 } 462 462 #else … … 578 578 args.pip[1] = pip[1]; 579 579 forkshell2(psh, jp, lp->n, n->npipe.backgnd ? FORK_BG : FORK_FG, 580 evalpipe_child, lp->n, &args, sizeof(args) );580 evalpipe_child, lp->n, &args, sizeof(args), NULL); 581 581 } 582 582 #else … … 677 677 args.pip[1] = pip[1]; 678 678 forkshell2(psh, jp, n, FORK_NOJOB, 679 evalbackcmd_child, n, &args, sizeof(args) );679 evalbackcmd_child, n, &args, sizeof(args), NULL); 680 680 } 681 681 #else … … 811 811 struct evalcommanddoit 812 812 { 813 struct cmdentry cmdentry; 814 char *lastarg; 815 const char *path; 813 struct stackmark smark; 814 816 815 struct backcmd *backcmd; 817 816 int flags; 818 817 int argc; 819 818 char **argv; 819 char *lastarg; 820 820 struct arglist varlist; 821 struct stackmark smark; 821 const char *path; 822 struct cmdentry cmdentry; 823 824 /* for child stuff only: */ 825 int pip[2]; 822 826 }; 823 827 … … 996 1000 } 997 1001 1002 /* child callback. */ 1003 static int evalcommand_child(shinstance *psh, union node *cmd, void *argp) 1004 { 1005 struct evalcommanddoit *args = (struct evalcommanddoit *)argp; 1006 1007 if (args->flags & EV_BACKCMD) { 1008 FORCEINTON; 1009 shfile_close(&psh->fdtab, args->pip[0]); 1010 if (args->pip[1] != 1) { 1011 movefd(psh, args->pip[1], 1); 1012 } 1013 } 1014 args->flags |= EV_EXIT; 1015 1016 evalcommand_doit(psh, cmd, args); 1017 /* not reached */ /** @todo make it return here */ 1018 return 0; 1019 } 1020 1021 /* Copies data in the argument structure from parent to child. */ 1022 static void evalcommand_setup_child(shinstance *pshchild, shinstance *pshparent, void *argp) 1023 { 1024 struct evalcommanddoit *args = (struct evalcommanddoit *)argp; 1025 char **argv; 1026 char **srcargv; 1027 struct strlist *sp; 1028 int argc, i; 1029 1030 setstackmark(pshchild, &args->smark); 1031 1032 /* copy arguments. */ 1033 srcargv = args->argv; 1034 argc = args->argc; 1035 args->argv = argv = stalloc(pshchild, sizeof(char *) * (argc + 1)); 1036 for (i = 0; i < argc; i++) 1037 argv[i] = stsavestr(pshchild, srcargv[i]); 1038 argv[argc] = NULL; 1039 if (args->lastarg) 1040 args->lastarg = argv[argc - 1]; 1041 1042 /* copy variable list, checking for the 'path'. */ 1043 sp = args->varlist.list; 1044 args->varlist.list = NULL; 1045 args->varlist.lastp = &args->varlist.list; 1046 for (; sp; sp = sp->next) { 1047 struct strlist *snew = (struct strlist *)stalloc(pshchild, sizeof(*snew)); 1048 char *text; 1049 snew->next = NULL; 1050 snew->text = text = stsavestr(pshchild, sp->text); 1051 1052 if (&text[5] == args->path) 1053 args->path = &text[sizeof("PATH=") - 1]; 1054 1055 *args->varlist.lastp = snew; 1056 args->varlist.lastp = &snew->next; 1057 } 1058 1059 if (args->path == pathval(pshparent)) 1060 args->path = pathval(pshchild); 1061 1062 /* back tick command should be ignored in this codepath 1063 (flags != EV_BACKCMD as EV_EXIT is ORed in). */ 1064 1065 /* If cmdentry references an internal function, we must duplicates it's nodes. */ 1066 if (args->cmdentry.cmdtype == CMDFUNCTION) 1067 args->cmdentry.u.func = copyparsetree(pshchild, args->cmdentry.u.func); /** @todo isn't this duplicated already? */ 1068 } 1069 998 1070 /* 999 1071 * Execute a simple command. … … 1135 1207 || args.cmdentry.u.bltin == evalcmd))) { 1136 1208 struct job *jp; 1137 int pip[2];1138 1209 int mode; 1210 1139 1211 INTOFF; 1140 1212 jp = makejob(psh, cmd, 1); 1141 1213 mode = cmd->ncmd.backgnd; 1214 args.pip[0] = -1; 1215 args.pip[1] = -1; 1142 1216 if (flags & EV_BACKCMD) { 1143 1217 mode = FORK_NOJOB; 1144 if (sh_pipe(psh, pip) < 0)1218 if (sh_pipe(psh, args.pip) < 0) 1145 1219 error(psh, "Pipe call failed"); 1146 1220 } 1221 1222 args.backcmd = backcmd; 1223 args.flags = flags; 1224 args.path = path; 1225 #ifdef KASH_USE_FORKSHELL2 1226 forkshell2(psh, jp, cmd, mode, evalcommand_child, cmd, 1227 &args, sizeof(args), evalcommand_setup_child); 1228 evalcommand_parent(psh, flags, args.lastarg, &args.smark, mode, jp, 1229 args.pip, backcmd); 1230 #else 1147 1231 if (forkshell(psh, jp, cmd, mode) != 0) { 1148 evalcommand_parent(psh, flags, args.lastarg, &args.smark, mode, jp, pip, backcmd); 1232 evalcommand_parent(psh, flags, args.lastarg, &args.smark, mode, jp, 1233 args.pip, backcmd); 1149 1234 return; /* at end of routine */ 1150 1235 } 1151 1152 if (flags & EV_BACKCMD) { 1153 FORCEINTON; 1154 shfile_close(&psh->fdtab, pip[0]); 1155 if (pip[1] != 1) { 1156 movefd(psh, pip[1], 1); 1157 } 1158 } 1159 flags |= EV_EXIT; 1160 1236 evalcommand_child(psh, cmd, &args); 1237 #endif 1238 } else { 1161 1239 args.backcmd = backcmd; 1162 1240 args.flags = flags; … … 1164 1242 evalcommand_doit(psh, cmd, &args); 1165 1243 } 1166 else {1167 args.backcmd = backcmd;1168 args.flags = flags;1169 args.path = path;1170 evalcommand_doit(psh, cmd, &args);1171 }1172 1244 } 1173 1245 … … 1188 1260 if (goodname(n->ncmd.args->narg.text)) 1189 1261 find_command(psh, n->ncmd.args->narg.text, &entry, 0, 1190 pathval(psh));1262 pathval(psh)); 1191 1263 } 1192 1264 -
trunk/src/kash/exec.c
r3435 r3437 150 150 } else { 151 151 /* Before we search the PATH, transform kmk_builtin_% to kmk_% so we don't 152 need to be too careful mixing internal and external kmk command . */152 need to be too careful mixing internal and external kmk commands. */ 153 153 if ( argv0len > 12 154 154 && argv0len < 42 -
trunk/src/kash/generated/nodes.h
r2290 r3437 102 102 struct nfile { 103 103 int type; 104 int fd; 104 105 union node *next; 105 int fd;106 106 union node *fname; 107 107 char *expfname; … … 111 111 struct ndup { 112 112 int type; 113 int fd; 113 114 union node *next; 114 int fd;115 115 int dupfd; 116 116 union node *vname; … … 120 120 struct nhere { 121 121 int type; 122 int fd; 122 123 union node *next; 123 int fd;124 124 union node *doc; 125 125 }; -
trunk/src/kash/jobs.c
r3435 r3437 807 807 int forkshell2(struct shinstance *psh, struct job *jp, union node *n, int mode, 808 808 int (*child)(struct shinstance *, void *, union node *), 809 union node *nchild, void *argp, size_t arglen) 809 union node *nchild, void *argp, size_t arglen, 810 void (*setupchild)(struct shinstance *, struct shinstance *, void *)) 810 811 { 811 812 pid_t pid; … … 816 817 { 817 818 /* child */ 818 (void)arglen;819 819 forkchild(psh, jp, n, mode); 820 820 sh_exit(psh, child(psh, nchild, argp)); … … 827 827 TRACE((psh, "Fork failed, errno=%d\n", errno)); 828 828 INTON; 829 (void)arglen; 830 (void)setupchild; 829 831 error(psh, "Cannot fork"); 830 832 return -1; /* won't get here */ -
trunk/src/kash/jobs.h
r3435 r3437 98 98 int forkshell2(struct shinstance *, struct job *, union node *, int, 99 99 int (*child)(struct shinstance *, void *, union node *), 100 union node *, void *, size_t); 100 union node *, void *, size_t, 101 void (*setupchild)(struct shinstance *, struct shinstance *, void *)); 101 102 #else 102 103 int forkshell(struct shinstance *, struct job *, union node *, int); -
trunk/src/kash/memalloc.c
r2638 r3437 146 146 psh->stacknleft -= (int)nbytes; 147 147 return p; 148 } 149 150 151 char * 152 stsavestr(struct shinstance *psh, const char *src) 153 { 154 if (src) { 155 size_t size = strlen(src) + 1; 156 char *dst = (char *)stalloc(psh, size); 157 return (char *)memcpy(dst, src, size); 158 } 159 return NULL; 148 160 } 149 161 -
trunk/src/kash/memalloc.h
r2290 r3437 52 52 char *savestr(struct shinstance *, const char *); 53 53 pointer stalloc(struct shinstance *, size_t); 54 char *stsavestr(struct shinstance *, const char *); 54 55 void stunalloc(struct shinstance *, pointer); 55 56 void setstackmark(struct shinstance *, struct stackmark *); -
trunk/src/kash/nodetypes
r1215 r3437 118 118 NAPPEND nfile # fd>> fname 119 119 type int 120 next nodeptr # next redirection in list121 fd int # file descriptor being redirected120 fd int # file descriptor being redirected (must match ndup) 121 next nodeptr # next redirection in list (must match ndup) 122 122 fname nodeptr # file name, in a NARG node 123 123 expfname temp char *expfname # actual file name … … 126 126 NFROMFD ndup # fd>&dupfd 127 127 type int 128 next nodeptr # next redirection in list129 fd int # file descriptor being redirected128 fd int # file descriptor being redirected (must match nfile) 129 next nodeptr # next redirection in list (must match nfile) 130 130 dupfd int # file descriptor to duplicate 131 131 vname nodeptr # file name if fd>&$var … … 135 135 NXHERE nhere # fd<<! 136 136 type int 137 next nodeptr # next redirection in list138 fd int # file descriptor being redirected137 fd int # file descriptor being redirected (must match nfile) 138 next nodeptr # next redirection in list (must match nfile) 139 139 doc nodeptr # input to command (NARG node) 140 140 -
trunk/src/kash/parser.c
r3065 r3437 1197 1197 1198 1198 parseredir: { 1199 union node *np; 1199 1200 char fd = *out; 1200 union node *np; 1201 char dummy[ sizeof(struct nfile) >= sizeof(struct ndup) 1202 && sizeof(struct nfile) >= sizeof(struct nhere) ? 1 : 0]; 1203 (void)dummy; 1201 1204 1202 1205 np = (union node *)stalloc(psh, sizeof (struct nfile)); … … 1218 1221 switch (c = pgetc(psh)) { 1219 1222 case '<': 1220 if (sizeof (struct nfile) != sizeof (struct nhere)) {1221 np = (union node *)stalloc(psh, sizeof (struct nhere));1222 np->nfile.fd = 0;1223 }1224 1223 np->type = NHERE; 1225 1224 psh->heredoc = (struct heredoc *)stalloc(psh, sizeof (struct heredoc)); … … 1417 1416 1418 1417 case '\\': 1419 1418 if ((pc = pgetc(psh)) == '\n') { 1420 1419 psh->plinno++; 1421 1420 if (psh->doprompt) … … 1431 1430 continue; 1432 1431 } 1433 if (pc != '\\' && pc != '`' && pc != '$' 1434 && (!ISDBLQUOTE() || pc != '"')) 1435 STPUTC(psh, '\\', pout); 1432 if (pc != '\\' && pc != '`' && pc != '$' && (!ISDBLQUOTE() || pc != '"')) 1433 STPUTC(psh, '\\', pout); 1436 1434 break; 1437 1435 … … 1779 1777 } 1780 1778 } 1779 1780 /* 1781 * Helper to copyparsetree. 1782 */ 1783 static struct nodelist * 1784 copynodelist(shinstance *psh, struct nodelist *src) 1785 { 1786 struct nodelist *ret = NULL; 1787 if (src) { 1788 struct nodelist **ppnext = &ret; 1789 while (src) { 1790 struct nodelist *dst = stalloc(psh, sizeof(*dst)); 1791 dst->next = NULL; 1792 *ppnext = dst; 1793 ppnext = &dst->next; 1794 dst->n = copyparsetree(psh, src->n); 1795 } 1796 } 1797 return ret; 1798 } 1799 1800 /* 1801 * Duplicates a node tree. 1802 * 1803 * Note! This could probably be generated from nodelist. 1804 */ 1805 union node * 1806 copyparsetree(shinstance *psh, union node *src) 1807 { 1808 /** @todo Try avoid recursion for one of the sub-nodes, esp. when there 1809 * is a list like 'next' one. */ 1810 union node *ret; 1811 if (src) { 1812 int const type = src->type; 1813 switch (type) { 1814 case NSEMI: 1815 case NAND: 1816 case NOR: 1817 case NWHILE: 1818 case NUNTIL: 1819 ret = (union node *)stalloc(psh, sizeof(src->nbinary)); 1820 ret->nbinary.type = type; 1821 ret->nbinary.ch1 = copyparsetree(psh, src->nbinary.ch1); 1822 ret->nbinary.ch2 = copyparsetree(psh, src->nbinary.ch2); 1823 break; 1824 1825 case NCMD: 1826 ret = (union node *)stalloc(psh, sizeof(src->ncmd)); 1827 ret->ncmd.type = NCMD; 1828 ret->ncmd.backgnd = src->ncmd.backgnd; 1829 ret->ncmd.args = copyparsetree(psh, src->ncmd.args); 1830 ret->ncmd.redirect = copyparsetree(psh, src->ncmd.redirect); 1831 break; 1832 1833 case NPIPE: 1834 ret = (union node *)stalloc(psh, sizeof(src->npipe)); 1835 ret->npipe.type = NPIPE; 1836 ret->npipe.backgnd = src->ncmd.backgnd; 1837 ret->npipe.cmdlist = copynodelist(psh, src->npipe.cmdlist); 1838 break; 1839 1840 case NREDIR: 1841 case NBACKGND: 1842 case NSUBSHELL: 1843 ret = (union node *)stalloc(psh, sizeof(src->nredir)); 1844 ret->nredir.type = type; 1845 ret->nredir.n = copyparsetree(psh, src->nredir.n); 1846 ret->nredir.redirect = copyparsetree(psh, src->nredir.redirect); 1847 break; 1848 1849 case NIF: 1850 ret = (union node *)stalloc(psh, sizeof(src->nif)); 1851 ret->nif.type = NIF; 1852 ret->nif.test = copyparsetree(psh, src->nif.test); 1853 ret->nif.ifpart = copyparsetree(psh, src->nif.ifpart); 1854 ret->nif.elsepart = copyparsetree(psh, src->nif.elsepart); 1855 break; 1856 1857 case NFOR: 1858 ret = (union node *)stalloc(psh, sizeof(src->nfor)); 1859 ret->nfor.type = NFOR; 1860 ret->nfor.args = copyparsetree(psh, src->nfor.args); 1861 ret->nfor.body = copyparsetree(psh, src->nfor.body); 1862 ret->nfor.var = stsavestr(psh, src->nfor.var); 1863 break; 1864 1865 case NCASE: 1866 ret = (union node *)stalloc(psh, sizeof(src->ncase)); 1867 ret->ncase.type = NCASE; 1868 ret->ncase.expr = copyparsetree(psh, src->ncase.expr); 1869 ret->ncase.cases = copyparsetree(psh, src->ncase.cases); 1870 break; 1871 1872 case NCLIST: 1873 ret = (union node *)stalloc(psh, sizeof(src->nclist)); 1874 ret->nclist.type = NCLIST; 1875 ret->nclist.next = copyparsetree(psh, src->nclist.next); 1876 ret->nclist.pattern = copyparsetree(psh, src->nclist.pattern); 1877 ret->nclist.body = copyparsetree(psh, src->nclist.body); 1878 break; 1879 1880 case NDEFUN: 1881 case NARG: 1882 ret = (union node *)stalloc(psh, sizeof(src->narg)); 1883 ret->narg.type = type; 1884 ret->narg.next = copyparsetree(psh, src->narg.next); 1885 ret->narg.text = stsavestr(psh, src->narg.text); 1886 ret->narg.backquote = copynodelist(psh, src->narg.backquote); 1887 break; 1888 1889 case NTO: 1890 case NCLOBBER: 1891 case NFROM: 1892 case NFROMTO: 1893 case NAPPEND: 1894 ret = (union node *)stalloc(psh, sizeof(src->nfile)); 1895 ret->nfile.type = type; 1896 ret->nfile.fd = src->nfile.fd; 1897 ret->nfile.next = copyparsetree(psh, src->nfile.next); 1898 ret->nfile.fname = copyparsetree(psh, src->nfile.fname); 1899 ret->nfile.expfname = stsavestr(psh, src->nfile.expfname); 1900 break; 1901 1902 case NTOFD: 1903 case NFROMFD: 1904 ret = (union node *)stalloc(psh, sizeof(src->ndup)); 1905 ret->ndup.type = type; 1906 ret->ndup.fd = src->ndup.fd; 1907 ret->ndup.next = copyparsetree(psh, src->ndup.next); 1908 ret->ndup.dupfd = src->ndup.dupfd; 1909 ret->ndup.vname = copyparsetree(psh, src->ndup.vname); 1910 break; 1911 1912 case NHERE: 1913 case NXHERE: 1914 ret = (union node *)stalloc(psh, sizeof(src->nhere)); 1915 ret->nhere.type = type; 1916 ret->nhere.fd = src->nhere.fd; 1917 ret->nhere.next = copyparsetree(psh, src->nhere.next); 1918 ret->nhere.doc = copyparsetree(psh, src->nhere.doc); 1919 break; 1920 1921 case NNOT: 1922 ret = (union node *)stalloc(psh, sizeof(src->nnot)); 1923 ret->nnot.type = NNOT; 1924 ret->nnot.com = copyparsetree(psh, src->nnot.com); 1925 break; 1926 1927 default: 1928 error(psh, "Unknown node type: %d (node=%p)", src->type, src); 1929 return NULL; 1930 } 1931 } else { 1932 ret = NULL; 1933 } 1934 return ret; 1935 } 1936 -
trunk/src/kash/parser.h
r1233 r3437 84 84 int goodname(const char *); 85 85 const char *getprompt(struct shinstance *, void *); 86 union node *copyparsetree(shinstance *, union node *); 86 87 87 88 #endif -
trunk/src/kash/redir.c
r3435 r3437 289 289 args.len = len; 290 290 forkshell2(psh, (struct job *)NULL, (union node *)NULL, FORK_NOJOB, 291 openhere_child, redir, &args, sizeof(args) );291 openhere_child, redir, &args, sizeof(args), NULL); 292 292 } 293 293 #else -
trunk/src/kash/shinstance.c
r3409 r3437 241 241 if (psh) 242 242 { 243 /* Init it enough tfor sh_destroy() to not get upset */243 /* Init it enough for sh_destroy() to not get upset */ 244 244 /* ... */ 245 245
Note:
See TracChangeset
for help on using the changeset viewer.