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