More select decoding fixes

* desc.c (decode_select): Actually print arg[0] as int on entering
syscall.  When arg[0] is negative, do not attempt to fetch and decode
descriptor sets on entering syscall, kernel will reject it anyway.
On exiting syscall, stop checking descriptor sets as soon as all
returned descriptors are found.
diff --git a/desc.c b/desc.c
index bbdc087..3547d96 100644
--- a/desc.c
+++ b/desc.c
@@ -486,31 +486,39 @@
 	const char *sep;
 	long arg;
 
-	/* Kernel truncates arg[0] to int, we do the same */
-	fdsize = (int)args[0];
+	/* Kernel truncates arg[0] to int, we do the same. */
+	nfds = (int) args[0];
+
+	/* Kernel rejects negative nfds, so we don't parse it either. */
+	if (nfds < 0) {
+		nfds = 0;
+		fds = NULL;
+	}
 	/* Beware of select(2^31-1, NULL, NULL, NULL) and similar... */
-	if (fdsize > 1024*1024)
-		fdsize = 1024*1024;
-	if (fdsize < 0)
-		fdsize = 0;
-	nfds = fdsize;
-	fdsize = (((fdsize + 7) / 8) + sizeof(long)-1) & -sizeof(long);
-	/* We had bugs a-la "while (j < args[0])" and "umoven(args[0])" below.
+	if (nfds > 1024*1024)
+		nfds = 1024*1024;
+
+	/*
+	 * We had bugs a-la "while (j < args[0])" and "umoven(args[0])" below.
 	 * Instead of args[0], use nfds for fd count, fdsize for array lengths.
 	 */
+	fdsize = (((nfds + 7) / 8) + sizeof(long)-1) & -sizeof(long);
 
 	if (entering(tcp)) {
-		fds = malloc(fdsize);
-		if (!fds)
-			die_out_of_memory();
-		tprintf("%ld", args[0]);
+		tprintf("%d", (int) args[0]);
+
+		if (fdsize > 0) {
+			fds = malloc(fdsize);
+			if (!fds)
+				die_out_of_memory();
+		}
 		for (i = 0; i < 3; i++) {
 			arg = args[i+1];
 			if (arg == 0) {
 				tprints(", NULL");
 				continue;
 			}
-			if (!verbose(tcp)) {
+			if (!verbose(tcp) || !fds) {
 				tprintf(", %#lx", arg);
 				continue;
 			}
@@ -536,8 +544,7 @@
 		static char outstr[1024];
 		char *outptr;
 #define end_outstr (outstr + sizeof(outstr))
-		const char *sep;
-		long ready_fds;
+		int ready_fds;
 
 		if (syserror(tcp))
 			return 0;
@@ -554,7 +561,7 @@
 
 		outptr = outstr;
 		sep = "";
-		for (i = 0; i < 3; i++) {
+		for (i = 0; i < 3 && ready_fds > 0; i++) {
 			int first = 1;
 
 			arg = args[i+1];
@@ -577,13 +584,12 @@
 							outptr += sprintf(outptr, " %u", j);
 						}
 					}
-					ready_fds--;
+					if (--ready_fds == 0)
+						break;
 				}
 			}
 			if (outptr != outstr)
 				*outptr++ = ']';
-			if (ready_fds == 0)
-				break;
 		}
 		free(fds);
 		/* This contains no useful information on SunOS.  */