| [2460] | 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 | #include <sys/cdefs.h>
 | 
|---|
 | 36 | #ifndef lint
 | 
|---|
 | 37 | #if 0
 | 
|---|
 | 38 | static char sccsid[] = "@(#)show.c      8.3 (Berkeley) 5/4/95";
 | 
|---|
 | 39 | #else
 | 
|---|
 | 40 | __RCSID("$NetBSD: show.c,v 1.26 2003/11/14 10:46:13 dsl Exp $");
 | 
|---|
 | 41 | #endif
 | 
|---|
 | 42 | #endif /* not lint */
 | 
|---|
 | 43 | 
 | 
|---|
 | 44 | #include <stdio.h>
 | 
|---|
 | 45 | #include <stdarg.h>
 | 
|---|
 | 46 | #include <stdlib.h>
 | 
|---|
 | 47 | 
 | 
|---|
 | 48 | #include "shell.h"
 | 
|---|
 | 49 | #include "parser.h"
 | 
|---|
 | 50 | #include "nodes.h"
 | 
|---|
 | 51 | #include "mystring.h"
 | 
|---|
 | 52 | #include "show.h"
 | 
|---|
 | 53 | #include "options.h"
 | 
|---|
 | 54 | 
 | 
|---|
 | 55 | 
 | 
|---|
 | 56 | #ifdef DEBUG
 | 
|---|
 | 57 | static void shtree(union node *, int, char *, FILE*);
 | 
|---|
 | 58 | static void shcmd(union node *, FILE *);
 | 
|---|
 | 59 | static void sharg(union node *, FILE *);
 | 
|---|
 | 60 | static void indent(int, char *, FILE *);
 | 
|---|
 | 61 | static void trstring(char *);
 | 
|---|
 | 62 | 
 | 
|---|
 | 63 | 
 | 
|---|
 | 64 | void
 | 
|---|
 | 65 | showtree(union node *n)
 | 
|---|
 | 66 | {
 | 
|---|
 | 67 |         trputs("showtree called\n");
 | 
|---|
 | 68 |         shtree(n, 1, NULL, stdout);
 | 
|---|
 | 69 | }
 | 
|---|
 | 70 | 
 | 
|---|
 | 71 | 
 | 
|---|
 | 72 | static void
 | 
|---|
 | 73 | shtree(union node *n, int ind, char *pfx, FILE *fp)
 | 
|---|
 | 74 | {
 | 
|---|
 | 75 |         struct nodelist *lp;
 | 
|---|
 | 76 |         const char *s;
 | 
|---|
 | 77 | 
 | 
|---|
 | 78 |         if (n == NULL)
 | 
|---|
 | 79 |                 return;
 | 
|---|
 | 80 | 
 | 
|---|
 | 81 |         indent(ind, pfx, fp);
 | 
|---|
 | 82 |         switch(n->type) {
 | 
|---|
 | 83 |         case NSEMI:
 | 
|---|
 | 84 |                 s = "; ";
 | 
|---|
 | 85 |                 goto binop;
 | 
|---|
 | 86 |         case NAND:
 | 
|---|
 | 87 |                 s = " && ";
 | 
|---|
 | 88 |                 goto binop;
 | 
|---|
 | 89 |         case NOR:
 | 
|---|
 | 90 |                 s = " || ";
 | 
|---|
 | 91 | binop:
 | 
|---|
 | 92 |                 shtree(n->nbinary.ch1, ind, NULL, fp);
 | 
|---|
 | 93 |            /*    if (ind < 0) */
 | 
|---|
 | 94 |                         fputs(s, fp);
 | 
|---|
 | 95 |                 shtree(n->nbinary.ch2, ind, NULL, fp);
 | 
|---|
 | 96 |                 break;
 | 
|---|
 | 97 |         case NCMD:
 | 
|---|
 | 98 |                 shcmd(n, fp);
 | 
|---|
 | 99 |                 if (ind >= 0)
 | 
|---|
 | 100 |                         putc('\n', fp);
 | 
|---|
 | 101 |                 break;
 | 
|---|
 | 102 |         case NPIPE:
 | 
|---|
 | 103 |                 for (lp = n->npipe.cmdlist ; lp ; lp = lp->next) {
 | 
|---|
 | 104 |                         shcmd(lp->n, fp);
 | 
|---|
 | 105 |                         if (lp->next)
 | 
|---|
 | 106 |                                 fputs(" | ", fp);
 | 
|---|
 | 107 |                 }
 | 
|---|
 | 108 |                 if (n->npipe.backgnd)
 | 
|---|
 | 109 |                         fputs(" &", fp);
 | 
|---|
 | 110 |                 if (ind >= 0)
 | 
|---|
 | 111 |                         putc('\n', fp);
 | 
|---|
 | 112 |                 break;
 | 
|---|
 | 113 |         default:
 | 
|---|
 | 114 |                 fprintf(fp, "<node type %d>", n->type);
 | 
|---|
 | 115 |                 if (ind >= 0)
 | 
|---|
 | 116 |                         putc('\n', fp);
 | 
|---|
 | 117 |                 break;
 | 
|---|
 | 118 |         }
 | 
|---|
 | 119 | }
 | 
