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