Document the plugin API.
[nbdkit/ericb.git] / plugins / example2 / example2.c
blobd9173ef105aee0ff8d70ff46fc5cb7afc6e515e5
1 /* nbdkit
2 * Copyright (C) 2013 Red Hat Inc.
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are
7 * met:
9 * * Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * * Neither the name of Red Hat nor the names of its contributors may be
17 * used to endorse or promote products derived from this software without
18 * specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
22 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
23 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
24 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
25 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
26 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
27 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
28 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
29 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
30 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
34 /* example2:
36 * A simple but more realistic read-only file server.
39 #include <config.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44 #include <fcntl.h>
45 #include <unistd.h>
47 #include <nbdkit-plugin.h>
49 static const char *filename = NULL;
51 /* Called for each key=value passed on the command line. This plugin
52 * only accepts file=<filename>, which is required.
54 static int
55 example2_config (const char *key, const char *value)
57 if (strcmp (key, "file") == 0) {
58 filename = value;
60 else {
61 nbdkit_error ("unknown parameter '%s'", key);
62 return -1;
65 return 0;
68 /* Check the user did pass a file=<FILENAME> parameter. */
69 static int
70 example2_config_complete (void)
72 if (filename == NULL) {
73 nbdkit_error ("you must supply the file=<FILENAME> parameter after the plugin name on the command line");
74 return -1;
77 return 0;
80 #define example2_config_help \
81 "file=<FILENAME> (required) The filename to serve."
83 /* The per-connection handle. */
84 struct example2_handle {
85 int fd;
88 /* Create the per-connection handle. */
89 static void *
90 example2_open (void)
92 struct example2_handle *h;
94 h = malloc (sizeof *h);
95 if (h == NULL) {
96 nbdkit_error ("malloc: %m");
97 return NULL;
100 h->fd = open (filename, O_RDONLY|O_CLOEXEC);
101 if (h->fd == -1) {
102 nbdkit_error ("open: %s: %m", filename);
103 free (h);
104 return NULL;
107 return h;
110 /* Free up the per-connection handle. */
111 static void
112 example2_close (void *handle)
114 struct example2_handle *h = handle;
116 close (h->fd);
117 free (h);
120 /* In fact NBDKIT_THREAD_MODEL_SERIALIZE_REQUESTS would work here.
121 * However for the benefit of people who blindly cut and paste code
122 * without bothering to read any documentation, leave this at a safe
123 * default.
125 #define THREAD_MODEL NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS
127 /* Read data from the file. */
128 static int
129 example2_pread (void *handle, void *buf, size_t count, off_t offset)
131 struct example2_handle *h = handle;
133 while (count > 0) {
134 ssize_t r = read (h->fd, buf, count);
135 if (r == -1) {
136 nbdkit_error ("read error: %m");
137 return -1;
139 if (r == 0) {
140 nbdkit_error ("unexpected end of file");
141 return -1;
143 buf += r;
144 count -= r;
147 return 0;
150 static struct nbdkit_plugin plugin = {
151 .name = "example2",
152 .config = example2_config,
153 .config_complete = example2_config_complete,
154 .config_help = example2_config_help,
155 .open = example2_open,
156 .close = example2_close,
157 .pread = example2_pread,
160 NBDKIT_REGISTER_PLUGIN(plugin)