|---|
 | 120 | 
 | 
|---|
 | 121 | 
 | 
|---|
 | 122 | 
 | 
|---|
 | 123 | static void
 | 
|---|
 | 124 | shcmd(union node *cmd, FILE *fp)
 | 
|---|
 | 125 | {
 | 
|---|
 | 126 |         union node *np;
 | 
|---|
 | 127 |         int first;
 | 
|---|
 | 128 |         const char *s;
 | 
|---|
 | 129 |         int dftfd;
 | 
|---|
 | 130 | 
 | 
|---|
 | 131 |         first = 1;
 | 
|---|
 | 132 |         for (np = cmd->ncmd.args ; np ; np = np->narg.next) {
 | 
|---|
 | 133 |                 if (! first)
 | 
|---|
 | 134 |                         putchar(' ');
 | 
|---|
 | 135 |                 sharg(np, fp);
 | 
|---|
 | 136 |                 first = 0;
 | 
|---|
 | 137 |         }
 | 
|---|
 | 138 |         for (np = cmd->ncmd.redirect ; np ; np = np->nfile.next) {
 | 
|---|
 | 139 |                 if (! first)
 | 
|---|
 | 140 |                         putchar(' ');
 | 
|---|
 | 141 |                 switch (np->nfile.type) {
 | 
|---|
 | 142 |                         case NTO:       s = ">";  dftfd = 1; break;
 | 
|---|
 | 143 |                         case NCLOBBER:  s = ">|"; dftfd = 1; break;
 | 
|---|
 | 144 |                         case NAPPEND:   s = ">>"; dftfd = 1; break;
 | 
|---|
 | 145 |                         case NTOFD:     s = ">&"; dftfd = 1; break;
 | 
|---|
 | 146 |                         case NFROM:     s = "<";  dftfd = 0; break;
 | 
|---|
 | 147 |                         case NFROMFD:   s = "<&"; dftfd = 0; break;
 | 
|---|
 | 148 |                         case NFROMTO:   s = "<>"; dftfd = 0; break;
 | 
|---|
 | 149 |                         default:        s = "*error*"; dftfd = 0; break;
 | 
|---|
 | 150 |                 }
 | 
|---|
 | 151 |                 if (np->nfile.fd != dftfd)
 | 
|---|
 | 152 |                         fprintf(fp, "%d", np->nfile.fd);
 | 
|---|
 | 153 |                 fputs(s, fp);
 | 
|---|
 | 154 |                 if (np->nfile.type == NTOFD || np->nfile.type == NFROMFD) {
 | 
|---|
 | 155 |                         fprintf(fp, "%d", np->ndup.dupfd);
 | 
|---|
 | 156 |                 } else {
 | 
|---|
 | 157 |                         sharg(np->nfile.fname, fp);
 | 
|---|
 | 158 |                 }
 | 
|---|
 | 159 |                 first = 0;
 | 
|---|
 | 160 |         }
 | 
|---|
 | 161 | }
 | 
