1.\" $FreeBSD$ 2.\" 3.\" Copyright (c) 2010-2022 Hans Petter Selasky 4.\" 5.\" All rights reserved. 6.\" 7.\" Redistribution and use in source and binary forms, with or without 8.\" modification, are permitted provided that the following conditions 9.\" are met: 10.\" 1. Redistributions of source code must retain the above copyright 11.\" notice, this list of conditions and the following disclaimer. 12.\" 2. 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. 15.\" 16.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26.\" SUCH DAMAGE. 27.\" 28.Dd July 18, 2022 29.Dt CUSE 3 30.Os 31.Sh NAME 32.Nm libcuse 33.Nd "Userland character device library" 34.Sh LIBRARY 35.Lb libcuse 36.Sh SYNOPSIS 37To load the required kernel module at boot time, place the following line in 38.Xr loader.conf 5 : 39.Bd -literal -offset indent 40cuse_load="YES" 41.Ed 42.Pp 43.In cuse.h 44.Sh DESCRIPTION 45The 46.Nm 47library contains functions to create a character device in userspace. 48The 49.Nm 50library is thread safe. 51.Sh LIBRARY INITIALISATION / DEINITIALISATION 52.Ft "int" 53.Fn "cuse_init" "void" 54This function initialises 55.Nm . 56Must be called at the beginning of the program. 57This function returns 0 on success or a negative value on failure. 58See 59.Dv CUSE_ERR_XXX 60for known error codes. 61If the cuse kernel module is not loaded, 62.Dv CUSE_ERR_NOT_LOADED 63is returned. 64.Pp 65.Ft "int" 66.Fn "cuse_uninit" "void" 67Deinitialise 68.Nm . 69Can be called at the end of the application. 70This function returns 0 on success or a negative value on failure. 71See 72.Dv CUSE_ERR_XXX 73for known error codes. 74.Sh UNIT MANAGEMENT 75.Ft "int" 76.Fn "cuse_alloc_unit_number" "int *" 77This function stores a uniq system unit number at the pointed 78integer loation. 79This function returns 0 on success or a negative value on failure. 80See 81.Dv CUSE_ERR_XXX 82for known error codes. 83.Pp 84.Ft "int" 85.Fn "cuse_alloc_unit_number_by_id" "int *" "int id" 86This function stores a unique system unit number at the pointed 87integer loation. 88The returned unit number is uniq within the given ID. 89Valid ID values are defined by the cuse include file. 90See the 91.Fn CUSE_ID_XXX 92macros for more information. 93This function returns 0 on success or a negative value on failure. 94See 95.Dv CUSE_ERR_XXX 96for known error codes. 97.Pp 98.Ft "int" 99.Fn "cuse_free_unit_number" "int" 100This function frees the given allocated system unit number. 101This function returns 0 on success or a negative value on failure. 102See 103.Dv CUSE_ERR_XXX 104for known error codes. 105.Pp 106.Ft "int" 107.Fn "cuse_free_unit_number_by_id" "int unit" "int id" 108This function frees the given allocated system unit number belonging 109to the given ID. 110If both the unit and id argument is -1, all allocated units will be freed. 111This function returns 0 on success or a negative value on failure. 112See 113.Dv CUSE_ERR_XXX 114for known error codes. 115.Sh LIBRARY USAGE 116.Ft "void *" 117.Fn "cuse_vmalloc" "unsigned size" 118This function allocates 119.Ar size 120bytes of memory. 121Only memory allocated by this function can be memory 122mapped by 123.Xr mmap 2 . 124This function returns a valid data pointer on success or 125.Dv NULL 126on failure. 127The returned pointer is always aligned to the system page size. 128The number and size of allocations is limited by the 129.Xr mmap 2 130offset having to fit into a 32-bit variable typically for 32-bit 131applications. 132.Pp 133.Ft "int" 134.Fn "cuse_is_vmalloc_addr" "void *" 135This function returns non-zero if the passed pointer points to a valid 136and non-freed allocation, as returned by 137.Fn cuse_vmalloc . 138Else this function returns zero. 139.Pp 140.Ft "void" 141.Fn "cuse_vmfree" "void *" 142This function frees memory allocated by 143.Fn cuse_vmalloc . 144This function is NULL safe. 145.Pp 146.Ft "unsigned long" 147.Fn "cuse_vmoffset" "void *" 148This function returns the mmap offset the client must use to 149access the allocated memory. 150The passed pointer must be aligned to the system page size. 151.Pp 152.Ft "struct cuse_dev *" 153.Fn "cuse_dev_create" "const struct cuse_methods *mtod" "void *priv0" "void *priv1" "uid_t" "gid_t" "int permission" "const char *fmt" "..." 154This function creates a new character device according to the given 155parameters. 156This function returns a valid cuse_dev structure pointer 157on success or 158.Dv NULL 159on failure. 160The device name can only contain a-z, 161A-Z, 0-9, dot, / and underscore characters. 162.Pp 163.Ft "void" 164.Fn "cuse_dev_destroy" "struct cuse_dev *" 165This functions destroys a previously created character device. 166.Pp 167.Ft "void *" 168.Fn "cuse_dev_get_priv0" "struct cuse_dev *" , 169.Ft "void *" 170.Fn "cuse_dev_get_priv1" "struct cuse_dev *" , 171.Ft "void" 172.Fn "cuse_dev_set_priv0" "struct cuse_dev *" "void *" , 173.Ft "void" 174.Fn "cuse_dev_set_priv1" "struct cuse_dev *" "void *" 175These functions are used to set and get the private data of the given 176cuse device. 177.Pp 178.Ft "int" 179.Fn "cuse_wait_and_process" "void" 180This function will block and do event processing. 181If parallel I/O is 182required multiple threads must be created looping on this 183function. 184This function returns 0 on success or a negative value on failure. 185See 186.Dv CUSE_ERR_XXX 187for known error codes. 188.Pp 189.Ft "void *" 190.Fn "cuse_dev_get_per_file_handle" "struct cuse_dev *" , 191.Ft "void" 192.Fn "cuse_dev_set_per_file_handle" "struct cuse_dev *" "void *" 193These functions are used to set and get the per-file-open specific handle 194and should only be used inside the cuse file operation callbacks. 195.Pp 196.Ft "void" 197.Fn "cuse_set_local" "int" 198This function instructs 199.Fn cuse_copy_out 200and 201.Fn cuse_copy_in 202that the 203user pointer is local, if the argument passed to it is non-zero. 204Else the user pointer is assumed to be at the peer application. 205This function should only be used inside the cuse file operation callbacks. 206The value is reset to zero when the given file operation returns, and 207does not affect any other file operation callbacks. 208.Pp 209.Ft "int" 210.Fn "cuse_get_local" "void" 211Returns the current local state. 212See 213.Fn cuse_set_local . 214.Pp 215.Ft "int" 216.Fn "cuse_copy_out" "const void *src" "void *peer_dst" "int len" , 217.Ft "int" 218.Fn "cuse_copy_in" "const void *peer_src" "void *dst" "int len" 219These functions are used to transfer data between the local 220application and the peer application. 221These functions must be used 222when operating on the data pointers passed to the 223.Fn cm_read , 224.Fn cm_write , 225and 226.Fn cm_ioctl 227callback functions. 228These functions return 0 on success or a negative value on failure. 229See 230.Dv CUSE_ERR_XXX 231for known error codes. 232.Pp 233.Ft "int" 234.Fn "cuse_got_peer_signal" "void" 235This function is used to check if a signal has been delivered to the 236peer application and should only be used inside the cuse file 237operation callbacks. 238This function returns 0 if a signal has been 239delivered to the caller. 240Else it returns a negative value. 241See 242.Dv CUSE_ERR_XXX 243for known error codes. 244.Pp 245.Ft "struct cuse_dev *" 246.Fn "cuse_dev_get_current" "int *pcmd" 247This function is used to get the current cuse device pointer and the 248currently executing command, by 249.Dv CUSE_CMD_XXX 250value. 251The 252.Ar pcmd 253argument 254is allowed to be 255.Dv NULL . 256This function should only be used inside the 257cuse file operation callbacks. 258On success a valid cuse device pointer 259is returned. 260On failure 261.Dv NULL 262is returned. 263.Pp 264.Ft "void" 265.Fn "cuse_poll_wakeup" "void" 266This function will wake up any file pollers. 267.Sh LIBRARY LIMITATIONS 268Transfer lengths for 269.Fn read , 270.Fn write , 271.Fn cuse_copy_in , 272and 273.Fn cuse_copy_out 274should not exceed what can fit into a 32-bit signed integer and is 275defined by the 276.Fn CUSE_LENGTH_MAX 277macro. 278Transfer lengths for ioctls should not exceed what is defined by the 279.Fn CUSE_BUFFER_MAX 280macro. 281.Sh LIBRARY CALLBACK METHODS 282In general fflags are defined by 283.Dv CUSE_FFLAG_XXX 284and errors are defined by 285.Dv CUSE_ERR_XXX . 286.Bd -literal -offset indent 287enum { 288 CUSE_ERR_NONE 289 CUSE_ERR_BUSY 290 CUSE_ERR_WOULDBLOCK 291 CUSE_ERR_INVALID 292 CUSE_ERR_NO_MEMORY 293 CUSE_ERR_FAULT 294 CUSE_ERR_SIGNAL 295 CUSE_ERR_OTHER 296 CUSE_ERR_NOT_LOADED 297 CUSE_ERR_NO_DEVICE 298 299 CUSE_POLL_NONE 300 CUSE_POLL_READ 301 CUSE_POLL_WRITE 302 CUSE_POLL_ERROR 303 304 CUSE_FFLAG_NONE 305 CUSE_FFLAG_READ 306 CUSE_FFLAG_WRITE 307 CUSE_FFLAG_NONBLOCK 308 CUSE_FFLAG_COMPAT32 309 310 CUSE_CMD_NONE 311 CUSE_CMD_OPEN 312 CUSE_CMD_CLOSE 313 CUSE_CMD_READ 314 CUSE_CMD_WRITE 315 CUSE_CMD_IOCTL 316 CUSE_CMD_POLL 317 CUSE_CMD_SIGNAL 318 CUSE_CMD_SYNC 319 CUSE_CMD_MAX 320}; 321.Ed 322.Pp 323.Ft "int" 324.Fn "cuse_open_t" "struct cuse_dev *" "int fflags" 325This function returns a 326.Dv CUSE_ERR_XXX 327value. 328.Pp 329.Ft "int" 330.Fn "cuse_close_t" "struct cuse_dev *" "int fflags" 331This function returns a 332.Dv CUSE_ERR_XXX 333value. 334.Pp 335.Ft "int" 336.Fn "cuse_read_t" "struct cuse_dev *" "int fflags" "void *peer_ptr" "int len" 337This function returns a 338.Dv CUSE_ERR_XXX 339value in case of failure or the 340actually transferred length in case of success. 341.Fn cuse_copy_in 342and 343.Fn cuse_copy_out 344must be used to transfer data to and from the 345.Ar peer_ptr . 346.Pp 347.Ft "int" 348.Fn "cuse_write_t" "struct cuse_dev *" "int fflags" "const void *peer_ptr" "int len" 349This function returns a 350.Dv CUSE_ERR_XXX 351value in case of failure or the 352actually transferred length in case of success. 353.Fn cuse_copy_in 354and 355.Fn cuse_copy_out 356must be used to transfer data to and from the 357.Ar peer_ptr . 358.Pp 359.Ft "int" 360.Fn "cuse_ioctl_t" "struct cuse_dev *" "int fflags" "unsigned long cmd" "void *peer_data" 361This function returns a 362.Dv CUSE_ERR_XXX 363value in case of failure or zero 364in case of success. 365.Fn cuse_copy_in 366and 367.Fn cuse_copy_out 368must be used to 369transfer data to and from the 370.Ar peer_data . 371.Pp 372.Ft "int" 373.Fn "cuse_poll_t" "struct cuse_dev *" "int fflags" "int events" 374This function returns a mask of 375.Dv CUSE_POLL_XXX 376values in case of failure and success. 377The events argument is also a mask of 378.Dv CUSE_POLL_XXX 379values. 380.Bd -literal -offset indent 381struct cuse_methods { 382 cuse_open_t *cm_open; 383 cuse_close_t *cm_close; 384 cuse_read_t *cm_read; 385 cuse_write_t *cm_write; 386 cuse_ioctl_t *cm_ioctl; 387 cuse_poll_t *cm_poll; 388}; 389.Ed 390.Sh HISTORY 391.Nm 392was written by Hans Petter Selasky. 393