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>
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
unsigned int fdsize = ((((args[0] + 7) / 8) + sizeof(long) - 1)
& -sizeof(long));
fd_set *fds;
- static char outstr[1024];
const char *sep;
long arg;
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;
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;
}
#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;
}
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;
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
}
}
}
}
-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)