source: trunk/packages/xen-common/xen-common/tools/vnet/libxutil/kernel_stream.c @ 34

Last change on this file since 34 was 34, checked in by hartmans, 17 years ago

Add xen and xen-common

File size: 4.5 KB
Line 
1/*
2 * Copyright (C) 2001 - 2004 Mike Wray <mike.wray@hp.com>
3 *
4 * This library is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; either version 2.1 of the License, or
7 * (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12 * GNU Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public License
15 * along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17 */
18
19/** @file
20 * An IOStream implementation using printk() for output.
21 * Input is not implemented.
22 */
23#ifdef __KERNEL__
24
25#include <linux/config.h>
26#include <linux/module.h>
27#include <linux/kernel.h>
28#include <linux/types.h>
29#include <linux/errno.h>
30#include <linux/slab.h>
31#include <linux/spinlock.h>
32
33#include "kernel_stream.h"
34#include "allocate.h"
35
36/** Number of characters in the output buffer.
37 * The kernel uses 1024 for printk, so that should suffice.
38 */
39#define BUF_N 1024
40
41/** State for a kernel stream. */
42typedef struct KernelData {
43    /** Stream lock. We need a lock to serialize access to the stream. */
44    spinlock_t lock;
45    /** Saved flags for locking. */
46    unsigned long flags;
47    /** Size of the output buffer. */
48    int buf_n;
49    /** Output buffer. */
50    char buf[BUF_N];
51} KernelData;
52
53static int kernel_write(IOStream *s, const void *msg, size_t n);
54static void kernel_free(IOStream *s);
55static void kernel_stream_lock(IOStream *s);
56static void kernel_stream_unlock(IOStream *s);
57
58/** Methods for a kernel stream. Output only. */
59static const IOMethods kernel_methods = {
60    write:  kernel_write,
61    free:   kernel_free,
62    lock:   kernel_stream_lock,
63    unlock: kernel_stream_unlock,
64};
65
66/** Shared state for kernel streams.
67 * All implementations write using printk, so we can use
68 * shared state and avoid allocating it.
69 */
70static const KernelData kernel_data = {
71    lock:  SPIN_LOCK_UNLOCKED,
72    flags: 0,
73    buf_n: BUF_N,
74};
75
76/** Stream for kernel printk. */
77static IOStream iokernel = {
78    methods: &kernel_methods,
79    data:    &kernel_data,
80    nofree:  1,
81};
82
83/** Stream for kernel printk. */
84IOStream *iostdout = &iokernel;
85
86/** Stream for kernel printk. */
87IOStream *iostdin = &iokernel;
88
89/** Stream for kernel printk. */
90IOStream *iostderr = &iokernel;
91
92/** Get an output-only stream implementation using
93 * printk(). The stream uses static storage, and must not be freed.
94 *
95 * @return kernel stream
96 */
97IOStream get_stream_kernel(void){
98    return iokernel;
99}
100
101/** Obtain the lock on the stream state.
102 *
103 * @param kdata stream state
104 */
105static inline void KernelData_lock(KernelData *kdata){
106    spin_lock_irqsave(&kdata->lock, kdata->flags);
107}
108
109/** Release the lock on the stream state.
110 *
111 * @param kdata stream state
112 */
113static inline void KernelData_unlock(KernelData *kdata){
114    spin_unlock_irqrestore(&kdata->lock, kdata->flags);
115}
116
117/** Get the stream state.
118 *
119 * @param s kernel stream
120 * @return stream state
121 */
122static inline KernelData *get_kernel_data(IOStream *s){
123    return (KernelData*)s->data;
124}
125
126/** Obtain the lock on the stream state.
127 *
128 * @param s stream
129 */
130void kernel_stream_lock(IOStream *s){
131    KernelData_lock(get_kernel_data(s));
132}
133
134/** Release the lock on the stream state.
135 *
136 * @param s stream
137 */
138void kernel_stream_unlock(IOStream *s){
139    KernelData_unlock(get_kernel_data(s));
140}
141
142/** Write to a kernel stream.
143 *
144 * @param stream kernel stream
145 * @param format print format
146 * @param args print arguments
147 * @return result of the print
148 */
149static int kernel_write(IOStream *stream, const void *buf, size_t n){
150    KernelData *kdata = get_kernel_data(stream);
151    int k;
152    k = kdata->buf_n - 1;
153    if(n < k) k = n;
154    memcpy(kdata->buf, buf, k);
155    kdata->buf[k] = '\0';
156    printk(kdata->buf);
157    return k;
158}
159
160/** Free a kernel stream.
161 * Frees the internal state of the stream.
162 * Do not call this unless the stream was dynamically allocated.
163 * Do not call this on a stream returned from get_stream_kernel().
164 *
165 * @param io stream to free
166 */
167static void kernel_free(IOStream *io){
168    KernelData *kdata;
169    if(io == &iokernel) return;
170    kdata = get_kernel_data(io);
171    memset(kdata, 0, sizeof(*kdata));
172    deallocate(kdata);
173}
174#endif /* __KERNEL__ */
175
176
177
178
Note: See TracBrowser for help on using the repository browser.