|---|
 | 162 | 
 | 
|---|
 | 163 | 
 | 
|---|
 | 164 | 
 | 
|---|
 | 165 | static void
 | 
|---|
 | 166 | sharg(union node *arg, FILE *fp)
 | 
|---|
 | 167 | {
 | 
|---|
 | 168 |         char *p;
 | 
|---|
 | 169 |         struct nodelist *bqlist;
 | 
|---|
 | 170 |         int subtype;
 | 
|---|
 | 171 | 
 | 
|---|
 | 172 |         if (arg->type != NARG) {
 | 
|---|
 | 173 |                 printf("<node type %d>\n", arg->type);
 | 
|---|
 | 174 |                 abort();
 | 
|---|
 | 175 |         }
 | 
|---|
 | 176 |         bqlist = arg->narg.backquote;
 | 
|---|
 | 177 |         for (p = arg->narg.text ; *p ; p++) {
 | 
|---|
 | 178 |                 switch (*p) {
 | 
|---|
 | 179 |                 case CTLESC:
 | 
|---|
 | 180 |                         putc(*++p, fp);
 | 
|---|
 | 181 |                         break;
 | 
|---|
 | 182 |                 case CTLVAR:
 | 
|---|
 | 183 |                         putc('$', fp);
 | 
|---|
 | 184 |                         putc('{', fp);
 | 
|---|
 | 185 |                         subtype = *++p;
 | 
|---|
 | 186 |                         if (subtype == VSLENGTH)
 | 
|---|
 | 187 |                                 putc('#', fp);
 | 
|---|
 | 188 | 
 | 
|---|
 | 189 |                         while (*p != '=')
 | 
|---|
 | 190 |                                 putc(*p++, fp);
 | 
|---|
 | 191 | 
 | 
|---|
 | 192 |                         if (subtype & VSNUL)
 | 
|---|
 | 193 |                                 putc(':', fp);
 | 
|---|
 | 194 | 
 | 
|---|
 | 195 |                         switch (subtype & VSTYPE) {
 | 
|---|
 | 196 |                         case VSNORMAL:
 | 
|---|
 | 197 |                                 putc('}', fp);
 | 
|---|
 | 198 |                                 break;
 | 
|---|
 | 199 |                         case VSMINUS:
 | 
|---|
 | 200 |                                 putc('-', fp);
 | 
|---|
 | 201 |                                 break;
 | 
|---|
 | 202 |                         case VSPLUS:
 | 
|---|
 | 203 |                                 putc('+', fp);
 | 
|---|
 | 204 |                                 break;
 | 
|---|
 | 205 |                         case VSQUESTION:
 | 
|---|
 | 206 |                                 putc('?', fp);
 | 
|---|
 | 207 |                                 break;
 | 
|---|
 | 208 |                         case VSASSIGN:
 | 
|---|
 | 209 |                                 putc('=', fp);
 | 
|---|
 | 210 |                                 break;
 | 
|---|
 | 211 |                         case VSTRIMLEFT:
 | 
|---|
 | 212 |                                 putc('#', fp);
 | 
|---|
 | 213 |                                 break;
 | 
|---|
 | 214 |                         case VSTRIMLEFTMAX:
 | 
|---|
 | 215 |                                 putc('#', fp);
 | 
|---|
 | 216 |                                 putc('#', fp);
 | 
|---|
 | 217 |                                 break;
 | 
|---|
 | 218 |                         case VSTRIMRIGHT:
 | 
|---|
 | 219 |                                 putc('%', fp);
 | 
|---|
 | 220 |                                 break;
 | 
|---|
 | 221 |                         case VSTRIMRIGHTMAX:
 | 
|---|
 | 222 |                                 putc('%', fp);
 | 
|---|
 | 223 |                                 putc('%', fp);
 | 
|---|
 | 224 |                                 break;
 | 
|---|
 | 225 |                         case VSLENGTH:
 | 
|---|
 | 226 |                                 break;
 | 
|---|
 | 227 |                         default:
 | 
|---|
 | 228 |                                 printf("<subtype %d>", subtype);
 | 
|---|
 | 229 |                         }
 | 
|---|
 | 230 |                         break;
 | 
|---|
 | 231 |                 case CTLENDVAR:
 | 
|---|
 | 232 |                      putc('}', fp);
 | 
|---|
 | 233 |                      break;
 | 
|---|
 | 234 |                 case CTLBACKQ:
 | 
|---|
 | 235 |                 case CTLBACKQ|CTLQUOTE:
 | 
|---|
 | 236 |                         putc('$', fp);
 | 
|---|
 | 237 |                         putc('(', fp);
 | 
|---|
 | 238 |                         shtree(bqlist->n, -1, NULL, fp);
 | 
|---|
 | 239 |                         putc(')', fp);
 | 
|---|
 | 240 |                         break;
 | 
|---|
 | 241 |                 default:
 | 
|---|
 | 242 |                         putc(*p, fp);
 | 
|---|
 | 243 |                         break;
 | 
|---|
 | 244 |                 }
 | 
|---|
 | 245 |         }
 | 
|---|
 | 246 | }
 | 
