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