예제 #1
0
void
printtv_bitness(struct tcb *tcp, long addr, enum bitness_t bitness, int special)
{
	char buf[TIMEVAL_TEXT_BUFSIZE];
	sprinttv(buf, tcp, addr, bitness, special);
	tprints(buf);
}
예제 #2
0
static int
decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
{
	int i, j, nfds;
	unsigned int fdsize = ((((args[0] + 7) / 8) + sizeof(long) - 1)
			       & -sizeof(long));
	fd_set *fds;
	static char outstr[1024];
	char *sep;
	long arg;

	if (entering(tcp)) {
		fds = (fd_set *) malloc(fdsize);
		if (fds == NULL)
			fprintf(stderr, "out of memory\n");
		nfds = args[0];
		tprintf("%d", nfds);
		for (i = 0; i < 3; i++) {
			arg = args[i+1];
			if (arg == 0) {
				tprintf(", NULL");
				continue;
			}
			if (fds == NULL || !verbose(tcp)) {
				tprintf(", %#lx", arg);
				continue;
			}
			if (umoven(tcp, arg, fdsize, (char *) fds) < 0) {
				tprintf(", [?]");
				continue;
			}
			tprintf(", [");
			for (j = 0, sep = ""; j < nfds; j++) {
				if (FD_ISSET(j, fds)) {
					tprintf("%s%u", sep, j);
					sep = " ";
				}
			}
			tprintf("]");
		}
		free(fds);
		tprintf(", ");
		printtv_bitness(tcp, args[4], bitness, 0);
	}
	else
	{
		unsigned int cumlen = 0;
		char *sep = "";

		if (syserror(tcp))
			return 0;

		if ((nfds = tcp->u_rval) == 0) {
			tcp->auxstr = "Timeout";
			return RVAL_STR;
		}

		fds = (fd_set *) malloc(fdsize);
		if (fds == NULL)
			fprintf(stderr, "out of memory\n");

		outstr[0] = '\0';
		for (i = 0; i < 3; i++) {
			int first = 1;
			char str[20];

			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)) {
					if (first) {
						sprintf(str, "%s%s [%u", sep,
							i == 0 ? "in" :
							i == 1 ? "out" :
							"except", j);
						first = 0;
						sep = ", ";
					}
					else
						sprintf(str, " %u", j);
					cumlen += strlen(str);
					if (cumlen < sizeof(outstr))
						strcat(outstr, str);
					nfds--;
				}
			}
			if (cumlen)
				strcat(outstr, "]");
			if (nfds == 0)
				break;
		}
		free(fds);
#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);
		}
