jcs's openbsd hax
openbsd
1.\" $OpenBSD: fuse_opt.3,v 1.8 2026/02/02 23:35:20 jsg Exp $
2.\"
3.\" Copyright (c) Ray Lai <ray@raylai.com>
4.\" Copyright (c) Helg Bredow <helg@openbsd.org>
5.\"
6.\" Permission to use, copy, modify, and distribute this software for any
7.\" purpose with or without fee is hereby granted, provided that the above
8.\" copyright notice and this permission notice appear in all copies.
9.\"
10.\" THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11.\" WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12.\" MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13.\" ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14.\" WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17.\"
18.Dd $Mdocdate: February 2 2026 $
19.Dt FUSE_OPT 3
20.Os
21.Sh NAME
22.Nm FUSE_ARGS_INIT ,
23.Nm FUSE_OPT_IS_OPT_KEY ,
24.Nm FUSE_OPT_KEY ,
25.Nm FUSE_OPT_END ,
26.Nm fuse_opt_add_arg ,
27.Nm fuse_opt_insert_arg ,
28.Nm fuse_opt_add_opt ,
29.Nm fuse_opt_add_opt_escaped ,
30.Nm fuse_opt_free_args ,
31.Nm fuse_opt_match ,
32.Nm fuse_opt_parse
33.Nd FUSE argument and option parser
34.Sh SYNOPSIS
35.Lb libfuse
36.In fuse_opt.h
37.Ft struct fuse_args
38.Fo FUSE_ARGS_INIT
39.Fa "int argc"
40.Fa "char argv**"
41.Fc
42.Ft int
43.Fo FUSE_OPT_IS_OPT_KEY
44.Fa "fuse_opt *t"
45.Fc
46.Ft struct fuse_opt
47.Fo FUSE_OPT_KEY
48.Fa "const char *templ"
49.Fa "int key"
50.Fc
51.Ft struct fuse_opt
52.Fn FUSE_OPT_END
53.Ft int
54.Fo fuse_opt_add_arg
55.Fa "struct fuse_args *args"
56.Fa "const char *arg"
57.Fc
58.Ft int
59.Fo fuse_opt_insert_arg
60.Fa "struct fuse_args *args"
61.Fa "int pos"
62.Fa "const char *opt"
63.Fc
64.Ft int
65.Fo fuse_opt_add_opt
66.Fa "char **opts"
67.Fa "const char *opt"
68.Fc
69.Ft int
70.Fo fuse_opt_add_opt_escaped
71.Fa "char **opts"
72.Fa "const char *opt"
73.Fc
74.Ft void
75.Fo fuse_opt_free_args
76.Fa "struct fuse_args *args"
77.Fc
78.Ft int
79.Fo fuse_opt_match
80.Fa "const struct fuse_opt *opts"
81.Fa "const char *opt"
82.Fc
83.Ft int
84.Fo fuse_opt_parse
85.Fa "struct fuse_args *args"
86.Fa "void *data"
87.Fa "const struct fuse_opt *opts"
88.Fa "fuse_opt_proc_t proc"
89.Fc
90.Ft typedef int
91.Fo (*fuse_opt_proc_t)
92.Fa "void *data"
93.Fa "const char *arg"
94.Fa "int key"
95.Fa "struct fuse_args *outargs"
96.Fc
97.Sh DESCRIPTION
98These FUSE library functions and macros provide support for complex
99argument and option parsing.
100These are typically entered on the command line
101but may also be passed by file systems to the
102.Xr fuse_mount 3
103and
104.Xr fuse_new 3
105functions.
106.Ft struct fuse_args
107holds string options in an array:
108.Bd -literal -offset indent
109struct fuse_args {
110 int argc; /* argument count */
111 char **argv; /* NULL-terminated array of arguments */
112 int allocated; /* argv was allocated and must be freed */
113};
114.Ed
115.Pp
116.Bl -tag -width Ds -compact
117.It Fn FUSE_ARGS_INIT
118initializes a
119.Ft struct fuse_args
120with
121.Fa argc
122and
123.Fa argv ,
124which are usually obtained from
125.Fn main .
126.Fa argv
127is
128.Dv NULL Ns -terminated ,
129and is suitable for use with
130.Xr execvp 3 .
131.Fa argv
132is used directly and
133.Fa allocated
134is set to 0.
135.Pp
136.It Fn fuse_opt_add_arg
137adds a single option to the end of
138.Fa args .
139If
140.Fa args->allocated
141is 0,
142.Fa args->argv
143is copied to the heap and
144.Fa args->allocated
145is set to a non-zero value.
146.Pp
147.It Fn fuse_opt_insert_arg
148inserts a single argument at position
149.Fa pos
150into
151.Fa args ,
152shifting
153.Fa args->argv
154as needed.
155.Pp
156.It Fn fuse_opt_free_args
157If
158.Fa args
159is allocated, free
160.Fa args->argv
161and zero all members of
162.Fa args .
163Otherwise, do nothing.
164.Pp
165.It Fn FUSE_OPT_KEY templ key
166Return a
167.Fa struct fuse_opt
168template that matches an argument or option
169.Vt templ
170with option key
171.Vt key .
172This macro is used as an element in
173.Fa struct fuse_opt
174arrays to create a template that is processed by a
175.Vt fuse_opt_proc_t .
176The special constants
177.Dv FUSE_OPT_KEY_KEEP
178and
179.Dv FUSE_OPT_KEY_DISCARD
180can be specified for
181.Fa val
182if
183.Fa proc
184does not need to handle this option or argument;
185.Fa proc
186is not called in this case.
187.Bd -literal -offset indent
188struct fuse_opt {
189 const char *templ; /* template for option */
190 unsigned long off; /* data offset */
191 int val; /* key value */
192};
193.Ed
194.Pp
195The following special key values can be used for
196.Fa val :
197.Bd -literal -offset indent
198FUSE_OPT_KEY_OPT /* no match */
199FUSE_OPT_KEY_NONOPT /* non-option */
200FUSE_OPT_KEY_KEEP /* don't process; return 1 */
201FUSE_OPT_KEY_DISCARD /* don't process; return 0 */
202.Ed
203.It Fn FUSE_OPT_END
204The last element of each
205.Fa "struct fuse_opt *opts"
206array passed to any function must be
207.Dv FUSE_OPT_END .
208.Pp
209.It Fn FUSE_OPT_IS_OPT_KEY templ
210Check whether
211.Fa templ
212is an option key.
213.Pp
214.It Fn fuse_opt_add_opt
215adds an option
216.Fa opt
217to a comma-separated string of options
218.Fa opts .
219.Fa *opts
220can be
221.Dv NULL ,
222which is typically used when adding the first option.
223.Pp
224.It Fn fuse_opt_add_opt_escaped
225escapes any
226.Sq ,\&
227and
228.Sq \e
229characters in
230.Fa opt
231before adding it to
232.Fa opts .
233.Pp
234.It Fn fuse_opt_match
235tests if the argument or option
236.Fa opt
237appears in the list of templates
238.Fa opts .
239If
240.Fa opt
241is an option then it must not include the -o prefix.
242.Pp
243.It Fn fuse_opt_parse
244parses options, setting any members of
245.Fa data
246automatically depending on the format of the template.
247If
248.Fa proc
249is not
250.Dv NULL ,
251then this is called for any argument that matches a template
252that has
253.Fa offset No = Dv FUSE_OPT_KEY_OPT .
254.Fa opts
255is an array of
256.Ft struct fuse_opt ,
257each of which describes actions for each option:
258.Pp
259The following templates are supported as options and must be preceded by
260.Fl o
261in the list of arguments, with or without a space between
262.Fl o
263and the option.
264If multiple options are specified they can be comma separated or specified
265individually with
266.Fl o
267each time.
268For example, these are all valid:
269.Bd -unfilled -offset indent
270.Fl o Ar foo
271.Sm off
272.Fl o Ar bar
273.Fl o Ar foo , bar
274.Sm on
275.Ed
276.Pp
277foo matches exactly
278.Pp
279foo= matches exactly
280.Pp
281foo=bar matches the option exactly (treated the same as if it didn't have an =).
282.Pp
283foo=%u %u can be any format that can be parsed by
284.Fn sscanf 3 .
285If this is %s then a copy of the string is allocated.
286.Pp
287Arguments
288.Pp
289-b or --bar matches the argument and sets the value of the struct at offset
290to key.
291.Pp
292.Qq Fl b Ns \ \&
293or
294.Qq Fl \-bar Ns \ \&
295(trailing space) argument expects a value, the whole argument,
296including -b, is passed to
297.Fa proc
298.Pp
299.Qq Fl b Ar %u
300or
301.Qq Fl \-bar Ar %u
302is treated the same as foo=%u above
303.Pp
304Each argument or option is matched against every template.
305This allows more than one member of
306.Fa data
307to be set by a single argument or option (see example for gid below).
308.Pp
309.It Fn fuse_opt_proc_t
310The fuse_opt_proc_t function takes the following arguments.
311.Bl -tag -width Ds
312.It Fa data
313data argument passed to
314.Fn fuse_opt_parse
315.It Fa arg
316the whole argument or option
317.It Fa key
318is the key defined with the option or one of the special keys.
319.It Fa outargs
320The current list of arguments
321.El
322.El
323.Sh RETURN VALUES
324.Fn fuse_opt_add_arg ,
325.Fn fuse_opt_insert_arg ,
326.Fn fuse_opt_add_opt ,
327.Fn fuse_opt_add_opt_escaped ,
328and
329.Fn fuse_opt_parse
330return 0 on success or \-1 on error.
331.Pp
332.Fn fuse_opt_match
333returns 1 on match or 0 if no match.
334.Sh EXAMPLES
335.Bd -literal
336#include <err.h>
337#include <fuse.h>
338#include <stddef.h>
339#include <stdio.h>
340#include <string.h>
341
342enum {
343 KEY_FOO
344};
345
346struct foo_config {
347 char *foo;
348 int bar;
349 gid_t gid;
350 int set_gid;
351 int toggle;
352};
353
354#define FOO_OPT(t, m) {t, offsetof(struct foo_config, m), 1}
355
356struct fuse_opt opts[] = {
357 FUSE_OPT_KEY("--foo ", KEY_FOO),/* passed to foo_opt_proc() */
358 FOO_OPT("-b", bar), /* set to 1 if present */
359 FOO_OPT("toggle", toggle), /* set to 1 if present */
360 FOO_OPT("gid=", set_gid), /* set to 1 if present */
361 FOO_OPT("gid=%u", gid), /* set to parsed value of %u */
362 FUSE_OPT_END
363};
364
365int
366foo_opt_proc(void *data, const char *val, int key, struct fuse_args *args)
367{
368 struct foo_config *conf = data;
369
370 switch(key)
371 {
372 case KEY_FOO:
373 conf->foo = strdup(val);
374 return (0); /* discard */
375 }
376
377 /* didn't process, so keep the option */
378 return (1);
379}
380
381int
382main(int argc, char *argv[])
383{
384 struct fuse_args args = FUSE_ARGS_INIT(argc, argv);
385 struct foo_config config;
386
387 memset(&config, 0, sizeof(config));
388 if (fuse_opt_parse(&args, &config, opts, foo_opt_proc) == -1)
389 err(1, "Usage: prog [foo=value] [-b] "
390 "[-o [gid=value],[toggle]]");
391
392 printf("foo=%s\en", config.foo);
393 printf("toggle=%d\en", config.toggle);
394 printf("bar=%d\en", config.bar);
395 printf("set_gid=%d\en", config.set_gid);
396 printf("gid=%u\en", config.gid);
397}
398.Ed
399.Sh ERRORS
400.Fn fuse_opt_add_arg ,
401.Fn fuse_opt_insert_arg ,
402.Fn fuse_opt_add_opt ,
403and
404.Fn fuse_opt_add_opt_escaped
405can run out of memory and set
406.Va errno .
407.Sh SEE ALSO
408.Xr fuse_main 3
409.Sh STANDARDS
410These library functions conform to FUSE 2.6.
411.Sh HISTORY
412These functions first appeared in
413.Ox 5.4 .
414.Sh AUTHORS
415.An Sylvestre Gallon Aq Mt ccna.syl@gmail.com
416.An Helg Bredow Aq Mt helg@openbsd.org
417.Pp
418This manual was written by
419.An Ray Lai Aq Mt ray@raylai.com
420and updated by
421.An Helg Bredow Aq Mt helg@openbsd.org