csh and tcsh work

Sources of csh/sh.exec.c

csh と tcsh のソース

Bill Joy

First published: October, 1978.

Copyright © 1979 Regents of the University of California.

  1. 1
    /* Copyright (c) 1979 Regents of the University of California */
  2. 2
    #include "sh.h"
  3. 3
  4. 4
    /*
  5. 5
     * C shell
  6. 6
     */
  7. 7
  8. 8
    /*
  9. 9
     * System level search and execute of a command.
  10. 10
     * We look in each directory for the specified command name.
  11. 11
     * If the name contains a '/' then we execute only the full path name.
  12. 12
     * If there is no search path then we execute only full path names.
  13. 13
     */
  14. 14
  15. 15
    /*
  16. 16
     * As we search for the command we note the first non-trivial error
  17. 17
     * message for presentation to the user.  This allows us often
  18. 18
     * to show that a file has the wrong mode/no access when the file
  19. 19
     * is not in the last component of the search path, so we must
  20. 20
     * go on after first detecting the error.
  21. 21
     */
  22. 22
    char	*exerr;			/* Execution error message */
  23. 23
    char	*expath;		/* Path for exerr */
  24. 24
  25. 25
    /* Dummy search path for just absolute search when no path */
  26. 26
    char	*justabs[] =	{ "", 0 };
  27. 27
  28. 28
    doexec(t)
  29. 29
    	register struct command *t;
  30. 30
    {
  31. 31
    	char *sav;
  32. 32
    	register char *dp, **pv, **av;
  33. 33
    	register struct varent *v;
  34. 34
    	bool slash = any('/', t->t_dcom[0]);
  35. 35
    	char *blk[2];
  36. 36
  37. 37
    	/*
  38. 38
    	 * Glob the command name.  If this does anything, then we
  39. 39
    	 * will execute the command only relative to ".".  One special
  40. 40
    	 * case: if there is no PATH, then we execute only commands
  41. 41
    	 * which start with '/'.
  42. 42
    	 */
  43. 43
    	dp = globone(t->t_dcom[0]);
  44. 44
    	xfree(t->t_dcom[0]);
  45. 45
    	exerr = 0; expath = t->t_dcom[0] = dp;
  46. 46
    	v = adrof("path");
  47. 47
    	if (v == 0 && expath[0] != '/')
  48. 48
    		pexerr();
  49. 49
    	slash |= gflag;
  50. 50
  51. 51
    	/*
  52. 52
    	 * Glob the argument list, if necessary.
  53. 53
    	 * Otherwise trim off the quote bits.
  54. 54
    	 */
  55. 55
    	gflag = 0; av = &t->t_dcom[1];
  56. 56
    	rscan(av, tglob);
  57. 57
    	if (gflag) {
  58. 58
    		av = glob(av);
  59. 59
    		if (av == 0)
  60. 60
    			error("No match");
  61. 61
    	}
  62. 62
    	blk[0] = t->t_dcom[0];
  63. 63
    	blk[1] = 0;
  64. 64
    	av = blkspl(blk, av);
  65. 65
    	scan(av, trim);
  66. 66
  67. 67
    	xechoit(av);		/* Echo command if -x */
  68. 68
    	closech();		/* Close random fd's */
  69. 69
  70. 70
    	/*
  71. 71
    	 * If no path, no words in path, or a / in the filename
  72. 72
    	 * then restrict the command search.
  73. 73
    	 */
  74. 74
    	if (v == 0 || v->vec[0] == 0 || slash)
  75. 75
    		pv = justabs;
  76. 76
    	else
  77. 77
    		pv = v->vec;
  78. 78
    	sav = strspl("/", *av);		/* / command name for postpending */
  79. 79
    	do {
  80. 80
    		if (pv[0][0] == 0 || eq(pv[0], "."))	/* don't make ./xxx */
  81. 81
    			texec(*av, av);
  82. 82
    		else {
  83. 83
    			dp = strspl(*pv, sav);
  84. 84
    			texec(dp, av);
  85. 85
    			xfree(dp);
  86. 86
    		}
  87. 87
    		pv++;
  88. 88
    	} while (*pv);
  89. 89
    	xfree(sav);
  90. 90
    	xfree(av);
  91. 91
    	pexerr();
  92. 92
    }
  93. 93
  94. 94
    pexerr()
  95. 95
    {
  96. 96
  97. 97
    	/* Couldn't find the damn thing */
  98. 98
    	setname(expath);
  99. 99
    	xfree(expath);
  100. 100
    	if (exerr)
  101. 101
    		bferr(exerr);
  102. 102
    	bferr("Command not found");
  103. 103
    }
  104. 104
  105. 105
    /* Last resort shell */
  106. 106
    char	*lastsh[] =	{ SHELLPATH, 0 };
  107. 107
  108. 108
    /*
  109. 109
     * Execute command f, arg list t.
  110. 110
     * Record error message if not found.
  111. 111
     * Also do shell scripts here.
  112. 112
     */
  113. 113
    texec(f, t)
  114. 114
    	char *f;
  115. 115
    	register char **t;
  116. 116
    {
  117. 117
    	register struct varent *v;
  118. 118
    	register char **vp;
  119. 119
    	extern char *sys_errlist[];
  120. 120
  121. 121
    	execv(f, t);
  122. 122
    	switch (errno) {
  123. 123
  124. 124
    	case ENOEXEC:
  125. 125
    		/*
  126. 126
    		 * If there is an alias for shell, then
  127. 127
    		 * put the words of the alias in front of the
  128. 128
    		 * argument list replacing the command name.
  129. 129
    		 * Note no interpretation of the words at this point.
  130. 130
    		 */
  131. 131
    		v = adrof1("shell", &aliases);
  132. 132
    		if (v == 0) {
  133. 133
    #ifdef OTHERSH
  134. 134
    			register int ff = open(f, 0);
  135. 135
    			char ch;
  136. 136
    #endif
  137. 137
  138. 138
    			vp = lastsh;
  139. 139
    			vp[0] = adrof("shell") ? value("shell") : SHELLPATH;
  140. 140
    #ifdef OTHERSH
  141. 141
    			if (ff != -1 && read(ff, &ch, 1) == 1 && ch != '#')
  142. 142
    				vp[0] = OTHERSH;
  143. 143
    			close(ff);
  144. 144
    #endif
  145. 145
    		} else
  146. 146
    			vp = v->vec;
  147. 147
    		t[0] = f;
  148. 148
    		t = blkspl(vp, t);		/* Splice up the new arglst */
  149. 149
    		f = *t;
  150. 150
    		execv(f, t);
  151. 151
    		xfree(t);
  152. 152
    		/* The sky is falling, the sky is falling! */
  153. 153
  154. 154
    	case ENOMEM:
  155. 155
    		Perror(f);
  156. 156
  157. 157
    	case ENOENT:
  158. 158
    		break;
  159. 159
  160. 160
    	default:
  161. 161
    		if (exerr == 0) {
  162. 162
    			exerr = sys_errlist[errno];
  163. 163
    			expath = savestr(f);
  164. 164
    		}
  165. 165
    	}
  166. 166
    }
  167. 167
  168. 168
    execash(t, kp)
  169. 169
    	register struct command *kp;
  170. 170
    {
  171. 171
  172. 172
    	didcch++;
  173. 173
    	lshift(kp->t_dcom, 1);
  174. 174
    	doexec(kp);
  175. 175
    	/*NOTREACHED*/
  176. 176
    }
  177. 177
  178. 178
    xechoit(t)
  179. 179
    	char **t;
  180. 180
    {
  181. 181
  182. 182
    	if (adrof("echo")) {
  183. 183
    		flush();
  184. 184
    		haderr = 1;
  185. 185
    		blkpr(t), printf("\n");
  186. 186
    		haderr = 0;
  187. 187
    	}
  188. 188
    }

To the top of this page