|---|
 | 247 | 
 | 
|---|
 | 248 | 
 | 
|---|
 | 249 | static void
 | 
|---|
 | 250 | indent(int amount, char *pfx, FILE *fp)
 | 
|---|
 | 251 | {
 | 
|---|
 | 252 |         int i;
 | 
|---|
 | 253 | 
 | 
|---|
 | 254 |         for (i = 0 ; i < amount ; i++) {
 | 
|---|
 | 255 |                 if (pfx && i == amount - 1)
 | 
|---|
 | 256 |                         fputs(pfx, fp);
 | 
|---|
 | 257 |                 putc('\t', fp);
 | 
|---|
 | 258 |         }
 | 
|---|
 | 259 | }
 | 
|---|
 | 260 | #endif
 | 
|---|
 | 261 | 
 | 
|---|
 | 262 | 
 | 
|---|
 | 263 | 
 | 
|---|
 | 264 | /*
 | 
|---|
 | 265 |  * Debugging stuff.
 | 
|---|
 | 266 |  */
 | 
|---|
 | 267 | 
 | 
|---|
 | 268 | 
 | 
|---|
 | 269 | FILE *tracefile;
 | 
|---|
 | 270 | 
 | 
|---|
 | 271 | 
 | 
|---|
 | 272 | #ifdef DEBUG
 | 
|---|
 | 273 | void
 | 
|---|
 | 274 | trputc(int c)
 | 
|---|
 | 275 | {
 | 
|---|
 | 276 |         if (debug != 1)
 | 
|---|
 | 277 |                 return;
 | 
|---|
 | 278 |         putc(c, tracefile);
 | 
|---|
 | 279 | }
 | 
|---|
 | 280 | #endif
 | 
|---|
 | 281 | 
 | 
|---|
 | 282 | void
 | 
|---|
 | 283 | trace(const char *fmt, ...)
 | 
|---|
 | 284 | {
 | 
|---|
 | 285 | #ifdef DEBUG
 | 
|---|
 | 286 |         va_list va;
 | 
|---|
 | 287 | 
 | 
|---|
 | 288 |         if (debug != 1)
 | 
|---|
 | 289 |                 return;
 | 
|---|
| [2463] | 290 |         fprintf(tracefile, "[%d] ", getpid());
 | 
|---|
| [2460] | 291 |         va_start(va, fmt);
 | 
|---|
 | 292 |         (void) vfprintf(tracefile, fmt, va);
 | 
|---|
 | 293 |         va_end(va);
 | 
|---|
 | 294 | #endif
 | 
|---|
 | 295 | }
 | 
|---|
 | 296 | 
 | 
|---|
 | 297 | void
 | 
