Optimization: eliminate all remaining usages of strcat()

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>
diff --git a/time.c b/time.c
index a4599f7..89a6216 100644
--- a/time.c
+++ b/time.c
@@ -112,40 +112,44 @@
 	}
 }
 
-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 defined(LINUX) && SUPPORTED_PERSONALITIES > 1
-		    || 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;
-
-			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, "{...}");
+	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
+#endif
+		)
+	{
+		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)
+			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)