#endif /* LINUX */
		return RVAL_STR;
	}
	return 0;
}
예제 #3
0
파일: desc.c 프로젝트: bigzz/strace_android
static int
decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
{
	int i, j;
	int nfds, fdsize;
	fd_set *fds = NULL;
	const char *sep;
	long arg;

	/* 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;

	/* Beware of select(2^31-1, NULL, NULL, NULL) and similar... */
	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) + current_wordsize-1) & -current_wordsize;

	if (entering(tcp)) {
		tprintf("%d", (int) args[0]);

		if (verbose(tcp) && 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 (!fds) {
				tprintf(", %#lx", arg);
				continue;
			}
			if (umoven(tcp, arg, fdsize, fds) < 0) {
				tprints(", [?]");
				continue;
			}
			tprints(", [");
			for (j = 0, sep = "";; j++) {
				j = next_set_bit(fds, j, nfds);
				if (j < 0)
					break;
				tprints(sep);
				printfd(tcp, j);
				sep = " ";
			}
			tprints("]");
		}
		free(fds);
		tprints(", ");
		printtv_bitness(tcp, args[4], bitness, 0);
	}
	else {
		static char outstr[1024];
		char *outptr;
#define end_outstr (outstr + sizeof(outstr))
		int ready_fds;

		if (syserror(tcp))
			return 0;

		ready_fds = tcp->u_rval;
		if (ready_fds == 0) {
			tcp->auxstr = "Timeout";
			return RVAL_STR;
		}

		fds = malloc(fdsize);
		if (!fds)
			die_out_of_memory();

		outptr = outstr;
		sep = "";
		for (i = 0; i < 3 && ready_fds > 0; i++) {
			int first = 1;

			arg = args[i+1];
			if (!arg || umoven(tcp, arg, fdsize, fds) < 0)
				continue;
			for (j = 0;; j++) {
				j = next_set_bit(fds, j, nfds);
				if (j < 0)
					break;
				/* +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);
					}
				}
				if (--ready_fds == 0)
					break;
			}
			if (outptr != outstr)
				*outptr++ = ']';
		}
		free(fds);
		/* This contains no useful information on SunOS.  */
		if (args[4]) {
			if (outptr < end_outstr - (10 + TIMEVAL_TEXT_BUFSIZE)) {
				outptr += sprintf(outptr, "%sleft ", sep);
				outptr = sprinttv(outptr, tcp, args[4], bitness, /*special:*/ 0);
			}
		}
		*outptr = '\0';
		tcp->auxstr = outstr;
		return RVAL_STR;
#undef end_outstr
	}
	return 0;
}
예제 #4
0
static int
decode_select(struct tcb *tcp, long *args, enum bitness_t bitness)
{
	int i, j;
	unsigned nfds, fdsize;
	fd_set *fds;
	const char *sep;
	long arg;

	fdsize = args[0];
	/* Beware of select(2^31-1, NULL, NULL, NULL) and similar... */
	if (args[0] > 1024*1024)
		fdsize = 1024*1024;
	if (args[0] < 0)
		fdsize = 0;
	fdsize = (((fdsize + 7) / 8) + sizeof(long)-1) & -sizeof(long);

	if (entering(tcp)) {
		fds = malloc(fdsize);
		if (!fds)
			die_out_of_memory();
		nfds = args[0];
		tprintf("%d", nfds);
		for (i = 0; i < 3; i++) {
			arg = args[i+1];
			if (arg == 0) {
				tprints(", NULL");
				continue;
			}
			if (!verbose(tcp)) {
				tprintf(", %#lx", arg);
				continue;
			}
			if (umoven(tcp, arg, fdsize, (char *) fds) < 0) {
				tprints(", [?]");
				continue;
			}
			tprints(", [");
			for (j = 0, sep = ""; j < nfds; j++) {
				if (FD_ISSET(j, fds)) {
					tprints(sep);
					printfd(tcp, j);
					sep = " ";
				}
			}
			tprints("]");
		}
		free(fds);
		tprints(", ");
		printtv_bitness(tcp, args[4], bitness, 0);
	}
	else {
		static char outstr[1024];
		char *outptr;
#define end_outstr (outstr + sizeof(outstr))
		const char *sep;

		if (syserror(tcp))
			return 0;

		nfds = tcp->u_rval;
		if (nfds == 0) {
			tcp->auxstr = "Timeout";
			return RVAL_STR;
		}

		fds = malloc(fdsize);
		if (!fds)
			die_out_of_memory();

		outptr = outstr;
		sep = "";
		for (i = 0; i < 3; i++) {
			int first = 1;

			arg = args[i+1];
			if (!arg || umoven(tcp, arg, fdsize, (char *) fds) < 0)
				continue;
			for (j = 0; j < args[0]; j++) {
				if (FD_ISSET(j, fds)) {
					/* +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);
						}
					}
					nfds--;
				}
			}
			if (outptr != outstr)
				*outptr++ = ']';
			if (nfds == 0)
				break;
		}
		free(fds);
		/* This contains no useful information on SunOS.  */
		if (args[4]) {
			if (outptr < end_outstr - (10 + TIMEVAL_TEXT_BUFSIZE)) {
				outptr += sprintf(outptr, "%sleft ", sep);
				outptr = sprinttv(outptr, tcp, args[4], bitness, /*special:*/ 0);
			}
		}
		*outptr = '\0';
		tcp->auxstr = outstr;
		return RVAL_STR;
#undef end_outstr
	}
	return 0;
}