|---|
 | 298 | tracev(const char *fmt, va_list va)
 | 
|---|
 | 299 | {
 | 
|---|
 | 300 | #ifdef DEBUG
 | 
|---|
 | 301 |         if (debug != 1)
 | 
|---|
 | 302 |                 return;
 | 
|---|
| [2463] | 303 |         fprintf(tracefile, "[%d] ", getpid());
 | 
|---|
| [2460] | 304 |         (void) vfprintf(tracefile, fmt, va);
 | 
|---|
 | 305 | #endif
 | 
|---|
 | 306 | }
 | 
|---|
 | 307 | 
 | 
|---|
 | 308 | 
 | 
|---|
 | 309 | #ifdef DEBUG
 | 
|---|
 | 310 | void
 | 
|---|
 | 311 | trputs(const char *s)
 | 
|---|
 | 312 | {
 | 
|---|
 | 313 |         if (debug != 1)
 | 
|---|
 | 314 |                 return;
 | 
|---|
 | 315 |         fputs(s, tracefile);
 | 
|---|
 | 316 | }
 | 
|---|
 | 317 | 
 | 
|---|
 | 318 | 
 | 
|---|
 | 319 | static void
 | 
|---|
 | 320 | trstring(char *s)
 | 
|---|
 | 321 | {
 | 
|---|
 | 322 |         char *p;
 | 
|---|
 | 323 |         char c;
 | 
|---|
 | 324 | 
 | 
|---|
 | 325 |         if (debug != 1)
 | 
|---|
 | 326 |                 return;
 | 
|---|
 | 327 |         putc('"', tracefile);
 | 
|---|
 | 328 |         for (p = s ; *p ; p++) {
 | 
|---|
 | 329 |                 switch (*p) {
 | 
|---|
 | 330 |                 case '\n':  c = 'n';  goto backslash;
 | 
|---|
 | 331 |                 case '\t':  c = 't';  goto backslash;
 | 
|---|
 | 332 |                 case '\r':  c = 'r';  goto backslash;
 | 
|---|
 | 333 |                 case '"':  c = '"';  goto backslash;
 | 
|---|
 | 334 |                 case '\\':  c = '\\';  goto backslash;
 | 
|---|
 | 335 |                 case CTLESC:  c = 'e';  goto backslash;
 | 
|---|
 | 336 |                 case CTLVAR:  c = 'v';  goto backslash;
 | 
|---|
 | 337 |                 case CTLVAR+CTLQUOTE:  c = 'V';  goto backslash;
 | 
|---|
 | 338 |                 case CTLBACKQ:  c = 'q';  goto backslash;
 | 
|---|
 | 339 |                 case CTLBACKQ+CTLQUOTE:  c = 'Q';  goto backslash;
 | 
|---|
 | 340 | backslash:        putc('\\', tracefile);
 | 
|---|
 | 341 |                         putc(c, tracefile);
 | 
|---|
 | 342 |                         break;
 | 
|---|
 | 343 |                 default:
 | 
|---|
 | 344 |                         if (*p >= ' ' && *p <= '~')
 | 
|---|
 | 345 |                                 putc(*p, tracefile);
 | 
|---|
 | 346 |                         else {
 | 
|---|
 | 347 |                                 putc('\\', tracefile);
 | 
|---|
 | 348 |                                 putc(*p >> 6 & 03, tracefile);
 | 
|---|
 | 349 |                                 putc(*p >> 3 & 07, tracefile);
 | 
|---|
 | 350 |                                 putc(*p & 07, tracefile);
 | 
|---|
 | 351 |                         }
 | 
|---|
 | 352 |                         break;
 | 
|---|
 | 353 |                 }
 | 
|---|
 | 354 |         }
 | 
|---|
 | 355 |         putc('"', tracefile);
 | 
|---|
 | 356 | }
 | 
|---|
 | 357 | #endif
 | 
|---|
 | 358 | 
 | 
|---|
 | 359 | 
 | 
|---|
 | 360 | void
 | 
