dt_subr.c

来自「Sun Solaris 10 中的 DTrace 组件的源代码。请参看: htt」· C语言 代码 · 共 729 行 · 第 1/2 页

C
729
字号
			return (-1);	}	if (n[0] > DT_VERSION_MAJMAX ||	    n[1] > DT_VERSION_MINMAX ||	    n[2] > DT_VERSION_MICMAX)		return (-1);	if (vp != NULL)		*vp = DT_VERSION_NUMBER(n[0], n[1], n[2]);	return (0);}intdt_version_defined(dt_version_t v){	int i;	for (i = 0; _dtrace_versions[i] != 0; i++) {		if (_dtrace_versions[i] == v)			return (1);	}	return (0);}char *dt_cpp_add_arg(dtrace_hdl_t *dtp, const char *str){	char *arg;	if (dtp->dt_cpp_argc == dtp->dt_cpp_args) {		int olds = dtp->dt_cpp_args;		int news = olds * 2;		char **argv = realloc(dtp->dt_cpp_argv, sizeof (char *) * news);		if (argv == NULL)			return (NULL);		bzero(&argv[olds], sizeof (char *) * olds);		dtp->dt_cpp_argv = argv;		dtp->dt_cpp_args = news;	}	if ((arg = strdup(str)) == NULL)		return (NULL);	assert(dtp->dt_cpp_argc < dtp->dt_cpp_args);	dtp->dt_cpp_argv[dtp->dt_cpp_argc++] = arg;	return (arg);}char *dt_cpp_pop_arg(dtrace_hdl_t *dtp){	char *arg;	if (dtp->dt_cpp_argc <= 1)		return (NULL); /* dt_cpp_argv[0] cannot be popped */	arg = dtp->dt_cpp_argv[--dtp->dt_cpp_argc];	dtp->dt_cpp_argv[dtp->dt_cpp_argc] = NULL;	return (arg);}/*PRINTFLIKE1*/voiddt_dprintf(const char *format, ...){	if (_dtrace_debug) {		va_list alist;		va_start(alist, format);		(void) fputs("libdtrace DEBUG: ", stderr);		(void) vfprintf(stderr, format, alist);		va_end(alist);	}}intdt_ioctl(dtrace_hdl_t *dtp, int val, void *arg){	const dtrace_vector_t *v = dtp->dt_vector;	if (v == NULL)		return (ioctl(dtp->dt_fd, val, arg));	return (v->dtv_ioctl(dtp->dt_varg, val, arg));}intdt_status(dtrace_hdl_t *dtp, processorid_t cpu){	const dtrace_vector_t *v = dtp->dt_vector;	if (v == NULL)		return (p_online(cpu, P_STATUS));	return (v->dtv_status(dtp->dt_varg, cpu));}longdt_sysconf(dtrace_hdl_t *dtp, int name){	const dtrace_vector_t *v = dtp->dt_vector;	if (v == NULL)		return (sysconf(name));	return (v->dtv_sysconf(dtp->dt_varg, name));}/* * Wrapper around write(2) to handle partial writes.  For maximum safety of * output files and proper error reporting, we continuing writing in the * face of partial writes until write(2) fails or 'buf' is completely written. * We also record any errno in the specified dtrace_hdl_t as well as 'errno'. */ssize_tdt_write(dtrace_hdl_t *dtp, int fd, const void *buf, size_t n){	ssize_t resid = n;	ssize_t len;	while (resid != 0) {		if ((len = write(fd, buf, resid)) <= 0)			break;		resid -= len;		buf = (char *)buf + len;	}	if (resid == n && n != 0)		return (dt_set_errno(dtp, errno));	return (n - resid);}/* * This function handles all output from libdtrace, as well as the * dtrace_sprintf() case.  If we're here due to dtrace_sprintf(), then * dt_sprintf_buflen will be non-zero; in this case, we sprintf into the * specified buffer and return.  Otherwise, if output is buffered (denoted by * a NULL fp), we sprintf the desired output into the buffered buffer * (expanding the buffer if required).  If we don't satisfy either of these * conditions (that is, if we are to actually generate output), then we call * fprintf with the specified fp.  In this case, we need to deal with one of * the more annoying peculiarities of libc's printf routines:  any failed * write persistently sets an error flag inside the FILE causing every * subsequent write to fail, but only the caller that initiated the error gets * the errno.  Since libdtrace clients often intercept SIGINT, this case is * particularly frustrating since we don't want the EINTR on one attempt to * write to the output file to preclude later attempts to write.  This * function therefore does a clearerr() if any error occurred, and saves the * errno for the caller inside the specified dtrace_hdl_t. *//*PRINTFLIKE3*/intdt_printf(dtrace_hdl_t *dtp, FILE *fp, const char *format, ...){	va_list ap;	int n;	va_start(ap, format);	if (dtp->dt_sprintf_buflen != 0) {		int len;		char *buf;		assert(dtp->dt_sprintf_buf != NULL);		buf = &dtp->dt_sprintf_buf[len = strlen(dtp->dt_sprintf_buf)];		len = dtp->dt_sprintf_buflen - len;		assert(len >= 0);		if ((n = vsnprintf(buf, len, format, ap)) < 0)			n = dt_set_errno(dtp, errno);		va_end(ap);		return (n);	}	if (fp == NULL) {		int needed, rval;		size_t avail;		/*		 * It's not legal to use buffered ouput if there is not a		 * handler for buffered output.		 */		if (dtp->dt_bufhdlr == NULL) {			va_end(ap);			return (dt_set_errno(dtp, EDT_NOBUFFERED));		}		if (dtp->dt_buffered_buf == NULL) {			assert(dtp->dt_buffered_size == 0);			dtp->dt_buffered_size = 1;			dtp->dt_buffered_buf = malloc(dtp->dt_buffered_size);			if (dtp->dt_buffered_buf == NULL) {				va_end(ap);				return (dt_set_errno(dtp, EDT_NOMEM));			}			dtp->dt_buffered_offs = 0;			dtp->dt_buffered_buf[0] = '\0';		}		if ((needed = vsnprintf(NULL, 0, format, ap)) < 0) {			rval = dt_set_errno(dtp, errno);			va_end(ap);			return (rval);		}		if (needed == 0) {			va_end(ap);			return (0);		}		for (;;) {			char *newbuf;			assert(dtp->dt_buffered_offs < dtp->dt_buffered_size);			avail = dtp->dt_buffered_size - dtp->dt_buffered_offs;			if (needed + 1 < avail)				break;			if ((newbuf = realloc(dtp->dt_buffered_buf,			    dtp->dt_buffered_size << 1)) == NULL) {				va_end(ap);				return (dt_set_errno(dtp, EDT_NOMEM));			}			dtp->dt_buffered_buf = newbuf;			dtp->dt_buffered_size <<= 1;		}		if (vsnprintf(&dtp->dt_buffered_buf[dtp->dt_buffered_offs],		    avail, format, ap) < 0) {			rval = dt_set_errno(dtp, errno);			va_end(ap);			return (rval);		}		dtp->dt_buffered_offs += needed;		assert(dtp->dt_buffered_buf[dtp->dt_buffered_offs] == '\0');		return (0);	}	n = vfprintf(fp, format, ap);	va_end(ap);	if (n < 0) {		clearerr(fp);		return (dt_set_errno(dtp, errno));	}	return (n);}intdt_buffered_flush(dtrace_hdl_t *dtp, dtrace_probedata_t *pdata,    dtrace_recdesc_t *rec, dtrace_aggdata_t *agg){	dtrace_bufdata_t data;	if (dtp->dt_buffered_offs == 0)		return (0);	data.dtbda_handle = dtp;	data.dtbda_buffered = dtp->dt_buffered_buf;	data.dtbda_probe = pdata;	data.dtbda_recdesc = rec;	data.dtbda_aggdata = agg;	if ((*dtp->dt_bufhdlr)(&data, dtp->dt_bufarg) == DTRACE_HANDLE_ABORT)		return (dt_set_errno(dtp, EDT_DIRABORT));	dtp->dt_buffered_offs = 0;	dtp->dt_buffered_buf[0] = '\0';	return (0);}voiddt_buffered_destroy(dtrace_hdl_t *dtp){	free(dtp->dt_buffered_buf);	dtp->dt_buffered_buf = NULL;	dtp->dt_buffered_offs = 0;	dtp->dt_buffered_size = 0;}void *dt_zalloc(dtrace_hdl_t *dtp, size_t size){	void *data;	if ((data = malloc(size)) == NULL)		(void) dt_set_errno(dtp, EDT_NOMEM);	else		bzero(data, size);	return (data);}void *dt_alloc(dtrace_hdl_t *dtp, size_t size){	void *data;	if ((data = malloc(size)) == NULL)		(void) dt_set_errno(dtp, EDT_NOMEM);	return (data);}/*ARGSUSED*/voiddt_free(dtrace_hdl_t *dtp, void *data){	free(data);}char *dt_basename(char *str){	char *last = strrchr(str, '/');	if (last == NULL)		return (str);	return (last + 1);}struct _rwlock;struct _lwp_mutex;intdt_rw_read_held(pthread_rwlock_t *lock){	extern int _rw_read_held(struct _rwlock *);	return (_rw_read_held((struct _rwlock *)lock));}intdt_rw_write_held(pthread_rwlock_t *lock){	extern int _rw_write_held(struct _rwlock *);	return (_rw_write_held((struct _rwlock *)lock));}intdt_mutex_held(pthread_mutex_t *lock){	extern int _mutex_held(struct _lwp_mutex *);	return (_mutex_held((struct _lwp_mutex *)lock));}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?