3 * Copyright (c) 2003 The Regents of the University of California. All
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
10 * - Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
13 * - Neither the name of the University nor the names of its
14 * contributors may be used to endorse or promote products derived
15 * from this software without specific prior written permission.
17 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS''
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
19 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
20 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
21 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
22 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
25 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33 * FUSD - The Framework for UserSpace Devices - Example program
35 * Jeremy Elson <jelson@circlemud.org>
37 * echo.c: Example of how to use both the 'read' and 'write' callbacks.
39 * This example creates a single device, /dev/echo. If you write
40 * something to /dev/echo (e.g., "echo HI THERE > /dev/echo"), it gets
41 * stored. Then, when you read (e.g. "cat /dev/echo"), you get back
42 * whatever you wrote most recently.
55 #define MIN(x, y) ((x) < (y) ? (x) : (y))
57 /* EXAMPLE START echo.c */
61 ssize_t
echo_read(struct fusd_file_info
*file
, char *user_buffer
,
62 size_t user_length
, loff_t
*offset
)
64 /* if the user has read past the end of the data, return EOF */
65 if (*offset
>= data_length
)
68 /* only return as much data as we have */
69 user_length
= MIN(user_length
, data_length
- *offset
);
71 /* copy data to user starting from the first byte they haven't seen */
72 memcpy(user_buffer
, data
+ *offset
, user_length
);
73 *offset
+= user_length
;
75 /* tell them how much data they got */
79 ssize_t
echo_write(struct fusd_file_info
*file
, const char *user_buffer
,
80 size_t user_length
, loff_t
*offset
)
82 /* free the old data, if any */
89 /* allocate space for new data; return error if that fails */
90 if ((data
= malloc(user_length
)) == NULL
)
93 /* make a copy of user's data; tell the user we copied everything */
94 memcpy(data
, user_buffer
, user_length
);
95 data_length
= user_length
;
100 int do_open_or_close(struct fusd_file_info
*file
)
102 return 0; /* opens and closes always succeed */
106 struct fusd_file_operations echo_fops
= {
107 open
: do_open_or_close
,
110 close
: do_open_or_close
114 int main(int argc
, char *argv
[])
116 if (fusd_register("/dev/echo", "misc", "echo", 0666, NULL
, &echo_fops
) < 0) {
117 perror("register of /dev/echo failed");
121 fprintf(stderr
, "calling fusd_run...\n");