]> granicus.if.org Git - strace/commitdiff
Optimization: eliminate all remaining usages of strcat()
authorDenys Vlasenko <dvlasenk@redhat.com>
Wed, 31 Aug 2011 10:26:03 +0000 (12:26 +0200)
committerDenys Vlasenko <dvlasenk@redhat.com>
Wed, 31 Aug 2011 10:26:03 +0000 (12:26 +0200)
After this change, we don't use strcat() anywhere.

* defs.h: Change sprinttv() return type to char *.
* time.c (sprinttv): Return pointer past last stored char.
* desc.c (decode_select): Change printing logic in order to eliminate
usage of strcat() - use stpcpy(), *outptr++ = ch, sprintf() instead.
Also reduce usage of strlen().
* stream.c (decode_poll): Likewise.

Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
defs.h
desc.c
stream.c
time.c

diff --git a/defs.h b/defs.h
index 0b6525798c24c210eae2d2d17ce71d896c0e4dab..dfca2c12ed90a275626f93e5a22df8385000f804 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -616,7 +616,7 @@ extern void printnum_int(struct tcb *, long, const char *);
 extern void printpath(struct tcb *, long);
 extern void printpathn(struct tcb *, long, int);
 extern void printtv_bitness(struct tcb *, long, enum bitness_t, int);
-extern void sprinttv(struct tcb *, long, enum bitness_t, char *);
+extern char *sprinttv(struct tcb *, long, enum bitness_t, char *);
 extern void print_timespec(struct tcb *, long);
 extern void sprint_timespec(char *, struct tcb *, long);
 #ifdef HAVE_SIGINFO_T
diff --git a/desc.c b/desc.c
index 4276a8148c0597324484e72259a13f4b21ffe2a4..a8dbe9551c0df6cf2ab7c92a3d75e08e8dc58d9f 100644 (file)
--- a/desc.c
+++ b/desc.c
@@ -493,7 +493,6 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
        unsigned int fdsize = ((((args[0] + 7) / 8) + sizeof(long) - 1)
                               & -sizeof(long));
        fd_set *fds;
-       static char outstr[1024];
        const char *sep;
        long arg;
 
@@ -532,8 +531,10 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
                printtv_bitness(tcp, args[4], bitness, 0);
        }
        else {
-               unsigned int cumlen = 0;
-               const char *sep = "";
+               static char outstr[1024];
+               char *outptr;
+#define end_outstr (outstr + sizeof(outstr))
+               const char *sep;
 
                if (syserror(tcp))
                        return 0;
@@ -544,41 +545,42 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
                        return RVAL_STR;
                }
 
-               fds = (fd_set *) malloc(fdsize);
+               fds = malloc(fdsize);
                if (fds == NULL)
                        fprintf(stderr, "out of memory\n");
 
