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 + -
显示快捷键?