csh and tcsh work

Sources of csh/sh.func.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
    struct biltins *
  9. 9
    isbfunc(cp)
  10. 10
    	register char *cp;
  11. 11
    {
  12. 12
    	register char *dp;
  13. 13
    	register struct biltins *bp;
  14. 14
  15. 15
    	if (lastchr(cp) == ':')
  16. 16
    		return ((struct biltins *) 1);
  17. 17
    	for (bp = bfunc; dp = bp->bname; bp++) {
  18. 18
    		if (dp[0] == cp[0] && eq(dp, cp))
  19. 19
    			return (bp);
  20. 20
    		if (dp[0] > cp[0])
  21. 21
    			break;
  22. 22
    	}
  23. 23
    	return (0);
  24. 24
    }
  25. 25
  26. 26
    func(t)
  27. 27
    	register struct command *t;
  28. 28
    {
  29. 29
    	register struct biltins *bp;
  30. 30
    	int i;
  31. 31
  32. 32
    	bp = bfunc;
  33. 33
    	if (lastchr(t->t_dcom[0]) == ':') {
  34. 34
    		xechoit(t->t_dcom);
  35. 35
    		if (!eq(t->t_dcom[0], ":") && t->t_dcom[1])
  36. 36
    			error("No args on labels");
  37. 37
    		return (1);
  38. 38
    	}
  39. 39
    	bp = isbfunc(t->t_dcom[0]);
  40. 40
    	if (bp == 0)
  41. 41
    		return (0);
  42. 42
    	/* timed builtins must go in background if output is pipe, or &'ed */
  43. 43
    	if (eq(bp->bname, "time"))
  44. 44
    		if ((t->t_dflg & FAND) || (t->t_dflg & FPOU))
  45. 45
    			return (0);
  46. 46
    	if (eq(bp->bname, "nohup") && t->t_dcom[1])
  47. 47
    		return (0);
  48. 48
    	xechoit(t->t_dcom);
  49. 49
    	setname(bp->bname);
  50. 50
    	i = blklen(t->t_dcom) - 1;
  51. 51
    	if (i < bp->minargs)
  52. 52
    		bferr("Too few arguments");
  53. 53
    	if (i > bp->maxargs)
  54. 54
    		bferr("Too many arguments");
  55. 55
    	i = (*bp->bfunct)(t->t_dcom, t);
  56. 56
    	/* time and nice may not do their deeds, all others guarantee too */
  57. 57
    	return (eq(bp->bname, "time") || eq(bp->bname, "nice") ? i : 1);
  58. 58
    }
  59. 59
  60. 60
    doonintr(v)
  61. 61
    	char **v;
  62. 62
    {
  63. 63
    	register char *cp;
  64. 64
    	register char *vv = v[1];
  65. 65
  66. 66
    	if (parintr == SIG_IGN)
  67. 67
    		return;
  68. 68
    	if (setintr && intty)
  69. 69
    		bferr("Can't from terminal");
  70. 70
    	cp = gointr, gointr = 0, xfree(cp);
  71. 71
    	if (vv == 0) {
  72. 72
    		signal(SIGINT, setintr ? SIG_IGN : SIG_DFL);
  73. 73
    		gointr = 0;
  74. 74
    	} else if (eq((vv = strip(vv)), "-")) {
  75. 75
    		signal(SIGINT, SIG_IGN);
  76. 76
    		gointr = "-";
  77. 77
    	} else {
  78. 78
    		gointr = savestr(vv);
  79. 79
    		signal(SIGINT, pintr);
  80. 80
    	}
  81. 81
    }
  82. 82
  83. 83
    donohup()
  84. 84
    {
  85. 85
  86. 86
    	if (intty)
  87. 87
    		bferr("Can't from terminal");
  88. 88
    	if (setintr == 0) {
  89. 89
    		signal(SIGHUP, SIG_IGN);
  90. 90
    #ifdef CC
  91. 91
    		submit(getpid());
  92. 92
    #endif
  93. 93
    	}
  94. 94
    }
  95. 95
  96. 96
    dozip()
  97. 97
    {
  98. 98
  99. 99
    	;
  100. 100
    }
  101. 101
  102. 102
    chngd(vp)
  103. 103
    	register char **vp;
  104. 104
    {
  105. 105
    	register int i;
  106. 106
    	register char *dp;
  107. 107
  108. 108
    	vp++;
  109. 109
    	dp = *vp;
  110. 110
    	if (dp)
  111. 111
    		dp = globone(dp);
  112. 112
    	else {
  113. 113
    		dp = value("home");
  114. 114
    		if (*dp == 0)
  115. 115
    			bferr("No home");
  116. 116
    	}
  117. 117
    	i = chdir(dp);
  118. 118
    	if (*vp)
  119. 119
    		xfree(dp);
  120. 120
    	if (i < 0)
  121. 121
    		Perror(dp);
  122. 122
    }
  123. 123
  124. 124
    prvars()
  125. 125
    {
  126. 126
  127. 127
    	plist(&shvhed);
  128. 128
    }
  129. 129
  130. 130
    doalias(v)
  131. 131
    	register char **v;
  132. 132
    {
  133. 133
    	register struct varent *vp;
  134. 134
    	register char *p;
  135. 135
  136. 136
    	v++;
  137. 137
    	p = *v++;
  138. 138
    	if (p == 0)
  139. 139
    		plist(&aliases);
  140. 140
    	else if (*v == 0) {
  141. 141
    		vp = adrof1(strip(p), &aliases);
  142. 142
    		if (vp)
  143. 143
    			blkpr(vp->vec), printf("\n");
  144. 144
    	} else {
  145. 145
    		if (eq(p, "alias") || eq(p, "unalias")) {
  146. 146
    			setname(p);
  147. 147
    			bferr("Too dangerous to alias that");
  148. 148
    		}
  149. 149
    		set1(strip(p), saveblk(v), &aliases);
  150. 150
    	}
  151. 151
    }
  152. 152
  153. 153
    unalias(v)
  154. 154
    	char **v;
  155. 155
    {
  156. 156
  157. 157
    	unset1(v, &aliases);
  158. 158
    }
  159. 159
  160. 160
    dologout()
  161. 161
    {
  162. 162
  163. 163
    	islogin();
  164. 164
    	goodbye();
  165. 165
    }
  166. 166
  167. 167
    islogin()
  168. 168
    {
  169. 169
  170. 170
    	if (loginsh)
  171. 171
    		return;
  172. 172
    	error("Not login shell");
  173. 173
    }
  174. 174
  175. 175
    doif(v, kp)
  176. 176
    	char **v;
  177. 177
    	struct command *kp;
  178. 178
    {
  179. 179
    	register int i;
  180. 180
    	register char **vv;
  181. 181
  182. 182
    	v++;
  183. 183
    	i = exp(&v);
  184. 184
    	vv = v;
  185. 185
    	if (*vv && eq(*vv, "then")) {
  186. 186
    		vv++;
  187. 187
    		if (*vv)
  188. 188
    			bferr("Improper then");
  189. 189
    		setname("then");
  190. 190
    		/*
  191. 191
    		 * If expression was zero, then scan to else,
  192. 192
    		 * otherwise just fall into following code.
  193. 193
    		 */
  194. 194
    		if (!i)
  195. 195
    			search(ZIF, 0);
  196. 196
    		return;
  197. 197
    	}
  198. 198
    	/*
  199. 199
    	 * Simple command attached to this if.
  200. 200
    	 * Left shift the node in this tree, munging it
  201. 201
    	 * so we can reexecute it.
  202. 202
    	 */
  203. 203
    	if (i) {
  204. 204
    		lshift(kp->t_dcom, vv - kp->t_dcom);
  205. 205
    		reexecute(kp);
  206. 206
    		donefds();
  207. 207
    	}
  208. 208
    }
  209. 209
  210. 210
    /*
  211. 211
     * Reexecute a command, being careful not
  212. 212
     * to redo i/o redirection, which is already set up.
  213. 213
     */
  214. 214
    reexecute(kp)
  215. 215
    	register struct command *kp;
  216. 216
    {
  217. 217
  218. 218
    	kp->t_dflg = FREDO;
  219. 219
    	execute(kp);
  220. 220
    }
  221. 221
  222. 222
    doelse()
  223. 223
    {
  224. 224
  225. 225
    	search(ZELSE, 0);
  226. 226
    }
  227. 227
  228. 228
    dogoto(v)
  229. 229
    	char **v;
  230. 230
    {
  231. 231
    	register struct whyle *wp;
  232. 232
    	char *lp;
  233. 233
  234. 234
    	/*
  235. 235
    	 * While we still can, locate any unknown ends of existing loops.
  236. 236
    	 * This obscure code is the WORST result of the fact that we
  237. 237
    	 * don't really parse.
  238. 238
    	 */
  239. 239
    	for (wp = whyles; wp; wp = wp->w_next)
  240. 240
    		if (wp->w_end == 0)
  241. 241
    			wp->w_end = search(ZBREAK, 0);
  242. 242
    		else
  243. 243
    			bseek(wp->w_end);
  244. 244
    	search(ZGOTO, 0, lp = globone(v[1]));
  245. 245
    	xfree(lp);
  246. 246
    	/*
  247. 247
    	 * Eliminate loops which were exited.
  248. 248
    	 */
  249. 249
    	wfree();
  250. 250
    }
  251. 251
  252. 252
    doswitch(v)
  253. 253
    	register char **v;
  254. 254
    {
  255. 255
    	register char *cp, *lp;
  256. 256
  257. 257
    	v++;
  258. 258
    	if (!*v || *(*v++) != '(')
  259. 259
    		goto syntax;
  260. 260
    	cp = **v == ')' ? "" : *v++;
  261. 261
    	if (*(*v++) != ')')
  262. 262
    		v--;
  263. 263
    	if (*v)
  264. 264
    syntax:
  265. 265
    		error("Syntax error");
  266. 266
    	search(ZSWITCH, 0, lp = globone(cp));
  267. 267
    	xfree(lp);
  268. 268
    }
  269. 269
  270. 270
    dobreak()
  271. 271
    {
  272. 272
  273. 273
    	if (whyles)
  274. 274
    		toend();
  275. 275
    	else
  276. 276
    		bferr("Not in while/foreach");
  277. 277
    }
  278. 278
  279. 279
    doexit(v)
  280. 280
    	char **v;
  281. 281
    {
  282. 282
  283. 283
    	/*
  284. 284
    	 * Don't DEMAND parentheses here either.
  285. 285
    	 */
  286. 286
    	v++;
  287. 287
    	if (*v) {
  288. 288
    		set("status", putn(exp(&v)));
  289. 289
    		if (*v)
  290. 290
    			bferr("Expression syntax");
  291. 291
    	}
  292. 292
    	btoeof();
  293. 293
    	if (intty)
  294. 294
    		close(SHIN);
  295. 295
    }
  296. 296
  297. 297
    doforeach(v)
  298. 298
    	register char **v;
  299. 299
    {
  300. 300
    	register char *cp;
  301. 301
    	register struct whyle *nwp;
  302. 302
  303. 303
    	v++;
  304. 304
    	cp = strip(*v);
  305. 305
    	while (*cp && letter(*cp))
  306. 306
    		cp++;
  307. 307
    	if (*cp || strlen(*v) >= 20)
  308. 308
    		bferr("Invalid variable");
  309. 309
    	cp = *v++;
  310. 310
    	if (v[0][0] != '(' || v[blklen(v) - 1][0] != ')')
  311. 311
    		bferr("Words not ()'ed");
  312. 312
    	v++;
  313. 313
    	gflag = 0, rscan(v, tglob);
  314. 314
    	v = glob(v);
  315. 315
    	if (v == 0)
  316. 316
    		bferr("No match");
  317. 317
    	nwp = (struct whyle *) calloc(1, sizeof *nwp);
  318. 318
    	nwp->w_fe = nwp->w_fe0 = v; gargv = 0;
  319. 319
    	nwp->w_start = btell();
  320. 320
    	nwp->w_fename = savestr(cp);
  321. 321
    	nwp->w_next = whyles;
  322. 322
    	whyles = nwp;
  323. 323
    	/*
  324. 324
    	 * Pre-read the loop so as to be more
  325. 325
    	 * comprehensible to a terminal user.
  326. 326
    	 */
  327. 327
    	if (intty)
  328. 328
    		preread();
  329. 329
    	doagain();
  330. 330
    }
  331. 331
  332. 332
    dowhile(v)
  333. 333
    	char **v;
  334. 334
    {
  335. 335
    	register int status;
  336. 336
    	register bool again = whyles != 0 && whyles->w_start == lineloc;
  337. 337
  338. 338
    	v++;
  339. 339
    	/*
  340. 340
    	 * Implement prereading here also, taking care not to
  341. 341
    	 * evaluate the expression before the loop has been read up
  342. 342
    	 * from a terminal.
  343. 343
    	 */
  344. 344
    	if (intty && !again)
  345. 345
    		status = !exp0(&v, 1);
  346. 346
    	else
  347. 347
    		status = !exp(&v);
  348. 348
    	if (*v)
  349. 349
    		bferr("Expression syntax");
  350. 350
    	if (!again) {
  351. 351
    		register struct whyle *nwp = (struct whyle *) calloc(1, sizeof (*nwp));
  352. 352
  353. 353
    		nwp->w_start = lineloc;
  354. 354
    		nwp->w_end = 0;
  355. 355
    		nwp->w_next = whyles;
  356. 356
    		whyles = nwp;
  357. 357
    		if (intty) {
  358. 358
    			/*
  359. 359
    			 * The tty preread
  360. 360
    			 */
  361. 361
    			preread();
  362. 362
    			doagain();
  363. 363
    			return;
  364. 364
    		}
  365. 365
    	}
  366. 366
    	if (status)
  367. 367
    		/* We ain't gonna loop no more, no more! */
  368. 368
    		toend();
  369. 369
    }
  370. 370
  371. 371
    preread()
  372. 372
    {
  373. 373
    	register int (*oldint)();
  374. 374
  375. 375
    	whyles->w_end = -1;
  376. 376
    	if (setintr)
  377. 377
    		oldint = signal(SIGINT, pintr);
  378. 378
    	search(ZBREAK, 0);
  379. 379
    	if (setintr)
  380. 380
    		signal(SIGINT, oldint);
  381. 381
    	whyles->w_end = btell();
  382. 382
    }
  383. 383
  384. 384
    doend()
  385. 385
    {
  386. 386
  387. 387
    	if (!whyles)
  388. 388
    		bferr("Not in while/foreach");
  389. 389
    	whyles->w_end = btell();
  390. 390
    	doagain();
  391. 391
    }
  392. 392
  393. 393
    docontin()
  394. 394
    {
  395. 395
  396. 396
    	if (!whyles)
  397. 397
    		bferr("Not in while/foreach");
  398. 398
    	doagain();
  399. 399
    }
  400. 400
  401. 401
    doagain()
  402. 402
    {
  403. 403
  404. 404
    	/* Repeating a while is simple */
  405. 405
    	if (whyles->w_fename == 0) {
  406. 406
    		bseek(whyles->w_start);
  407. 407
    		return;
  408. 408
    	}
  409. 409
    	/*
  410. 410
    	 * The foreach variable list actually has a spurious word
  411. 411
    	 * ")" at the end of the w_fe list.  Thus we are at the
  412. 412
    	 * of the list if one word beyond this is 0.
  413. 413
    	 */
  414. 414
    	if (!whyles->w_fe[1]) {
  415. 415
    		dobreak();
  416. 416
    		return;
  417. 417
    	}
  418. 418
    	set(whyles->w_fename, savestr(*whyles->w_fe++));
  419. 419
    	bseek(whyles->w_start);
  420. 420
    }
  421. 421
  422. 422
    dorepeat(v, kp)
  423. 423
    	char **v;
  424. 424
    	struct command *kp;
  425. 425
    {
  426. 426
    	register int i;
  427. 427
    	register int (*saveintr)();
  428. 428
  429. 429
    	i = getn(v[1]);
  430. 430
    	if (setintr)
  431. 431
    		saveintr = signal(SIGINT, SIG_IGN);
  432. 432
    	lshift(v, 2);
  433. 433
    	while (i > 0) {
  434. 434
    		if (setintr)
  435. 435
    			signal(SIGINT, pintr);
  436. 436
    		reexecute(kp);
  437. 437
    		--i;
  438. 438
    	}
  439. 439
    	donefds();
  440. 440
    	if (setintr)
  441. 441
    		signal(SIGINT, saveintr);
  442. 442
    }
  443. 443
  444. 444
    doswbrk()
  445. 445
    {
  446. 446
  447. 447
    	search(ZBRKSW, 0);
  448. 448
    }
  449. 449
  450. 450
    srchx(cp)
  451. 451
    	register char *cp;
  452. 452
    {
  453. 453
    	register struct srch *sp;
  454. 454
  455. 455
    	for (sp = srchn; sp->s_name; sp++)
  456. 456
    		if (eq(cp, sp->s_name))
  457. 457
    			return (sp->s_value);
  458. 458
    	return (-1);
  459. 459
    }
  460. 460
  461. 461
    char	Stype;
  462. 462
    char	*Sgoal;
  463. 463
  464. 464
    /*VARARGS2*/
  465. 465
    search(type, level, goal)
  466. 466
    	int type;
  467. 467
    	register int level;
  468. 468
    	char *goal;
  469. 469
    {
  470. 470
    	char wordbuf[BUFSIZ];
  471. 471
    	register char *aword = wordbuf;
  472. 472
    	register char *cp;
  473. 473
  474. 474
    	Stype = type; Sgoal = goal;
  475. 475
    	if (type == ZGOTO)
  476. 476
    		bseek(0l);
  477. 477
    	do {
  478. 478
    		if (intty && fseekp == feobp)
  479. 479
    			printf("? "), flush();
  480. 480
    		aword[0] = 0, getword(aword);
  481. 481
    		switch (srchx(aword)) {
  482. 482
  483. 483
    		case ZELSE:
  484. 484
    			if (level == 0 && type == ZIF)
  485. 485
    				return;
  486. 486
    			break;
  487. 487
  488. 488
    		case ZIF:
  489. 489
    			while (getword(aword))
  490. 490
    				continue;
  491. 491
    			if ((type == ZIF || type == ZELSE) && eq(aword, "then"))
  492. 492
    				level++;
  493. 493
    			break;
  494. 494
  495. 495
    		case ZENDIF:
  496. 496
    			if (type == ZIF || type == ZELSE)
  497. 497
    				level--;
  498. 498
    			break;
  499. 499
  500. 500
    		case ZFOREACH:
  501. 501
    		case ZWHILE:
  502. 502
    			if (type == ZBREAK)
  503. 503
    				level++;
  504. 504
    			break;
  505. 505
  506. 506
    		case ZEND:
  507. 507
    			if (type == ZBREAK)
  508. 508
    				level--;
  509. 509
    			break;
  510. 510
  511. 511
    		case ZSWITCH:
  512. 512
    			if (type == ZSWITCH || type == ZBRKSW)
  513. 513
    				level++;
  514. 514
    			break;
  515. 515
  516. 516
    		case ZENDSW:
  517. 517
    			if (type == ZSWITCH || type == ZBRKSW)
  518. 518
    				level--;
  519. 519
    			break;
  520. 520
  521. 521
    		case ZLABEL:
  522. 522
    			if (type == ZGOTO && getword(aword) && eq(aword, goal))
  523. 523
    				level = -1;
  524. 524
    			break;
  525. 525
  526. 526
    		default:
  527. 527
    			if (type != ZGOTO && (type != ZSWITCH || level != 0))
  528. 528
    				break;
  529. 529
    			if (lastchr(aword) != ':')
  530. 530
    				break;
  531. 531
    			aword[strlen(aword) - 1] = 0;
  532. 532
    			if (type == ZGOTO && eq(aword, goal) || type == ZSWITCH && eq(aword, "default"))
  533. 533
    				level = -1;
  534. 534
    			break;
  535. 535
  536. 536
    		case ZCASE:
  537. 537
    			if (type != ZSWITCH || level != 0)
  538. 538
    				break;
  539. 539
    			getword(aword);
  540. 540
    			if (lastchr(aword) == ':')
  541. 541
    				aword[strlen(aword) - 1] = 0;
  542. 542
    			cp = strip(Dfix1(aword));
  543. 543
    			if (Gmatch(goal, cp))
  544. 544
    				level = -1;
  545. 545
    			xfree(cp);
  546. 546
    			break;
  547. 547
  548. 548
    		case ZDEFAULT:
  549. 549
    			if (type == ZSWITCH && level == 0)
  550. 550
    				level = -1;
  551. 551
    			break;
  552. 552
    		}
  553. 553
    		getword(0);
  554. 554
    	} while (level >= 0);
  555. 555
    }
  556. 556
  557. 557
    getword(wp)
  558. 558
    	register char *wp;
  559. 559
    {
  560. 560
    	register int found = 0;
  561. 561
    	register int c, d;
  562. 562
  563. 563
    	c = readc(1);
  564. 564
    	d = 0;
  565. 565
    	do {
  566. 566
    		while (c == ' ' || c == '\t')
  567. 567
    			c = readc(1);
  568. 568
    		if (c < 0)
  569. 569
    			goto past;
  570. 570
    		if (c == '\n') {
  571. 571
    			if (wp)
  572. 572
    				break;
  573. 573
    			return (0);
  574. 574
    		}
  575. 575
    		unreadc(c);
  576. 576
    		found = 1;
  577. 577
    		do {
  578. 578
    			c = readc(1);
  579. 579
    			if (c == '\\' && (c = readc(1)) == '\n')
  580. 580
    				c = ' ';
  581. 581
    			if (any(c, "'\""))
  582. 582
    				if (d == 0)
  583. 583
    					d = c;
  584. 584
    				else if (d == c)
  585. 585
    					d = 0;
  586. 586
    			if (c < 0)
  587. 587
    				goto past;
  588. 588
    			if (wp)
  589. 589
    				*wp++ = c;
  590. 590
    		} while ((d || c != ' ' && c != '\t') && c != '\n');
  591. 591
    	} while (wp == 0);
  592. 592
    	unreadc(c);
  593. 593
    	if (found)
  594. 594
    		*--wp = 0;
  595. 595
    	return (found);
  596. 596
  597. 597
    past:
  598. 598
    	switch (Stype) {
  599. 599
  600. 600
    	case ZIF:
  601. 601
    		bferr("then/endif not found");
  602. 602
  603. 603
    	case ZELSE:
  604. 604
    		bferr("endif not found");
  605. 605
  606. 606
    	case ZBRKSW:
  607. 607
    	case ZSWITCH:
  608. 608
    		bferr("endsw not found");
  609. 609
  610. 610
    	case ZBREAK:
  611. 611
    		bferr("end not found");
  612. 612
  613. 613
    	case ZGOTO:
  614. 614
    		setname(Sgoal);
  615. 615
    		bferr("label not found");
  616. 616
    	}
  617. 617
    	/*NOTREACHED*/
  618. 618
    }
  619. 619
  620. 620
    toend()
  621. 621
    {
  622. 622
  623. 623
    	if (whyles->w_end == 0) {
  624. 624
    		search(ZBREAK, 0);
  625. 625
    		whyles->w_end = btell() - 1;
  626. 626
    	} else
  627. 627
    		bseek(whyles->w_end);
  628. 628
    	wfree();
  629. 629
    }
  630. 630
  631. 631
    wfree()
  632. 632
    {
  633. 633
    	long o = btell();
  634. 634
  635. 635
    	while (whyles) {
  636. 636
    		register struct whyle *wp = whyles;
  637. 637
    		register struct whyle *nwp = wp->w_next;
  638. 638
  639. 639
    		if (o >= wp->w_start && (wp->w_end == 0 || o < wp->w_end))
  640. 640
    			break;
  641. 641
    		if (wp->w_fe0)
  642. 642
    			blkfree(wp->w_fe0);
  643. 643
    		if (wp->w_fename)
  644. 644
    			xfree(wp->w_fename);
  645. 645
    		xfree(wp);
  646. 646
    		whyles = nwp;
  647. 647
    	}
  648. 648
    }
  649. 649
  650. 650
    doecho(v)
  651. 651
    	char **v;
  652. 652
    {
  653. 653
  654. 654
    	echo(' ', v);
  655. 655
    }
  656. 656
  657. 657
    doglob(v)
  658. 658
    	char **v;
  659. 659
    {
  660. 660
  661. 661
    	echo(0, v);
  662. 662
    	flush();
  663. 663
    }
  664. 664
  665. 665
    echo(sep, v)
  666. 666
    	char sep;
  667. 667
    	register char **v;
  668. 668
    {
  669. 669
    	register char *cp;
  670. 670
    	int (*saveintr)();
  671. 671
    	if (setintr)
  672. 672
    		saveintr = signal(SIGINT, pintr);
  673. 673
  674. 674
    	v++;
  675. 675
    	if (*v == 0)
  676. 676
    		return;
  677. 677
    	gflag = 0; rscan(v, tglob);
  678. 678
    	if (gflag) {
  679. 679
    		v = glob(v);
  680. 680
    		if (v == 0)
  681. 681
    			bferr("No match");
  682. 682
    	} else
  683. 683
    		scan(v, trim);
  684. 684
    	while (cp = *v++) {
  685. 685
    		register int c;
  686. 686
  687. 687
    		while (c = *cp++) {
  688. 688
    			if (sep == ' ' && *cp && c == '\\') {
  689. 689
    				c = *cp++;
  690. 690
    				if (c == 'c') {
  691. 691
    					flush();
  692. 692
    					return;
  693. 693
    				} else if (c == 'n')
  694. 694
    					c = '\n';
  695. 695
    				else
  696. 696
    					putchar('\\');
  697. 697
    			}
  698. 698
    			putchar(c | QUOTE);
  699. 699
    		}
  700. 700
    		if (*v)
  701. 701
    			putchar(sep | QUOTE);
  702. 702
    	}
  703. 703
    	if (sep)
  704. 704
    		putchar('\n');
  705. 705
    	if (setintr)
  706. 706
    		signal(SIGINT, saveintr);
  707. 707
    	if (gargv)
  708. 708
    		blkfree(gargv), gargv = 0;
  709. 709
    }
  710. 710
  711. 711
    #ifndef	V6
  712. 712
    char	**environ;
  713. 713
  714. 714
    dosetenv(v)
  715. 715
    	register char **v;
  716. 716
    {
  717. 717
    	char *lp = globone(v[2]);
  718. 718
  719. 719
    	setenv(v[1], lp);
  720. 720
    	xfree(lp);
  721. 721
    }
  722. 722
  723. 723
    setenv(name, value)
  724. 724
    	char *name, *value;
  725. 725
    {
  726. 726
    	register char **ep = environ;
  727. 727
    	register char *cp, *dp;
  728. 728
    	char *blk[2], **oep = ep;
  729. 729
  730. 730
    	for (; *ep; ep++) {
  731. 731
    		for (cp = name, dp = *ep; *cp && *cp == *dp; cp++, dp++)
  732. 732
    			continue;
  733. 733
    		if (*cp != 0 || *dp != '=')
  734. 734
    			continue;
  735. 735
    		cp = strspl("=", value);
  736. 736
    		xfree(*ep);
  737. 737
    		*ep = strspl(name, cp);
  738. 738
    		xfree(cp);
  739. 739
    		return;
  740. 740
    	}
  741. 741
    	blk[0] = strspl(name, "="); blk[1] = 0;
  742. 742
    	environ = blkspl(environ, blk);
  743. 743
    	xfree(oep);
  744. 744
    	setenv(name, value);
  745. 745
    }
  746. 746
  747. 747
    doumask(v)
  748. 748
    	register char **v;
  749. 749
    {
  750. 750
    	register char *cp = v[1];
  751. 751
    	register int i;
  752. 752
  753. 753
    	if (cp == 0) {
  754. 754
    		i = umask(0);
  755. 755
    		umask(i);
  756. 756
    		printf("%o\n", i);
  757. 757
    		return;
  758. 758
    	}
  759. 759
    	i = 0;
  760. 760
    	while (digit(*cp) && *cp != '8' && *cp != '9')
  761. 761
    		i = i * 8 + *cp++ - '0';
  762. 762
    	if (*cp || i < 0 || i > 0777)
  763. 763
    		bferr("Improper mask");
  764. 764
    	umask(i);
  765. 765
    }
  766. 766
    #endif

To the top of this page