|---|
 | 361 | trargs(char **ap)
 | 
|---|
 | 362 | {
 | 
|---|
 | 363 | #ifdef DEBUG
 | 
|---|
 | 364 |         if (debug != 1)
 | 
|---|
 | 365 |                 return;
 | 
|---|
 | 366 |         while (*ap) {
 | 
|---|
 | 367 |                 trstring(*ap++);
 | 
|---|
 | 368 |                 if (*ap)
 | 
|---|
 | 369 |                         putc(' ', tracefile);
 | 
|---|
 | 370 |                 else
 | 
|---|
 | 371 |                         putc('\n', tracefile);
 | 
|---|
 | 372 |         }
 | 
|---|
 | 373 | #endif
 | 
|---|
 | 374 | }
 | 
|---|
 | 375 | 
 | 
|---|
 | 376 | 
 | 
|---|
 | 377 | #ifdef DEBUG
 | 
|---|
 | 378 | void
 | 
|---|
 | 379 | opentrace(void)
 | 
|---|
 | 380 | {
 | 
|---|
 | 381 |         char s[100];
 | 
|---|
 | 382 | #ifdef O_APPEND
 | 
|---|
 | 383 |         int flags;
 | 
|---|
 | 384 | #endif
 | 
|---|
 | 385 | 
 | 
|---|
 | 386 |         if (debug != 1) {
 | 
|---|
 | 387 |                 if (tracefile)
 | 
|---|
 | 388 |                         fflush(tracefile);
 | 
|---|
 | 389 |                 /* leave open because libedit might be using it */
 | 
|---|
 | 390 |                 return;
 | 
|---|
 | 391 |         }
 | 
|---|
 | 392 | #ifdef not_this_way
 | 
|---|
 | 393 |         {
 | 
|---|
 | 394 |                 char *p;
 | 
|---|
 | 395 |                 if ((p = getenv("HOME")) == NULL) {
 | 
|---|
 | 396 |                         if (geteuid() == 0)
 | 
|---|
 | 397 |                                 p = "/";
 | 
|---|
 | 398 |                         else
 | 
|---|
 | 399 |                                 p = "/tmp";
 | 
|---|
 | 400 |                 }
 | 
|---|
 | 401 |                 scopy(p, s);
 | 
|---|
 | 402 |                 strcat(s, "/trace");
 | 
|---|
 | 403 |         }
 | 
|---|
 | 404 | #else
 | 
|---|
 | 405 |         scopy("./trace", s);
 | 
|---|
 | 406 | #endif /* not_this_way */
 | 
|---|
 | 407 |         if (tracefile) {
 | 
|---|
 | 408 |                 if (!freopen(s, "a", tracefile)) {
 | 
|---|
 | 409 |                         fprintf(stderr, "Can't re-open %s\n", s);
 | 
|---|
 | 410 |                         debug = 0;
 | 
|---|
 | 411 |                         return;
 | 
|---|
 | 412 |                 }
 | 
|---|
 | 413 |         } else {
 | 
|---|
 | 414 |                 if ((tracefile = fopen(s, "a")) == NULL) {
 | 
|---|
 | 415 |                         fprintf(stderr, "Can't open %s\n", s);
 | 
|---|
 | 416 |                         debug = 0;
 | 
|---|
 | 417 |                         return;
 | 
|---|
 | 418 |                 }
 | 
|---|
 | 419 |         }
 | 
|---|
 | 420 | #ifdef O_APPEND
 | 
|---|
 | 421 |         if ((flags = fcntl(fileno(tracefile), F_GETFL, 0)) >= 0)
 | 
|---|
 | 422 |                 fcntl(fileno(tracefile), F_SETFL, flags | O_APPEND);
 | 
|---|
 | 423 | #endif
 | 
|---|
 | 424 |         setlinebuf(tracefile);
 | 
|---|
 | 425 |         fputs("\nTracing started.\n", tracefile);
 | 
|---|
 | 426 | }
 | 
|---|
 | 427 | #endif /* DEBUG */
 | 
|---|