-               outstr[0] = '\0';
+               tcp->auxstr = outstr;
+               outptr = outstr;
+               sep = "";
                for (i = 0; i < 3; i++) {
                        int first = 1;
 
-                       tcp->auxstr = outstr;
                        arg = args[i+1];
                        if (fds == NULL || !arg ||
                            umoven(tcp, arg, fdsize, (char *) fds) < 0)
                                continue;
                        for (j = 0; j < args[0]; j++) {
                                if (FD_ISSET(j, fds)) {
-                                       char str[11 + 3 * sizeof(int)];
-
-                                       if (first) {
-                                               sprintf(str, "%s%s [%u", sep,
-                                                       i == 0 ? "in" :
-                                                       i == 1 ? "out" :
-                                                       "except", j);
-                                               first = 0;
-                                               sep = ", ";
+                                       /* +2 chars needed at the end: ']',NUL */
+                                       if (outptr < end_outstr - (sizeof(", except [") + sizeof(int)*3 + 2)) {
+                                               if (first) {
+                                                       outptr += sprintf(outptr, "%s%s [%u",
+                                                               sep,
+                                                               i == 0 ? "in" : i == 1 ? "out" : "except",
+                                                               j
+                                                       );
+                                                       first = 0;
+                                                       sep = ", ";
+                                               }
+                                               else {
+                                                       outptr += sprintf(outptr, " %u", j);
+                                               }
                                        }
-                                       else
-                                               sprintf(str, " %u", j);
-                                       cumlen += strlen(str);
-                                       if (cumlen < sizeof(outstr))
-                                               strcat(outstr, str);
                                        nfds--;
                                }
                        }
-                       if (cumlen)
-                               strcat(outstr, "]");
+                       if (outptr != outstr)
+                               *outptr++ = ']';
                        if (nfds == 0)
                                break;
                }
@@ -586,15 +588,15 @@ decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
 #ifdef LINUX
                /* This contains no useful information on SunOS.  */
                if (args[4]) {
-                       char str[128];
-
-                       sprintf(str, "%sleft ", sep);
-                       sprinttv(tcp, args[4], bitness, str + strlen(str));
-                       if ((cumlen += strlen(str)) < sizeof(outstr))
-                               strcat(outstr, str);
+                       if (outptr < end_outstr - 128) {
+                               outptr += sprintf(outptr, "%sleft ", sep);
+                               outptr = sprinttv(tcp, args[4], bitness, outptr);
+                       }
                }
 #endif /* LINUX */
+               *outptr = '\0';
                return RVAL_STR;
+#undef end_outstr
        }
        return 0;
 }
index d55beb5e9d7942635ea2c1303fa11f0f76500a6d..165e1165ecfb1d2724966bf20b180e31b61972ee 100644 (file)
--- a/stream.c
+++ b/stream.c
@@ -341,9 +341,9 @@ decode_poll(struct tcb *tcp, long pts)
                return 0;
        } else {
                static char outstr[1024];
-               char str[64];
+               char *outptr;
+#define end_outstr (outstr + sizeof(outstr))
                const char *flagstr;
-               unsigned int cumlen;
 
                if (syserror(tcp))
                        return 0;
@@ -366,62 +366,56 @@ decode_poll(struct tcb *tcp, long pts)
                        abbrev_end = end;
                }
 
-               outstr[0] = '\0';
-               cumlen = 0;
+               outptr = outstr;
 
                for (cur = start; cur < end; cur += sizeof(fds)) {
                        if (umoven(tcp, cur, sizeof fds, (char *) &fds) < 0) {
-                               ++cumlen;
-                               if (cumlen < sizeof(outstr))
-                                       strcat(outstr, "?");
+                               if (outptr < end_outstr - 2)
+                                       *outptr++ = '?';
                                failed = 1;
                                break;
                        }
                        if (!fds.revents)
                                continue;
-                       if (!cumlen) {
-                               ++cumlen;
-                               strcat(outstr, "[");
+                       if (outptr == outstr) {
+                               *outptr++ = '[';
                        } else {
-                               cumlen += 2;
-                               if (cumlen < sizeof(outstr))
-                                       strcat(outstr, ", ");
+                               if (outptr < end_outstr - 3)
+                                       outptr = stpcpy(outptr, ", ");
                        }
                        if (cur >= abbrev_end) {
-                               cumlen += 3;
-                               if (cumlen < sizeof(outstr))
-                                       strcat(outstr, "...");
+                               if (outptr < end_outstr - 4)
+                                       outptr = stpcpy(outptr, "...");
                                break;
                        }
-                       sprintf(str, "{fd=%d, revents=", fds.fd);
+                       if (outptr < end_outstr - (sizeof("{fd=%d, revents=") + sizeof(int)*3) + 1)
+                               outptr += sprintf(outptr, "{fd=%d, revents=", fds.fd);
                        flagstr = sprintflags("", pollflags, fds.revents);
-                       cumlen += strlen(str) + strlen(flagstr) + 1;
-                       if (cumlen < sizeof(outstr)) {
-                               strcat(outstr, str);
-                               strcat(outstr, flagstr);
-                               strcat(outstr, "}");
+                       if (outptr < end_outstr - (strlen(flagstr) + 2)) {
+                               outptr = stpcpy(outptr, flagstr);
+                               *outptr++ = '}';
                        }
                }
                if (failed)
                        return 0;
 
-               if (cumlen && ++cumlen < sizeof(outstr))
-                       strcat(outstr, "]");
+               if (outptr != outstr /* && outptr < end_outstr - 1 (always true)*/)
+                       *outptr++ = ']';
 
+               *outptr = '\0';
                if (pts) {
-                       char str[128];
-
-                       sprintf(str, "%sleft ", cumlen ? ", " : "");
-                       sprint_timespec(str + strlen(str), tcp, pts);
-                       if ((cumlen += strlen(str)) < sizeof(outstr))
-                               strcat(outstr, str);
+                       if (outptr < end_outstr - 128) {
+                               outptr = stpcpy(outptr, outptr == outstr ? "left " : ", left ");
+                               sprint_timespec(outptr, tcp, pts);
+                       }
                }
 
-               if (!outstr[0])
+               if (outptr == outstr)
                        return 0;
 
                tcp->auxstr = outstr;
                return RVAL_STR;
+#undef end_outstr
        }
 }
 
