1e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* 2e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Copyright (C) 2009 Red Hat Inc, Steven Rostedt <srostedt@redhat.com> 3e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 4e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 5e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This program is free software; you can redistribute it and/or 6e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * modify it under the terms of the GNU Lesser General Public 7e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * License as published by the Free Software Foundation; 8e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * version 2.1 of the License (not later!) 9e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 10e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * This program is distributed in the hope that it will be useful, 11e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * but WITHOUT ANY WARRANTY; without even the implied warranty of 12e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * GNU Lesser General Public License for more details. 14e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 15e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * You should have received a copy of the GNU Lesser General Public 16e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * License along with this program; if not, see <http://www.gnu.org/licenses> 17e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 18e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 19e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 20e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdio.h> 21e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdlib.h> 22e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <string.h> 23e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include <stdarg.h> 24e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 25e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "event-parse.h" 26e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#include "event-utils.h" 27e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 28e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/* 29e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * The TRACE_SEQ_POISON is to catch the use of using 30e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * a trace_seq structure after it was destroyed. 31e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 32e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define TRACE_SEQ_POISON ((void *)0xdeadbeef) 33e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng#define TRACE_SEQ_CHECK(s) \ 34e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengdo { \ 35e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if ((s)->buffer == TRACE_SEQ_POISON) \ 36e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng die("Usage of trace_seq after it was destroyed"); \ 37e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} while (0) 38e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 39e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/** 40e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * trace_seq_init - initialize the trace_seq structure 41e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: a pointer to the trace_seq structure to initialize 42e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 43e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid trace_seq_init(struct trace_seq *s) 44e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 45e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->len = 0; 46e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->readpos = 0; 47e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->buffer_size = TRACE_SEQ_BUF_SIZE; 48e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->buffer = malloc_or_die(s->buffer_size); 49e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 50e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 51e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/** 52e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * trace_seq_reset - re-initialize the trace_seq structure 53e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: a pointer to the trace_seq structure to reset 54e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 55e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid trace_seq_reset(struct trace_seq *s) 56e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 57e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!s) 58e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return; 59e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng TRACE_SEQ_CHECK(s); 60e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->len = 0; 61e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->readpos = 0; 62e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 63e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 64e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/** 65e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * trace_seq_destroy - free up memory of a trace_seq 66e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: a pointer to the trace_seq to free the buffer 67e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 68e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * Only frees the buffer, not the trace_seq struct itself. 69e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 70e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid trace_seq_destroy(struct trace_seq *s) 71e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 72e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!s) 73e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return; 74e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng TRACE_SEQ_CHECK(s); 75e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng free(s->buffer); 76e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->buffer = TRACE_SEQ_POISON; 77e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 78e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 79e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengstatic void expand_buffer(struct trace_seq *s) 80e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 81e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->buffer_size += TRACE_SEQ_BUF_SIZE; 82e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->buffer = realloc(s->buffer, s->buffer_size); 83e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (!s->buffer) 84e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng die("Can't allocate trace_seq buffer memory"); 85e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 86e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 87e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/** 88e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * trace_seq_printf - sequence printing of trace information 89e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: trace sequence descriptor 90e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @fmt: printf format string 91e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 92e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * It returns 0 if the trace oversizes the buffer's free 93e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * space, 1 otherwise. 94e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 95e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * The tracer may use either sequence operations or its own 96e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * copy to user routines. To simplify formating of a trace 97e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * trace_seq_printf is used to store strings into a special 98e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * buffer (@s). Then the output may be either used by 99e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * the sequencer or pulled into another buffer. 100e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 101e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint 102e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtrace_seq_printf(struct trace_seq *s, const char *fmt, ...) 103e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 104e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng va_list ap; 105e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int len; 106e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int ret; 107e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 108e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng TRACE_SEQ_CHECK(s); 109e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 110e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng try_again: 111e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng len = (s->buffer_size - 1) - s->len; 112e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 113e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng va_start(ap, fmt); 114e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ret = vsnprintf(s->buffer + s->len, len, fmt, ap); 115e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng va_end(ap); 116e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 117e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ret >= len) { 118e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng expand_buffer(s); 119e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto try_again; 120e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 121e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 122e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->len += ret; 123e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 124e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 1; 125e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 126e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 127e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/** 128e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * trace_seq_vprintf - sequence printing of trace information 129e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: trace sequence descriptor 130e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @fmt: printf format string 131e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 132e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * The tracer may use either sequence operations or its own 133e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * copy to user routines. To simplify formating of a trace 134e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * trace_seq_printf is used to store strings into a special 135e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * buffer (@s). Then the output may be either used by 136e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * the sequencer or pulled into another buffer. 137e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 138e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint 139e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengtrace_seq_vprintf(struct trace_seq *s, const char *fmt, va_list args) 140e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 141e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int len; 142e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int ret; 143e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 144e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng TRACE_SEQ_CHECK(s); 145e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 146e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng try_again: 147e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng len = (s->buffer_size - 1) - s->len; 148e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 149e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng ret = vsnprintf(s->buffer + s->len, len, fmt, args); 150e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 151e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng if (ret >= len) { 152e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng expand_buffer(s); 153e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng goto try_again; 154e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng } 155e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 156e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->len += ret; 157e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 158e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return len; 159e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 160e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 161e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng/** 162e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * trace_seq_puts - trace sequence printing of simple string 163e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @s: trace sequence descriptor 164e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * @str: simple string to record 165e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * 166e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * The tracer may use either the sequence operations or its own 167e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * copy to user routines. This function records a simple string 168e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * into a special buffer (@s) for later retrieval by a sequencer 169e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng * or other mechanism. 170e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng */ 171e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint trace_seq_puts(struct trace_seq *s, const char *str) 172e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 173e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng int len; 174e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 175e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng TRACE_SEQ_CHECK(s); 176e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 177e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng len = strlen(str); 178e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 179e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (len > ((s->buffer_size - 1) - s->len)) 180e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng expand_buffer(s); 181e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 182e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng memcpy(s->buffer + s->len, str, len); 183e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->len += len; 184e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 185e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return len; 186e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 187e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 188e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint trace_seq_putc(struct trace_seq *s, unsigned char c) 189e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 190e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng TRACE_SEQ_CHECK(s); 191e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 192e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng while (s->len >= (s->buffer_size - 1)) 193e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng expand_buffer(s); 194e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 195e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->buffer[s->len++] = c; 196e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 197e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return 1; 198e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 199e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 200e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengvoid trace_seq_terminate(struct trace_seq *s) 201e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 202e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng TRACE_SEQ_CHECK(s); 203e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 204e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng /* There's always one character left on the buffer */ 205e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng s->buffer[s->len] = 0; 206e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 207e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng 208e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Chengint trace_seq_do_printf(struct trace_seq *s) 209e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng{ 210e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng TRACE_SEQ_CHECK(s); 211e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng return printf("%.*s", s->len, s->buffer); 212e6e8a0bd7cffcc9ae2e0e75546fb12a19213d4aeBen Cheng} 213