1 /*- 2 * Copyright (c) 1980, 1991 The Regents of the University of California. 3 * All rights reserved. 4 * 5 * %sccs.include.redist.c% 6 */ 7 8 #ifndef lint 9 static char sccsid[] = "@(#)misc.c 5.6 (Berkeley) 04/04/91"; 10 #endif /* not lint */ 11 12 #include "sh.h" 13 14 /* 15 * C Shell 16 */ 17 18 onlyread(cp) 19 char *cp; 20 { 21 extern char end[]; 22 23 return (cp < end); 24 } 25 26 xfree(cp) 27 char *cp; 28 { 29 extern char end[]; 30 31 if (cp >= end && cp < (char *) &cp) 32 free(cp); 33 } 34 35 char * 36 savestr(s) 37 register char *s; 38 { 39 char *n; 40 register char *p; 41 42 if (s == 0) 43 s = ""; 44 for (p = s; *p++;) 45 ; 46 n = p = xalloc((unsigned) (p - s)); 47 while (*p++ = *s++) 48 ; 49 return (n); 50 } 51 52 char * 53 calloc(i, j) 54 register unsigned i; 55 unsigned j; 56 { 57 char *cp; 58 59 i *= j; 60 cp = xalloc(i); 61 bzero(cp, (int)i); 62 return (cp); 63 } 64 65 nomem(i) 66 unsigned i; 67 { 68 #ifdef debug 69 static char *av[2] = {0, 0}; 70 #endif 71 72 child++; 73 #ifndef debug 74 error("Out of memory"); 75 #ifdef lint 76 i = i; 77 #endif 78 #else 79 showall(av); 80 printf("i=%d: Out of memory\n", i); 81 chdir("/usr/bill/cshcore"); 82 abort(); 83 #endif 84 return 0; /* fool lint */ 85 } 86 87 char ** 88 blkend(up) 89 register char **up; 90 { 91 92 while (*up) 93 up++; 94 return (up); 95 } 96 97 blkpr(av) 98 register char **av; 99 { 100 101 for (; *av; av++) { 102 printf("%s", *av); 103 if (av[1]) 104 printf(" "); 105 } 106 } 107 108 blklen(av) 109 register char **av; 110 { 111 register int i = 0; 112 113 while (*av++) 114 i++; 115 return (i); 116 } 117 118 char ** 119 blkcpy(oav, bv) 120 char **oav; 121 register char **bv; 122 { 123 register char **av = oav; 124 125 while (*av++ = *bv++) 126 continue; 127 return (oav); 128 } 129 130 char ** 131 blkcat(up, vp) 132 char **up, **vp; 133 { 134 135 (void) blkcpy(blkend(up), vp); 136 return (up); 137 } 138 139 blkfree(av0) 140 char **av0; 141 { 142 register char **av = av0; 143 144 for (; *av; av++) 145 XFREE(*av) 146 XFREE((char *)av0) 147 } 148 149 char ** 150 saveblk(v) 151 register char **v; 152 { 153 register char **newv = 154 (char **) calloc((unsigned) (blklen(v) + 1), sizeof (char **)); 155 char **onewv = newv; 156 157 while (*v) 158 *newv++ = savestr(*v++); 159 return (onewv); 160 } 161 162 char * 163 strspl(cp, dp) 164 char *cp, *dp; 165 { 166 char *ep; 167 register char *p, *q; 168 169 for (p = cp; *p++;) 170 ; 171 for (q = dp; *q++;) 172 ; 173 ep = xalloc((unsigned) ((p - cp) + (q - dp) - 1)); 174 for (p = ep, q = cp; *p++ = *q++;) 175 ; 176 for (p--, q = dp; *p++ = *q++;) 177 ; 178 return (ep); 179 } 180 181 char ** 182 blkspl(up, vp) 183 register char **up, **vp; 184 { 185 register char **wp = 186 (char **) calloc((unsigned) (blklen(up) + blklen(vp) + 1), 187 sizeof (char **)); 188 189 (void) blkcpy(wp, up); 190 return (blkcat(wp, vp)); 191 } 192 193 lastchr(cp) 194 register char *cp; 195 { 196 197 if (!*cp) 198 return (0); 199 while (cp[1]) 200 cp++; 201 return (*cp); 202 } 203 204 /* 205 * This routine is called after an error to close up 206 * any units which may have been left open accidentally. 207 */ 208 closem() 209 { 210 register int f; 211 212 for (f = 0; f < NOFILE; f++) 213 if (f != SHIN && f != SHOUT && f != SHDIAG && f != OLDSTD && 214 f != FSHTTY) 215 (void) close(f); 216 } 217 218 donefds() 219 { 220 221 (void) close(0); 222 (void) close(1); 223 (void) close(2); 224 didfds = 0; 225 } 226 227 /* 228 * Move descriptor i to j. 229 * If j is -1 then we just want to get i to a safe place, 230 * i.e. to a unit > 2. This also happens in dcopy. 231 */ 232 dmove(i, j) 233 register int i, j; 234 { 235 236 if (i == j || i < 0) 237 return (i); 238 if (j >= 0) { 239 (void) dup2(i, j); 240 return (j); 241 } 242 j = dcopy(i, j); 243 if (j != i) 244 (void) close(i); 245 return (j); 246 } 247 248 dcopy(i, j) 249 register int i, j; 250 { 251 252 if (i == j || i < 0 || j < 0 && i > 2) 253 return (i); 254 if (j >= 0) { 255 (void) dup2(i, j); 256 return (j); 257 } 258 (void) close(j); 259 return (renum(i, j)); 260 } 261 262 renum(i, j) 263 register int i, j; 264 { 265 register int k = dup(i); 266 267 if (k < 0) 268 return (-1); 269 if (j == -1 && k > 2) 270 return (k); 271 if (k != j) { 272 j = renum(k, j); 273 (void) close(k); 274 return (j); 275 } 276 return (k); 277 } 278 279 /* 280 * Left shift a command argument list, discarding 281 * the first c arguments. Used in "shift" commands 282 * as well as by commands like "repeat". 283 */ 284 lshift(v, c) 285 register char **v; 286 register int c; 287 { 288 register char **u = v; 289 290 while (*u && --c >= 0) 291 xfree(*u++); 292 (void) blkcpy(v, u); 293 } 294 295 number(cp) 296 char *cp; 297 { 298 299 if (*cp == '-') { 300 cp++; 301 if (!digit(*cp++)) 302 return (0); 303 } 304 while (*cp && digit(*cp)) 305 cp++; 306 return (*cp == 0); 307 } 308 309 char ** 310 copyblk(v) 311 register char **v; 312 { 313 register char **nv = 314 (char **) calloc((unsigned) (blklen(v) + 1), sizeof (char **)); 315 316 return (blkcpy(nv, v)); 317 } 318 319 char * 320 strend(cp) 321 register char *cp; 322 { 323 324 while (*cp) 325 cp++; 326 return (cp); 327 } 328 329 char * 330 strip(cp) 331 char *cp; 332 { 333 register char *dp = cp; 334 335 while (*dp++ &= TRIM) 336 continue; 337 return (cp); 338 } 339 340 udvar(name) 341 char *name; 342 { 343 344 setname(name); 345 bferr("Undefined variable"); 346 } 347 348 prefix(sub, str) 349 register char *sub, *str; 350 { 351 352 for (;;) { 353 if (*sub == 0) 354 return (1); 355 if (*str == 0) 356 return (0); 357 if (*sub++ != *str++) 358 return (0); 359 } 360 } 361