VirtualBox

Changeset 2296 in kBuild for trunk/src/kash/show.c


Ignore:
Timestamp:
Mar 1, 2009 1:54:30 AM (16 years ago)
Author:
bird
Message:

kash: avoid file steams in the trace code.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kash/show.c

    r2293 r2296  
    4444#include <stdarg.h>
    4545#include <stdlib.h>
     46#include <assert.h>
    4647
    4748#include "shell.h"
     
    266267 */
    267268
    268 
     269#ifdef DEBUG
     270#ifdef TRACE_VIA_STDIO
    269271FILE *tracefile;
    270 
    271 
    272 #ifdef DEBUG
     272#endif
     273
     274/** @def TRY_GET_PSH_OR_RETURN
     275 * Make sure @a psh is valid, trying to fetch it from TLS
     276 * if it's NULL and returning (void) if that fails. */
     277# define TRY_GET_PSH_OR_RETURN(psh)  \
     278        if (!(psh)) { \
     279                psh = shthread_get_shell(); \
     280                if (!psh) \
     281                        return; \
     282        } else do { } while (0)
     283
     284/** @def RETURN_IF_NOT_TRACING
     285 * Return if we're not tracing. */
     286# ifdef TRACE_VIA_STDIO
     287#  define RETURN_IF_NOT_TRACING(psh) \
     288        if (debug(psh) != 1 || !tracefile)
     289                return; \
     290        else do {} while (0)
     291# else
     292#  define RETURN_IF_NOT_TRACING(psh) \
     293        if (debug(psh) != 1 || psh->tracefd == -1) \
     294                return; \
     295        else do {} while (0)
     296# endif
     297
     298/** @def TRACE_PUTC
     299 * putc/trace_char wrapper. The @a psh / @a tracefile
     300 * is taken from the context and not as a paramenter. */
     301# ifdef TRACE_VIA_STDIO
     302#  define TRACE_PUTC(c)         fputc(c, tracefile)
     303# else
     304#  define TRACE_PUTC(c)         trace_char(psh, c)
     305# endif
     306
     307
     308# ifndef TRACE_VIA_STDIO
     309/* Flushes the tracebuf. */
     310static void
     311trace_flush(shinstance *psh)
     312{
     313        size_t pos = psh->tracepos;
     314
     315        if (pos > sizeof(psh->tracebuf)) {
     316                char *end;
     317                assert(0);
     318                end = memchr(psh->tracebuf, '\0', sizeof(psh->tracebuf));
     319                pos = end ? end - &psh->tracebuf[0] : 0;
     320        }
     321
     322        if (pos) {
     323                char    prefix[40];
     324                size_t  len;
     325
     326                len = sprintf(prefix, "[%d] ", sh_getpid(psh));
     327                shfile_write(&psh->fdtab, psh->tracefd, prefix, len);
     328                shfile_write(&psh->fdtab, psh->tracefd, psh->tracebuf, pos);
     329
     330                psh->tracepos = 0;
     331                psh->tracebuf[0] = '\0';
     332        }
     333}
     334
     335/* Adds a char to the trace buffer. */
     336static void
     337trace_char(shinstance *psh, int c)
     338{
     339        size_t pos = psh->tracepos;
     340        if (pos >= sizeof(psh->tracebuf) - 1) {
     341                trace_flush(psh);
     342                pos = psh->tracepos;
     343        }
     344        psh->tracebuf[pos] = c;
     345        psh->tracepos = pos + 1;
     346        if (c == '\n')
     347                trace_flush(psh);
     348        else
     349                psh->tracebuf[pos + 1] = '\0';
     350}
     351
     352/* Add a string to the trace buffer. */
     353static void
     354trace_string(shinstance *psh, const char *str)
     355{
     356        /* push it out line by line. */
     357        while (*str) {
     358                /* find line/string length. */
     359                size_t          pos;
     360                size_t          len;
     361                const char *end = str;
     362                int             flush_it = 0;
     363                while (*end) {
     364                        if (*end++ == '\n') {
     365                                flush_it = 1;
     366                                break;
     367                        }
     368                }
     369                len = end - str;
     370
     371                /* copy to the buffer */
     372                pos = psh->tracepos;
     373                if (pos + len <= sizeof(psh->tracebuf)) {
     374                        memcpy(&psh->tracebuf[pos], str, len);
     375                        psh->tracepos = pos + len;
     376                        if (flush_it)
     377                                trace_flush(psh);
     378                } else {
     379                        /* it's too big for some reason... */
     380                        trace_flush(psh);
     381                        shfile_write(&psh->fdtab, psh->tracefd, str, len);
     382                        if (!flush_it)
     383                                shfile_write(&psh->fdtab, psh->tracefd, "[too long]\n", sizeof( "[too long]\n") - 1);
     384                }
     385
     386                /* advance */
     387                str = end;
     388        }
     389}
     390# endif
     391
    273392void
    274393trputc(shinstance *psh, int c)
    275394{
    276         if (psh && debug(psh) != 1)
    277                 return;
    278         putc(c, tracefile);
     395        TRY_GET_PSH_OR_RETURN(psh);
     396        RETURN_IF_NOT_TRACING(psh);
     397
     398# ifdef TRACE_VIA_STDIO
     399    putc(c, tracefile);
     400# else
     401        trace_char(psh, c);
     402# endif
    279403}
    280404#endif
     
    286410        int savederrno = errno;
    287411        va_list va;
    288 
    289         if (!tracefile || (psh && debug(psh) != 1))
    290                 return;
     412# ifndef TRACE_VIA_STDIO
     413        char buf[2048];
     414# endif
     415
     416        TRY_GET_PSH_OR_RETURN(psh);
     417        RETURN_IF_NOT_TRACING(psh);
     418
     419# ifdef TRACE_VIA_STDIO
    291420        fprintf(tracefile, "[%d] ", sh_getpid(psh));
    292421        va_start(va, fmt);
    293422        (void) vfprintf(tracefile, fmt, va);
    294423        va_end(va);
     424# else
     425        va_start(va, fmt);
     426#  ifdef _MSC_VER
     427        _vsnprintf(buf, sizeof(buf), fmt, va);
     428#  else
     429        vsnprintf(buf, sizeof(buf), fmt, va);
     430#  endif
     431        va_end(va);
     432        trace_string(psh, buf);
     433# endif
    295434
    296435        errno = savederrno;
     
    303442#ifdef DEBUG
    304443        int savederrno = errno;
    305 
    306         if (!tracefile || (psh && debug(psh) != 1))
    307                 return;
     444# ifndef TRACE_VIA_STDIO
     445        char buf[2048];
     446# endif
     447
     448        TRY_GET_PSH_OR_RETURN(psh);
     449        RETURN_IF_NOT_TRACING(psh);
     450
     451# ifdef TRACE_VIA_STDIO
    308452        fprintf(tracefile, "[%d] ", sh_getpid(psh));
    309453        (void) vfprintf(tracefile, fmt, va);
     454# else
     455#  ifdef _MSC_VER
     456        _vsnprintf(buf, sizeof(buf), fmt, va);
     457#  else
     458        vsnprintf(buf, sizeof(buf), fmt, va);
     459#  endif
     460        trace_string(psh, buf);
     461# endif
    310462
    311463        errno = savederrno;
     
    320472        int savederrno = errno;
    321473
    322         if (!tracefile || (psh && debug(psh) != 1))
    323                 return;
     474        TRY_GET_PSH_OR_RETURN(psh);
     475        RETURN_IF_NOT_TRACING(psh);
     476
     477# ifdef TRACE_VIA_STDIO
    324478        fputs(s, tracefile);
     479# else
     480        trace_string(psh, s);
     481# endif
    325482
    326483        errno = savederrno;
     
    335492        char c;
    336493
    337         if (!tracefile || (psh && debug(psh) != 1))
    338                 return;
    339         putc('"', tracefile);
     494        TRY_GET_PSH_OR_RETURN(psh);
     495        RETURN_IF_NOT_TRACING(psh);
     496
     497        TRACE_PUTC('"');
    340498        for (p = s ; *p ; p++) {
    341499                switch (*p) {
     
    350508                case CTLBACKQ:  c = 'q';  goto backslash;
    351509                case CTLBACKQ+CTLQUOTE:  c = 'Q';  goto backslash;
    352 backslash:        putc('\\', tracefile);
    353                         putc(c, tracefile);
     510backslash:        TRACE_PUTC('\\');
     511                        TRACE_PUTC(c);
    354512                        break;
    355513                default:
    356514                        if (*p >= ' ' && *p <= '~')
    357                                 putc(*p, tracefile);
     515                                TRACE_PUTC(*p);
    358516                        else {
    359                                 putc('\\', tracefile);
    360                                 putc(*p >> 6 & 03, tracefile);
    361                                 putc(*p >> 3 & 07, tracefile);
    362                                 putc(*p & 07, tracefile);
     517                                TRACE_PUTC('\\');
     518                                TRACE_PUTC(*p >> 6 & 03);
     519                                TRACE_PUTC(*p >> 3 & 07);
     520                                TRACE_PUTC(*p & 07);
    363521                        }
    364522                        break;
    365523                }
    366524        }
    367         putc('"', tracefile);
     525        TRACE_PUTC('"');
    368526
    369527        errno = savederrno;
     
    378536        int savederrno = errno;
    379537
    380         if (!tracefile || (psh && debug(psh) != 1))
    381                 return;
     538        TRY_GET_PSH_OR_RETURN(psh);
     539        RETURN_IF_NOT_TRACING(psh);
     540
    382541        while (*ap) {
    383542                trstring(psh, *ap++);
    384543                if (*ap)
    385                         putc(' ', tracefile);
     544                        TRACE_PUTC(' ');
    386545                else
    387                         putc('\n', tracefile);
     546                        TRACE_PUTC('\n');
    388547        }
    389548
     
    398557{
    399558    static const char s[] = "./trace";
     559# ifdef TRACE_VIA_STDIO
    400560        int fd;
    401 
    402         if (psh && debug(psh) != 1) {
     561# endif
     562
     563        TRY_GET_PSH_OR_RETURN(psh);
     564        if (debug(psh) != 1) {
     565# ifdef TRACE_VIA_STDIO
    403566                if (tracefile)
    404567                        fflush(tracefile);
    405568                /* leave open because libedit might be using it */
     569# else
     570                if (psh->tracefd != -1) {
     571                        trace_flush(psh);
     572                        shfile_close(&psh->fdtab, psh->tracefd);
     573                        psh->tracefd = -1;
     574                }
     575# endif
    406576                return;
    407577        }
    408578
     579# ifdef TRACE_VIA_STDIO
    409580        if (tracefile) {
    410581                if (!freopen(s, "a", tracefile)) {
     
    416587                fd = open(s, O_APPEND | O_RDWR | O_CREAT, 0600);
    417588                if (fd != -1) {
    418 # if K_OS == K_OS_WINDOWS
     589#  if K_OS == K_OS_WINDOWS
    419590            int fds[50];
    420591            int i = 0;
     
    431602            while (i-- > 0)
    432603                close(fds[i]);
    433 # else
     604#  else
    434605            int fdTarget = 199;
    435606            while (fdTarget > 10)
    436607            {
    437608                int fd2 = shfile_fcntl(&psh->fdtab, fd, F_DUPFD, fdTarget);
    438                 if (fd2 != -1)
    439                     break;
     609                                if (fd2 != -1) {
     610                                        close(fd);
     611                                        fd = fd2;
     612                                        break;
     613                                }
    440614                fdTarget = (fdTarget + 1 / 2) - 1;
    441615            }
    442                         if (fd2 != -1) {
    443                                 close(fd);
    444                                 fd = fd2;
    445                         }
    446 # endif
     616#  endif
    447617                }
    448618                if (fd == -1 || (tracefile = fdopen(fd, "a")) == NULL) {
     
    454624        setvbuf(tracefile, (char *)NULL, _IOLBF, 1024);
    455625        fputs("\nTracing started.\n", tracefile);
     626
     627# else  /* !TRACE_VIA_STDIO */
     628        if (psh->tracefd != -1) {
     629                return;
     630        }
     631        psh->tracefd = shfile_open(&psh->fdtab, s, O_APPEND | O_RDWR | O_CREAT, 0600);
     632        if (psh->tracefd != -1) {
     633                /* relocate it */
     634                int fdTarget = 199;
     635                while (fdTarget > 10)
     636                {
     637                        int fd2 = shfile_fcntl(&psh->fdtab, psh->tracefd, F_DUPFD, fdTarget);
     638                        if (fd2 != -1) {
     639                                shfile_close(&psh->fdtab, psh->tracefd);
     640                                psh->tracefd = fd2;
     641                                break;
     642                        }
     643                        fdTarget = (fdTarget + 1 / 2) - 1;
     644                }
     645        }
     646        if (psh->tracefd == -1) {
     647                fprintf(stderr, "Can't open %s\n", s);
     648                debug(psh) = 0;
     649                return;
     650        }
     651        trace_string(psh, "Tracing started.\n");
     652
     653# endif /* !TRACE_VIA_STDIO */
    456654}
    457655#endif /* DEBUG */
Note: See TracChangeset for help on using the changeset viewer.

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