tests: ocaml: Test NBDKit.version () binding
[nbdkit.git] / tests / test-stdio-plugin.c
blob09382a094a0e59d45c13bea2c2cec0e49c601d06
1 /* nbdkit
2 * Copyright (C) 2013-2020 Red Hat Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
30 * SUCH DAMAGE.
33 #include <config.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdbool.h>
38 #include <string.h>
39 #include <fcntl.h>
40 #include <unistd.h>
41 #include <sys/stat.h>
43 #undef NDEBUG /* Keep test strong even for nbdkit built without assertions */
44 #include <assert.h>
46 #define NBDKIT_API_VERSION 2
47 #include <nbdkit-plugin.h>
49 #include "getline.h"
51 static const char *msg = "input";
53 /* Check whether stdin/out match /dev/null */
54 static bool
55 stdio_check (void)
57 static int dn = -1;
58 struct stat st1, st2;
60 if (dn == -1) {
61 dn = open ("/dev/null", O_RDONLY);
62 assert (dn > STDERR_FILENO);
64 if (fstat (dn, &st1) == -1)
65 assert (false);
67 if (fstat (STDIN_FILENO, &st2) == -1)
68 assert (false);
69 if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
70 return false;
72 if (fstat (STDOUT_FILENO, &st2) == -1)
73 assert (false);
74 if (st1.st_dev != st2.st_dev || st1.st_ino != st2.st_ino)
75 return false;
77 return true;
80 static void
81 stdio_dump_plugin (void)
83 char *buf = NULL;
84 size_t len = 0;
85 bool check = stdio_check ();
87 assert (check == false);
89 /* Reading from stdin during .dump_plugin is unusual, but not forbidden */
90 if (getline (&buf, &len, stdin) == -1)
91 assert (false);
92 /* The point of .dump_plugin is to extend details sent to stdout */
93 printf ("%s=%s\n", msg, buf);
94 free (buf);
97 static int
98 stdio_config (const char *key, const char *value)
100 bool check = stdio_check ();
101 assert (check == false);
102 msg = key;
103 return 0;
106 static int
107 stdio_config_complete (void)
109 bool check = stdio_check ();
110 assert (check == false);
111 if (nbdkit_stdio_safe ()) {
112 char *buf = NULL;
113 size_t len = 0;
115 /* Reading from stdin during .config_complete is safe except under -s */
116 if (getline (&buf, &len, stdin) == -1)
117 assert (false);
118 /* Output during .config_complete is unusual, but not forbidden */
119 printf ("%s=%s\n", msg, buf);
120 free (buf);
122 return 0;
125 static int
126 stdio_get_ready (void)
128 bool check = stdio_check ();
129 assert (check == false);
130 return 0;
133 static int
134 stdio_after_fork (void)
136 bool check = stdio_check ();
137 assert (check == true);
138 return 0;
141 static void *
142 stdio_open (int readonly)
144 bool check = stdio_check ();
145 assert (check == true);
146 return NBDKIT_HANDLE_NOT_NEEDED;
149 static int64_t
150 stdio_get_size (void *handle)
152 bool check = stdio_check ();
153 assert (check == true);
154 return 1024*1024;
157 #define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
159 static int
160 stdio_pread (void *handle, void *buf, uint32_t count, uint64_t offset,
161 uint32_t flags)
163 bool check = stdio_check ();
164 assert (check == true);
165 memset (buf, 0, count);
166 return 0;
169 static struct nbdkit_plugin plugin = {
170 .name = "stdio",
171 .version = PACKAGE_VERSION,
172 .dump_plugin = stdio_dump_plugin,
173 .config = stdio_config,
174 .config_complete = stdio_config_complete,
175 .get_ready = stdio_get_ready,
176 .after_fork = stdio_after_fork,
177 .open = stdio_open,
178 .get_size = stdio_get_size,
179 .pread = stdio_pread,
182 NBDKIT_REGISTER_PLUGIN(plugin)