diff --git a/time.c b/time.c
index a4599f708f02c5df0bae0e96d5263c58f9a54edb..89a6216060d59c77f55e6856b32e460461cc090c 100644 (file)
--- a/time.c
+++ b/time.c
@@ -112,40 +112,44 @@ printtv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness, int special)
        }
 }
 
-void
+char *
 sprinttv(struct tcb *tcp, long addr, enum bitness_t bitness, char *buf)
 {
+       int rc;
+
        if (addr == 0)
-               strcpy(buf, "NULL");
-       else if (!verbose(tcp))
-               sprintf(buf, "%#lx", addr);
-       else {
-               int rc;
+               return stpcpy(buf, "NULL");
 
-               if (bitness == BITNESS_32
+       if (!verbose(tcp)) {
+               buf += sprintf(buf, "%#lx", addr);
+               return buf;
+       }
+
+       if (bitness == BITNESS_32
 #if defined(LINUX) && SUPPORTED_PERSONALITIES > 1
-                   || personality_wordsize[current_personality] == 4
+           || personality_wordsize[current_personality] == 4
 #endif
-                       )
-               {
-                       struct timeval32 tv;
-
-                       rc = umove(tcp, addr, &tv);
-                       if (rc >= 0)
-                               sprintf(buf, "{%u, %u}",
-                                       tv.tv_sec, tv.tv_usec);
-               } else {
-                       struct timeval tv;
+               )
+       {
+               struct timeval32 tv;
+
+               rc = umove(tcp, addr, &tv);
+               if (rc >= 0)
+                       buf += sprintf(buf, "{%u, %u}",
+                               tv.tv_sec, tv.tv_usec);
+       } else {
+               struct timeval tv;
 
-                       rc = umove(tcp, addr, &tv);
-                       if (rc >= 0)
-                               sprintf(buf, "{%lu, %lu}",
-                                       (unsigned long) tv.tv_sec,
-                                       (unsigned long) tv.tv_usec);
-               }
-               if (rc < 0)
-                       strcpy(buf, "{...}");
+               rc = umove(tcp, addr, &tv);
+               if (rc >= 0)
+                       buf += sprintf(buf, "{%lu, %lu}",
+                               (unsigned long) tv.tv_sec,
+                               (unsigned long) tv.tv_usec);
        }
+       if (rc < 0)
+               buf = stpcpy(buf, "{...}");
+
+       return buf;
 }
 
 void print_timespec(struct tcb *tcp, long addr)