VirtualBox

source: kBuild/trunk/src/ash/show.c@ 2302

Last change on this file since 2302 was 2140, checked in by bird, 16 years ago

ash: Changed opentrace so that the trace file get's a high file descriptor.

  • Property svn:eol-style set to native
File size: 8.9 KB
Line 
1/* $NetBSD: show.c,v 1.26 2003/11/14 10:46:13 dsl Exp $ */
2
3/*-
4 * Copyright (c) 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 *
7 * This code is derived from software contributed to Berkeley by
8 * Kenneth Almquist.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. Neither the name of the University nor the names of its contributors
19 * may be used to endorse or promote products derived from this software
20 * without specific prior written permission.
21 *
22 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
23 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
24 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
25 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
26 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
27 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
28 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
29 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * SUCH DAMAGE.
33 */
34
35#ifdef HAVE_SYS_CDEFS_H
36#include <sys/cdefs.h>
37#endif
38#ifndef lint
39#if 0
40static char sccsid[] = "@(#)show.c 8.3 (Berkeley) 5/4/95";
41#else
42__RCSID("$NetBSD: show.c,v 1.26 2003/11/14 10:46:13 dsl Exp $");
43#endif
44#endif /* not lint */
45
46#include <stdio.h>
47#include <stdarg.h>
48#include <stdlib.h>
49#include <sys/fcntl.h>
50#include <unistd.h>
51
52#include "shell.h"
53#include "parser.h"
54#include "nodes.h"
55#include "mystring.h"
56#include "show.h"
57#include "options.h"
58
59
60#ifdef DEBUG
61static void shtree(union node *, int, char *, FILE*);
62static void shcmd(union node *, FILE *);
63static void sharg(union node *, FILE *);
64static void indent(int, char *, FILE *);
65static void trstring(char *);
66
67
68void
69showtree(union node *n)
70{
71 trputs("showtree called\n");
72 shtree(n, 1, NULL, stdout);
73}
74
75
76static void
77shtree(union node *n, int ind, char *pfx, FILE *fp)
78{
79 struct nodelist *lp;
80 const char *s;
81
82 if (n == NULL)
83 return;
84
85 indent(ind, pfx, fp);
86 switch(n->type) {
87 case NSEMI:
88 s = "; ";
89 goto binop;
90 case NAND:
91 s = " && ";
92 goto binop;
93 case NOR:
94 s = " || ";
95binop:
96 shtree(n->nbinary.ch1, ind, NULL, fp);
97 /* if (ind < 0) */
98 fputs(s, fp);
99 shtree(n->nbinary.ch2, ind, NULL, fp);
100 break;
101 case NCMD:
102 shcmd(n, fp);
103 if (ind >= 0)
104 putc('\n', fp);
105 break;
106 case NPIPE:
107 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
108 shcmd(lp->n, fp);
109 if (lp->next)
110 fputs(" | ", fp);
111 }
112 if (n->npipe.backgnd)
113 fputs(" &", fp);
114 if (ind >= 0)
115 putc('\n', fp);
116 break;
117 default:
118 fprintf(fp, "<node type %d>", n->type);
119 if (ind >= 0)
120 putc('\n', fp);
121 break;
122 }
123}
124
125
126
127static void
128shcmd(union node *cmd, FILE *fp)
129{
130 union node *np;
131 int first;
132 const char *s;
133 int dftfd;
134
135 first = 1;
136 for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
137 if (! first)
138 putchar(' ');
139 sharg(np, fp);
140 first = 0;
141 }
142 for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
143 if (! first)
144 putchar(' ');
145 switch (np->nfile.type) {
146 case NTO: s = ">"; dftfd = 1; break;
147 case NCLOBBER: s = ">|"; dftfd = 1; break;
148 case NAPPEND: s = ">>"; dftfd = 1; break;
149 case NTOFD: s = ">&"; dftfd = 1; break;
150 case NFROM: s = "<"; dftfd = 0; break;
151 case NFROMFD: s = "<&"; dftfd = 0; break;
152 case NFROMTO: s = "<>"; dftfd = 0; break;
153 default: s = "*error*"; dftfd = 0; break;
154 }
155 if (np->nfile.fd != dftfd)
156 fprintf(fp, "%d", np->nfile.fd);
157 fputs(s, fp);
158 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
159 fprintf(fp, "%d", np->ndup.dupfd);
160 } else {
161 sharg(np->nfile.fname, fp);
162 }
163 first = 0;
164 }
165}
166
167
168
169static void
170sharg(union node *arg, FILE *fp)
171{
172 char *p;
173 struct nodelist *bqlist;
174 int subtype;
175
176 if (arg->type != NARG) {
177 printf("<node type %d>\n", arg->type);
178 abort();
179 }
180 bqlist = arg->narg.backquote;
181 for (p = arg->narg.text ; *p ; p++) {
182 switch (*p) {
183 case CTLESC:
184 putc(*++p, fp);
185 break;
186 case CTLVAR:
187 putc('$', fp);
188 putc('{', fp);
189 subtype = *++p;
190 if (subtype == VSLENGTH)
191 putc('#', fp);
192
193 while (*p != '=')
194 putc(*p++, fp);
195
196 if (subtype & VSNUL)
197 putc(':', fp);
198
199 switch (subtype & VSTYPE) {
200 case VSNORMAL:
201 putc('}', fp);
202 break;
203 case VSMINUS:
204 putc('-', fp);
205 break;
206 case VSPLUS:
207 putc('+', fp);
208 break;
209 case VSQUESTION:
210 putc('?', fp);
211 break;
212 case VSASSIGN:
213 putc('=', fp);
214 break;
215 case VSTRIMLEFT:
216 putc('#', fp);
217 break;
218 case VSTRIMLEFTMAX:
219 putc('#', fp);
220 putc('#', fp);
221 break;
222 case VSTRIMRIGHT:
223 putc('%', fp);
224 break;
225 case VSTRIMRIGHTMAX:
226 putc('%', fp);
227 putc('%', fp);
228 break;
229 case VSLENGTH:
230 break;
231 default:
232 printf("<subtype %d>", subtype);
233 }
234 break;
235 case CTLENDVAR:
236 putc('}', fp);
237 break;
238 case CTLBACKQ:
239 case CTLBACKQ|CTLQUOTE:
240 putc('$', fp);
241 putc('(', fp);
242 shtree(bqlist->n, -1, NULL, fp);
243 putc(')', fp);
244 break;
245 default:
246 putc(*p, fp);
247 break;
248 }
249 }
250}
251
252
253static void
254indent(int amount, char *pfx, FILE *fp)
255{
256 int i;
257
258 for (i = 0 ; i < amount ; i++) {
259 if (pfx && i == amount - 1)
260 fputs(pfx, fp);
261 putc('\t', fp);
262 }
263}
264#endif
265
266
267
268/*
269 * Debugging stuff.
270 */
271
272
273FILE *tracefile;
274
275
276#ifdef DEBUG
277void
278trputc(int c)
279{
280 if (debug != 1)
281 return;
282 putc(c, tracefile);
283}
284#endif
285
286void
287trace(const char *fmt, ...)
288{
289#ifdef DEBUG
290 va_list va;
291
292 if (debug != 1)
293 return;
294 fprintf(tracefile, "[%d] ", getpid());
295 va_start(va, fmt);
296 (void) vfprintf(tracefile, fmt, va);
297 va_end(va);
298#endif
299}
300
301void
302tracev(const char *fmt, va_list va)
303{
304#ifdef DEBUG
305 if (debug != 1)
306 return;
307 fprintf(tracefile, "[%d] ", getpid());
308 (void) vfprintf(tracefile, fmt, va);
309#endif
310}
311
312
313#ifdef DEBUG
314void
315trputs(const char *s)
316{
317 if (debug != 1)
318 return;
319 fputs(s, tracefile);
320}
321
322
323static void
324trstring(char *s)
325{
326 char *p;
327 char c;
328
329 if (debug != 1)
330 return;
331 putc('"', tracefile);
332 for (p = s ; *p ; p++) {
333 switch (*p) {
334 case '\n': c = 'n'; goto backslash;
335 case '\t': c = 't'; goto backslash;
336 case '\r': c = 'r'; goto backslash;
337 case '"': c = '"'; goto backslash;
338 case '\\': c = '\\'; goto backslash;
339 case CTLESC: c = 'e'; goto backslash;
340 case CTLVAR: c = 'v'; goto backslash;
341 case CTLVAR+CTLQUOTE: c = 'V'; goto backslash;
342 case CTLBACKQ: c = 'q'; goto backslash;
343 case CTLBACKQ+CTLQUOTE: c = 'Q'; goto backslash;
344backslash: putc('\\', tracefile);
345 putc(c, tracefile);
346 break;
347 default:
348 if (*p >= ' ' && *p <= '~')
349 putc(*p, tracefile);
350 else {
351 putc('\\', tracefile);
352 putc(*p >> 6 & 03, tracefile);
353 putc(*p >> 3 & 07, tracefile);
354 putc(*p & 07, tracefile);
355 }
356 break;
357 }
358 }
359 putc('"', tracefile);
360}
361#endif
362
363
364void
365trargs(char **ap)
366{
367#ifdef DEBUG
368 if (debug != 1)
369 return;
370 while (*ap) {
371 trstring(*ap++);
372 if (*ap)
373 putc(' ', tracefile);
374 else
375 putc('\n', tracefile);
376 }
377#endif
378}
379
380
381#ifdef DEBUG
382void
383opentrace(void)
384{
385 char s[100];
386#ifdef O_APPEND
387 int flags;
388#endif
389#if 1
390 int fd;
391#endif
392
393 if (debug != 1) {
394 if (tracefile)
395 fflush(tracefile);
396 /* leave open because libedit might be using it */
397 return;
398 }
399#ifdef not_this_way
400 {
401 char *p;
402 if ((p = getenv("HOME")) == NULL) {
403 if (geteuid() == 0)
404 p = "/";
405 else
406 p = "/tmp";
407 }
408 scopy(p, s);
409 strcat(s, "/trace");
410 }
411#else
412 scopy("./trace", s);
413#endif /* not_this_way */
414 if (tracefile) {
415 if (!freopen(s, "a", tracefile)) {
416 fprintf(stderr, "Can't re-open %s\n", s);
417 debug = 0;
418 return;
419 }
420 trace("opentrace: fno=%d - freopen\n", fileno(tracefile));
421 } else {
422#if 0
423 if ((tracefile = fopen(s, "a")) == NULL) {
424#else
425 fd = open(s, O_APPEND | O_RDWR | O_CREAT, 0600);
426 if (fd != -1) {
427 int fd2 = fcntl(fd, F_DUPFD, 199);
428 if (fd2 == -1)
429 fd2 = fcntl(fd, F_DUPFD, 99);
430 if (fd2 == -1)
431 fd2 = fcntl(fd, F_DUPFD, 49);
432 if (fd2 == -1)
433 fd2 = fcntl(fd, F_DUPFD, 18);
434 if (fd2 == -1)
435 fd2 = fcntl(fd, F_DUPFD, 10);
436 if (fd2 != -1) {
437 close(fd);
438 fd = fd2;
439 }
440 }
441 if (fd == -1 || (tracefile = fdopen(fd, "a")) == NULL) {
442#endif
443 fprintf(stderr, "Can't open %s\n", s);
444 debug = 0;
445 return;
446 }
447 trace("opentrace: fno=%d\n", fileno(tracefile));
448 }
449#ifdef O_APPEND
450 if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
451 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
452#endif
453 setlinebuf(tracefile);
454 fputs("\nTracing started.\n", tracefile);
455}
456#endif /* DEBUG */
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette