diff options
Diffstat (limited to 'share/examples')
47 files changed, 645 insertions, 329 deletions
diff --git a/share/examples/FreeBSD_version/Makefile b/share/examples/FreeBSD_version/Makefile index 13d60978e868..9c74916dd6b4 100644 --- a/share/examples/FreeBSD_version/Makefile +++ b/share/examples/FreeBSD_version/Makefile @@ -1,4 +1,3 @@ - PACKAGE=examples FILESDIR=${SHAREDIR}/examples/${PROG} PROG= FreeBSD_version diff --git a/share/examples/Makefile b/share/examples/Makefile index 61e21f9350c1..f0c050a36306 100644 --- a/share/examples/Makefile +++ b/share/examples/Makefile @@ -15,12 +15,14 @@ LDIRS= BSD_daemon \ find_interface \ flua \ indent \ + inotify \ ipfw \ jails \ kld \ libvgl \ mdoc \ netgraph \ + oci \ perfmon \ ppi \ ppp \ @@ -96,6 +98,10 @@ SE_FLUA= libjail.lua SE_DIRS+= indent SE_INDENT= indent.pro +SE_DIRS+= inotify +SE_INOTIFY= inotify.c \ + Makefile + .if ${MK_IPFILTER} != "no" SUBDIR+= ipfilter .endif @@ -199,6 +205,11 @@ SE_NETGRAPH= \ virtual.chain \ virtual.lan \ +SE_DIRS+= oci +SE_OCI= \ + README \ + Containerfile.pkg + SE_DIRS+= perfmon SE_PERFMON= \ Makefile \ @@ -315,11 +326,13 @@ SE_SCSI_TARGET= \ SE_DIRS+= sound SE_SOUND= \ - basic.c \ - ossinit.h \ - ossmidi.h \ - midi.c \ - README + sndstat_nv.c \ + midi.c + +SE_DIRS+= sound/oss +SE_SOUND_OSS= \ + README \ + audio.c SE_DIRS+= sunrpc SE_SUNRPC= Makefile diff --git a/share/examples/csh/dot.cshrc b/share/examples/csh/dot.cshrc index 5cda009dbd96..4408af31cda3 100644 --- a/share/examples/csh/dot.cshrc +++ b/share/examples/csh/dot.cshrc @@ -137,3 +137,6 @@ setenv CLICOLOR 1 # other autolist options set autolist = TAB + +# Case insensitive search in pager and man +setenv PAGER less -I diff --git a/share/examples/drivers/make_device_driver.sh b/share/examples/drivers/make_device_driver.sh index 5b8f8efa6469..d6d3a8d7c6b9 100755 --- a/share/examples/drivers/make_device_driver.sh +++ b/share/examples/drivers/make_device_driver.sh @@ -342,7 +342,8 @@ ${1}_isa_identify (driver_t *driver, device_t parent) if ((ioport == 0) && (irq == 0)) return; /* We've added all our local hints. */ - child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "${1}", -1); + child = BUS_ADD_CHILD(parent, ISA_ORDER_SPECULATIVE, "${1}", + DEVICE_UNIT_ANY); bus_set_resource(child, SYS_RES_IOPORT, 0, ioport, NUMPORTS); bus_set_resource(child, SYS_RES_IRQ, 0, irq, 1); bus_set_resource(child, SYS_RES_DRQ, 0, res[i].drq, 1); diff --git a/share/examples/etc/make.conf b/share/examples/etc/make.conf index 0cf156371aec..93c611557cb6 100644 --- a/share/examples/etc/make.conf +++ b/share/examples/etc/make.conf @@ -43,8 +43,7 @@ # pentium3m, pentium3, pentium-m, pentium2, pentiumpro, # pentium-mmx, pentium, i486 # (VIA CPUs) c7, c3-2, c3 -# ARM architecture: armv5, armv5te, armv6, armv6t2, arm1176jzf-s, armv7, -# armv7-a, armv7ve, generic-armv7-a, cortex-a5, +# ARM architecture: armv7, armv7-a, armv7ve, generic-armv7-a, cortex-a5, # cortex-a7, cortex-a8, cortex-a9, cortex-a12, # cortex-a15, cortex-a17 # ARM64 architecture: cortex-a53, cortex-a57, cortex-a72, @@ -78,7 +77,7 @@ # # CFLAGS+= -msse3 # CXXFLAGS+= -msse3 -# CFLAGS.armv6+= -mfloat-abi=softfp +# CFLAGS.armv7+= -mfloat-abi=softfp # # MAKE_SHELL controls the shell used internally by make(1) to process the # command scripts in makefiles. Three shells are supported, sh, ksh, and diff --git a/share/examples/find_interface/Makefile b/share/examples/find_interface/Makefile index 91ce0eb88072..23d02a2002de 100644 --- a/share/examples/find_interface/Makefile +++ b/share/examples/find_interface/Makefile @@ -1,4 +1,3 @@ - PACKAGE=examples FILESDIR=${SHAREDIR}/examples/${PROG} PROG= find_interface diff --git a/share/examples/hast/ucarp.sh b/share/examples/hast/ucarp.sh index 73253a295f53..67c7aecea44f 100755 --- a/share/examples/hast/ucarp.sh +++ b/share/examples/hast/ucarp.sh @@ -3,7 +3,6 @@ # SPDX-License-Identifier: BSD-2-Clause # # Copyright (c) 2010 The FreeBSD Foundation -# All rights reserved. # # This software was developed by Pawel Jakub Dawidek under sponsorship from # the FreeBSD Foundation. diff --git a/share/examples/hast/ucarp_down.sh b/share/examples/hast/ucarp_down.sh index 133d35c59d5b..df78de156b1e 100755 --- a/share/examples/hast/ucarp_down.sh +++ b/share/examples/hast/ucarp_down.sh @@ -3,7 +3,6 @@ # SPDX-License-Identifier: BSD-2-Clause # # Copyright (c) 2010 The FreeBSD Foundation -# All rights reserved. # # This software was developed by Pawel Jakub Dawidek under sponsorship from # the FreeBSD Foundation. diff --git a/share/examples/hast/ucarp_up.sh b/share/examples/hast/ucarp_up.sh index 9f22b4205909..62dee23c12c7 100755 --- a/share/examples/hast/ucarp_up.sh +++ b/share/examples/hast/ucarp_up.sh @@ -3,7 +3,6 @@ # SPDX-License-Identifier: BSD-2-Clause # # Copyright (c) 2010 The FreeBSD Foundation -# All rights reserved. # # This software was developed by Pawel Jakub Dawidek under sponsorship from # the FreeBSD Foundation. diff --git a/share/examples/hwpmc/Makefile b/share/examples/hwpmc/Makefile index fcbb6160bb00..c7d1c54b1d19 100644 --- a/share/examples/hwpmc/Makefile +++ b/share/examples/hwpmc/Makefile @@ -1,4 +1,3 @@ - PACKAGE=examples FILESDIR=${SHAREDIR}/examples/hwpmc PROG= overhead diff --git a/share/examples/inotify/Makefile b/share/examples/inotify/Makefile new file mode 100644 index 000000000000..c54c629c58d7 --- /dev/null +++ b/share/examples/inotify/Makefile @@ -0,0 +1,6 @@ +PROG= inotify +MAN= + +LIBADD= xo + +.include <bsd.prog.mk> diff --git a/share/examples/inotify/inotify.c b/share/examples/inotify/inotify.c new file mode 100644 index 000000000000..b8e300bc992c --- /dev/null +++ b/share/examples/inotify/inotify.c @@ -0,0 +1,172 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2025 Klara, Inc. + */ + +/* + * A simple program to demonstrate inotify. Given one or more paths, it watches + * all events on those paths and prints them to standard output. + */ + +#include <sys/types.h> +#include <sys/event.h> +#include <sys/inotify.h> + +#include <assert.h> +#include <err.h> +#include <limits.h> +#include <signal.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +#include <libxo/xo.h> + +static void +usage(void) +{ + xo_errx(1, "usage: inotify <path1> [<path2> ...]"); +} + +static const char * +ev2str(uint32_t event) +{ + switch (event & IN_ALL_EVENTS) { + case IN_ACCESS: + return ("IN_ACCESS"); + case IN_ATTRIB: + return ("IN_ATTRIB"); + case IN_CLOSE_WRITE: + return ("IN_CLOSE_WRITE"); + case IN_CLOSE_NOWRITE: + return ("IN_CLOSE_NOWRITE"); + case IN_CREATE: + return ("IN_CREATE"); + case IN_DELETE: + return ("IN_DELETE"); + case IN_DELETE_SELF: + return ("IN_DELETE_SELF"); + case IN_MODIFY: + return ("IN_MODIFY"); + case IN_MOVE_SELF: + return ("IN_MOVE_SELF"); + case IN_MOVED_FROM: + return ("IN_MOVED_FROM"); + case IN_MOVED_TO: + return ("IN_MOVED_TO"); + case IN_OPEN: + return ("IN_OPEN"); + default: + switch (event) { + case IN_IGNORED: + return ("IN_IGNORED"); + case IN_Q_OVERFLOW: + return ("IN_Q_OVERFLOW"); + case IN_UNMOUNT: + return ("IN_UNMOUNT"); + } + warnx("unknown event %#x", event); + assert(0); + } +} + +static void +set_handler(int kq, int sig) +{ + struct kevent kev; + + (void)signal(sig, SIG_IGN); + EV_SET(&kev, sig, EVFILT_SIGNAL, EV_ADD, 0, 0, NULL); + if (kevent(kq, &kev, 1, NULL, 0, NULL) < 0) + xo_err(1, "kevent"); +} + +int +main(int argc, char **argv) +{ + struct inotify_event *iev, *iev1; + struct kevent kev; + size_t ievsz; + int ifd, kq; + + argc = xo_parse_args(argc, argv); + if (argc < 2) + usage(); + argc--; + argv++; + + ifd = inotify_init1(IN_NONBLOCK); + if (ifd < 0) + xo_err(1, "inotify"); + for (int i = 0; i < argc; i++) { + int wd; + + wd = inotify_add_watch(ifd, argv[i], IN_ALL_EVENTS); + if (wd < 0) + xo_err(1, "inotify_add_watch(%s)", argv[i]); + } + + xo_set_version("1"); + xo_open_list("events"); + + kq = kqueue(); + if (kq < 0) + xo_err(1, "kqueue"); + + /* + * Handle signals in the event loop so that we can close the xo list. + */ + set_handler(kq, SIGINT); + set_handler(kq, SIGTERM); + set_handler(kq, SIGHUP); + set_handler(kq, SIGQUIT); + + /* + * Monitor the inotify descriptor for events. + */ + EV_SET(&kev, ifd, EVFILT_READ, EV_ADD, 0, 0, NULL); + if (kevent(kq, &kev, 1, NULL, 0, NULL) < 0) + xo_err(1, "kevent"); + + ievsz = sizeof(*iev) + NAME_MAX + 1; + iev = malloc(ievsz); + if (iev == NULL) + err(1, "malloc"); + + for (;;) { + ssize_t n; + const char *ev; + + if (kevent(kq, NULL, 0, &kev, 1, NULL) < 0) + xo_err(1, "kevent"); + if (kev.filter == EVFILT_SIGNAL) + break; + + n = read(ifd, iev, ievsz); + if (n < 0) + xo_err(1, "read"); + assert(n >= (ssize_t)sizeof(*iev)); + + for (iev1 = iev; n > 0;) { + assert(n >= (ssize_t)sizeof(*iev1)); + + ev = ev2str(iev1->mask); + xo_open_instance("event"); + xo_emit("{:wd/%3d} {:event/%16s} {:name/%s}\n", + iev1->wd, ev, iev1->name); + xo_close_instance("event"); + + n -= sizeof(*iev1) + iev1->len; + iev1 = (struct inotify_event *)(void *) + ((char *)iev1 + sizeof(*iev1) + iev1->len); + } + (void)xo_flush(); + } + + xo_close_list("events"); + + if (xo_finish() < 0) + xo_err(1, "stdout"); + exit(0); +} diff --git a/share/examples/ipfilter/Makefile b/share/examples/ipfilter/Makefile index b1b8b57449f1..ec4d4be3dd2f 100644 --- a/share/examples/ipfilter/Makefile +++ b/share/examples/ipfilter/Makefile @@ -1,4 +1,3 @@ - PACKAGE=ipf FILES= README diff --git a/share/examples/jails/jng b/share/examples/jails/jng index 610b08f96840..53dc680e6312 100755 --- a/share/examples/jails/jng +++ b/share/examples/jails/jng @@ -314,6 +314,8 @@ jng_bridge() ngctl name $iface:lower ${iface}bridge || return fi + mtu=$(ifconfig ${iface} | sed -n '1s/^.*mtu //p;') || return + # Optionally create a secondary bridge if [ "$bridge" != "bridge" ] && ! ngctl info "$iface$bridge:" > /dev/null 2>&1 @@ -346,6 +348,7 @@ jng_bridge() echo $2 ) || return ngctl name "$iface$bridge:link$num" $eiface || return ifconfig $new name $eiface || return + ifconfig $eiface mtu $mtu || return ifconfig $eiface up || return # diff --git a/share/examples/kld/cdev/Makefile b/share/examples/kld/cdev/Makefile index 706cb2dcbae9..8c7662243b3c 100644 --- a/share/examples/kld/cdev/Makefile +++ b/share/examples/kld/cdev/Makefile @@ -1,4 +1,3 @@ - PACKAGE=examples FILESDIR=${SHAREDIR}/examples/kld/cdev SUBDIR= module test diff --git a/share/examples/kld/dyn_sysctl/Makefile b/share/examples/kld/dyn_sysctl/Makefile index 0dffd9c8e7b0..e47eb3f339b3 100644 --- a/share/examples/kld/dyn_sysctl/Makefile +++ b/share/examples/kld/dyn_sysctl/Makefile @@ -1,4 +1,3 @@ - PACKAGE=examples FILESDIR=${SHAREDIR}/examples/kld/${KMOD} SRCS = dyn_sysctl.c diff --git a/share/examples/kld/firmware/Makefile b/share/examples/kld/firmware/Makefile index b4b144a7669d..5e31deaa17eb 100644 --- a/share/examples/kld/firmware/Makefile +++ b/share/examples/kld/firmware/Makefile @@ -1,4 +1,3 @@ - PACKAGE=examples FILESDIR=${SHAREDIR}/examples/kld/firmware SUBDIR= fwimage fwconsumer diff --git a/share/examples/kld/firmware/fwconsumer/Makefile b/share/examples/kld/firmware/fwconsumer/Makefile index b29684999124..ce4f77d41d89 100644 --- a/share/examples/kld/firmware/fwconsumer/Makefile +++ b/share/examples/kld/firmware/fwconsumer/Makefile @@ -1,4 +1,3 @@ - PACKAGE=examples FILESDIR=${SHAREDIR}/examples/kld/fwconsumer KMOD= fw_consumer diff --git a/share/examples/kld/firmware/fwimage/Makefile b/share/examples/kld/firmware/fwimage/Makefile index 1e0e3ff3ca93..b57d2bf326b4 100644 --- a/share/examples/kld/firmware/fwimage/Makefile +++ b/share/examples/kld/firmware/fwimage/Makefile @@ -1,4 +1,3 @@ - PACKAGE=examples FILESDIR=${SHAREDIR}/examples/kld/fwimage KMOD= beastie diff --git a/share/examples/kld/khelp/Makefile b/share/examples/kld/khelp/Makefile index 7cbaa79ceda6..dfdf602a4689 100644 --- a/share/examples/kld/khelp/Makefile +++ b/share/examples/kld/khelp/Makefile @@ -1,4 +1,3 @@ - .include <bsd.own.mk> # Change if the src tree you are compiling for is not in /usr/src diff --git a/share/examples/kld/khelp/h_example.c b/share/examples/kld/khelp/h_example.c index fea7826a1fb4..92f0c885bbce 100644 --- a/share/examples/kld/khelp/h_example.c +++ b/share/examples/kld/khelp/h_example.c @@ -2,7 +2,6 @@ * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2010-2011 The FreeBSD Foundation - * All rights reserved. * * This software was developed at the Centre for Advanced Internet * Architectures, Swinburne University of Technology, Melbourne, Australia by diff --git a/share/examples/kld/random_adaptor/Makefile b/share/examples/kld/random_adaptor/Makefile index c391da795e89..c9011bb2dba3 100644 --- a/share/examples/kld/random_adaptor/Makefile +++ b/share/examples/kld/random_adaptor/Makefile @@ -1,4 +1,3 @@ - PACKAGE=examples FILESDIR=${SHAREDIR}/examples/kld/${KMOD} KMOD= random_adaptor_example diff --git a/share/examples/kld/syscall/Makefile b/share/examples/kld/syscall/Makefile index efae887771e2..4270f388bd1b 100644 --- a/share/examples/kld/syscall/Makefile +++ b/share/examples/kld/syscall/Makefile @@ -1,4 +1,3 @@ - PACKAGE=examples FILESDIR=${SHAREDIR}/examples/kld/syscall SUBDIR= module test diff --git a/share/examples/libusb20/Makefile b/share/examples/libusb20/Makefile index 262f1ac3825a..9c0524c00b2c 100644 --- a/share/examples/libusb20/Makefile +++ b/share/examples/libusb20/Makefile @@ -1,4 +1,3 @@ - PACKAGE=examples FILESDIR=${SHAREDIR}/examples/libusb20 TARGETS= bulk control diff --git a/share/examples/libvgl/Makefile b/share/examples/libvgl/Makefile index ebfa7eaa47ea..8bb99eb795b9 100644 --- a/share/examples/libvgl/Makefile +++ b/share/examples/libvgl/Makefile @@ -1,4 +1,3 @@ - PACKAGE=examples FILESDIR=${SHAREDIR}/examples/libvgl PROG= demo diff --git a/share/examples/oci/Containerfile.pkg b/share/examples/oci/Containerfile.pkg new file mode 100644 index 000000000000..074c470affc9 --- /dev/null +++ b/share/examples/oci/Containerfile.pkg @@ -0,0 +1,27 @@ +# This is an example showing how to extend the freebsd-runtime OCI image by +# installing additional packages while keeping the resulting image as small as +# possible. + +# The OS version matching the desired freebsd-runtime image +ARG version=14.snap + +# Select freebsd-runtime as our starting point. +FROM localhost/freebsd-runtime:${version} + +# A list of package(s) to install +ARG packages + +# Install package management tools. We specify 'FreeBSD' as the repository to +# use for downloading pkg since the freebsd-runtime image has both FreeBSD and +# FreeBSD-base pkg repo configs installed and FreeBSD-base does not contain the +# pkg package. +RUN env ASSUME_ALWAYS_YES=yes pkg bootstrap -r FreeBSD && pkg update + +# Install some package(s). +RUN pkg install -y ${packages} + +# Clean up and remove package management overhead. We delete downloaded +# packages, uninstall pkg and delete the repository metadata downloaded by 'pkg +# install'. This retains the record of which packages are installed in the +# image. +RUN pkg clean -ay && pkg delete -fy pkg && rm -rf /var/db/pkg/repos diff --git a/share/examples/oci/README b/share/examples/oci/README new file mode 100644 index 000000000000..890641cee300 --- /dev/null +++ b/share/examples/oci/README @@ -0,0 +1,7 @@ +This example Containerfile shows how to add packages to freebsd-runtime while +minimising the package metadata overhead. + +For instance, To build a new image called 'my-new-image:latest' containing the +nginx package: + +# podman build --squash --build-arg packages=nginx --tag my-new-image:latest -f Containerfile.pkg diff --git a/share/examples/perfmon/Makefile b/share/examples/perfmon/Makefile index a687980e7808..96712dee88e3 100644 --- a/share/examples/perfmon/Makefile +++ b/share/examples/perfmon/Makefile @@ -1,4 +1,3 @@ - PACKAGE=examples FILESDIR=${SHAREDIR}/examples/${PROG} PROG= perfmon diff --git a/share/examples/pf/Makefile b/share/examples/pf/Makefile index 4ea4f9c79bb8..3107fa346c65 100644 --- a/share/examples/pf/Makefile +++ b/share/examples/pf/Makefile @@ -1,4 +1,3 @@ - PACKAGE=examples FILES= faq-example1 faq-example2 faq-example3 \ ackpri queue1 queue2 queue3 queue4 \ diff --git a/share/examples/scsi_target/Makefile b/share/examples/scsi_target/Makefile index 39950b8c0ac1..42dd2ca58513 100644 --- a/share/examples/scsi_target/Makefile +++ b/share/examples/scsi_target/Makefile @@ -1,10 +1,13 @@ - PACKAGE=examples FILESDIR=${SHAREDIR}/examples/${PROG} PROG= scsi_target SRCS= scsi_target.h scsi_target.c scsi_cmds.c DPADD= ${LIBCAM} ${LIBSBUF} -LDADD= -lcam -lsbuf +LIBADD+= cam +LIBADD+= sbuf +# cast-qual is triggered only in a code path where the volatile keyword doesn't +# matter +CFLAGS.scsi_cmds.c= -Wno-cast-qual MAN= scsi_target.8 diff --git a/share/examples/scsi_target/scsi_cmds.c b/share/examples/scsi_target/scsi_cmds.c index 43217a562aba..122d4dec6287 100644 --- a/share/examples/scsi_target/scsi_cmds.c +++ b/share/examples/scsi_target/scsi_cmds.c @@ -102,10 +102,6 @@ static struct targ_cdb_handlers cdb_handlers[] = { static struct scsi_inquiry_data inq_data; static struct initiator_state istates[MAX_INITIATORS]; -extern int debug; -extern off_t volume_size; -extern u_int sector_size; -extern size_t buf_size; cam_status tcmd_init(u_int16_t req_inq_flags, u_int16_t sim_inq_flags) @@ -553,7 +549,7 @@ tcmd_rdwr_decode(struct ccb_accept_tio *atio, struct ccb_scsiio *ctio) tcmd_illegal_req(atio, ctio); return (0); } - if (blkno + count > volume_size) { + if (((off_t)(blkno + count)) > volume_size) { warnx("Attempt to access past end of volume"); tcmd_sense(ctio->init_id, ctio, SSD_KEY_ILLEGAL_REQUEST, 0x21, 0); diff --git a/share/examples/scsi_target/scsi_target.c b/share/examples/scsi_target/scsi_target.c index b8f3ed6a8a81..ee0a94e7a2a0 100644 --- a/share/examples/scsi_target/scsi_target.c +++ b/share/examples/scsi_target/scsi_target.c @@ -77,7 +77,9 @@ static struct ccb_queue work_queue; static struct ioc_enable_lun ioc_enlun = { CAM_BUS_WILDCARD, CAM_TARGET_WILDCARD, - CAM_LUN_WILDCARD + CAM_LUN_WILDCARD, + 0, + 0 }; /* Local functions */ @@ -208,7 +210,7 @@ main(int argc, char *argv[]) if (argc != 2) usage(); - sscanf(argv[0], "%u:%u:%u", &ioc_enlun.path_id, &ioc_enlun.target_id, + sscanf(argv[0], "%u:%u:%ju", &ioc_enlun.path_id, &ioc_enlun.target_id, &ioc_enlun.lun_id); file_name = argv[1]; @@ -258,10 +260,12 @@ main(int argc, char *argv[]) if (notaio == 0) { struct aiocb aio, *aiop; + void *aio_buf; /* See if we have we have working AIO support */ memset(&aio, 0, sizeof(aio)); - aio.aio_buf = malloc(sector_size); + aio_buf = malloc(sector_size); + aio.aio_buf = aio_buf; if (aio.aio_buf == NULL) err(1, "malloc"); aio.aio_fildes = file_fd; @@ -278,7 +282,7 @@ main(int argc, char *argv[]) assert(aiop == &aio); signal(SIGSYS, SIG_DFL); } - free((void *)aio.aio_buf); + free(aio_buf); if (debug && notaio == 0) warnx("aio support tested ok"); } @@ -331,7 +335,7 @@ main(int argc, char *argv[]) } static void -cleanup() +cleanup(void) { struct ccb_hdr *ccb_h; @@ -358,7 +362,7 @@ cleanup() /* Allocate ATIOs/INOTs and queue on HBA */ static int -init_ccbs() +init_ccbs(void) { int i; @@ -395,7 +399,7 @@ init_ccbs() } static void -request_loop() +request_loop(void) { struct kevent events[MAX_EVENTS]; struct timespec ts, *tptr; @@ -535,10 +539,10 @@ request_loop() /* CCBs are ready from the kernel */ static void -handle_read() +handle_read(void) { union ccb *ccb_array[MAX_INITIATORS], *ccb; - int ccb_count, i, oo; + int ccb_count, i; ccb_count = read(targ_fd, ccb_array, sizeof(ccb_array)); if (ccb_count <= 0) { @@ -590,7 +594,7 @@ handle_read() /* Queue on the appropriate ATIO */ queue_io(ctio); /* Process any queued completions. */ - oo += run_queue(c_descr->atio); + run_queue(c_descr->atio); break; } case XPT_IMMEDIATE_NOTIFY: @@ -840,7 +844,7 @@ send_ccb(union ccb *ccb, int priority) /* Return a CTIO/descr/buf combo from the freelist or malloc one */ static struct ccb_scsiio * -get_ctio() +get_ctio(void) { struct ccb_scsiio *ctio; struct ctio_descr *c_descr; @@ -938,7 +942,7 @@ get_sim_flags(u_int16_t *flags) } static void -rel_simq() +rel_simq(void) { struct ccb_relsim crs; @@ -953,7 +957,7 @@ rel_simq() /* Cancel all pending CCBs. */ static void -abort_all_pending() +abort_all_pending(void) { struct ccb_abort cab; struct ccb_hdr *ccb_h; @@ -976,7 +980,7 @@ abort_all_pending() } static void -usage() +usage(void) { fprintf(stderr, "Usage: scsi_target [-AdSTY] [-b bufsize] [-c sectorsize]\n" diff --git a/share/examples/scsi_target/scsi_target.h b/share/examples/scsi_target/scsi_target.h index a873c050b7c6..57b6696d2e77 100644 --- a/share/examples/scsi_target/scsi_target.h +++ b/share/examples/scsi_target/scsi_target.h @@ -115,7 +115,11 @@ extern void free_ccb(union ccb *ccb); static __inline u_int min(u_int a, u_int b) { return (a < b ? a : b); } /* Global Data */ -extern int notaio; +extern int notaio; +extern int debug; +extern off_t volume_size; +extern u_int sector_size; +extern size_t buf_size; /* * Compat Defines diff --git a/share/examples/smbfs/Makefile b/share/examples/smbfs/Makefile index e38305148005..6f230bdf8802 100644 --- a/share/examples/smbfs/Makefile +++ b/share/examples/smbfs/Makefile @@ -1,5 +1,4 @@ - -PACKAGE=utilities +PACKAGE= smbutils FILESDIR= ${SHAREDIR}/examples/smbfs FILES= dot.nsmbrc diff --git a/share/examples/smbfs/Makefile.inc b/share/examples/smbfs/Makefile.inc new file mode 100644 index 000000000000..8d89dafa6e25 --- /dev/null +++ b/share/examples/smbfs/Makefile.inc @@ -0,0 +1 @@ +PACKAGE?= smbutils diff --git a/share/examples/smbfs/print/Makefile b/share/examples/smbfs/print/Makefile index 0a0fd500724f..d8be651b2e31 100644 --- a/share/examples/smbfs/print/Makefile +++ b/share/examples/smbfs/print/Makefile @@ -1,5 +1,3 @@ - -PACKAGE=utilities FILESDIR= ${SHAREDIR}/examples/smbfs/print FILES= lj6l ljspool printcap.sample tolj diff --git a/share/examples/sound/basic.c b/share/examples/sound/basic.c deleted file mode 100644 index 83ecbe6ea9a7..000000000000 --- a/share/examples/sound/basic.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2021 Goran Mekić - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include "ossinit.h" - -int -main() -{ - config_t config = { - .device = "/dev/dsp", - .channels = -1, - .format = format, - .frag = -1, - .sample_rate = 48000, - .sample_size = sizeof(sample_t), - .buffer_info.fragments = -1, - .mmap = 0, - }; - - /* Initialize device */ - oss_init(&config); - - /* - * Allocate input and output buffers so that their size match - * frag_size - */ - int ret; - int bytes = config.buffer_info.bytes; - int8_t *ibuf = malloc(bytes); - int8_t *obuf = malloc(bytes); - sample_t *channels = malloc(bytes); - - printf( - "bytes: %d, fragments: %d, fragsize: %d, fragstotal: %d, samples: %d\n", - bytes, - config.buffer_info.fragments, - config.buffer_info.fragsize, - config.buffer_info.fragstotal, - config.sample_count - ); - - /* Minimal engine: read input and copy it to the output */ - for (;;) { - ret = read(config.fd, ibuf, bytes); - if (ret < bytes) { - fprintf( - stderr, - "Requested %d bytes, but read %d!\n", - bytes, - ret - ); - break; - } - oss_split(&config, (sample_t *)ibuf, channels); - /* All processing will happen here */ - oss_merge(&config, channels, (sample_t *)obuf); - ret = write(config.fd, obuf, bytes); - if (ret < bytes) { - fprintf( - stderr, - "Requested %d bytes, but wrote %d!\n", - bytes, - ret - ); - break; - } - } - - /* Cleanup */ - free(channels); - free(obuf); - free(ibuf); - close(config.fd); - return (0); -} diff --git a/share/examples/sound/midi.c b/share/examples/sound/midi.c index 6d6ac9aa0fcd..5b001ba537e5 100644 --- a/share/examples/sound/midi.c +++ b/share/examples/sound/midi.c @@ -2,6 +2,10 @@ * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2022 Goran Mekić + * Copyright (c) 2024 The FreeBSD Foundation + * + * Portions of this software were developed by Christos Margiolis + * <christos@FreeBSD.org> under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,52 +29,61 @@ * SUCH DAMAGE. */ +#include <err.h> +#include <fcntl.h> +#include <stdio.h> +#include <stdlib.h> #include <unistd.h> -#include "ossmidi.h" +#define CMD_MASK 0xF0 +#define CHANNEL_MASK 0x0F +#define NOTE_ON 0x90 +#define NOTE_OFF 0x80 +#define CTL_CHANGE 0xB0 int -main() +main(int argc, char *argv[]) { - midi_event_t event; - midi_config_t midi_config; - int l = -1; - unsigned char raw; + int fd; + unsigned char raw, type, channel, b1, b2; - midi_config.device = "/dev/umidi1.0"; - oss_midi_init(&midi_config); + if ((fd = open("/dev/umidi0.0", O_RDWR)) < 0) + err(1, "Error opening MIDI device"); - while ((l = read(midi_config.fd, &raw, sizeof(raw))) != -1) { - if (!(raw & 0x80)) { + for (;;) { + if (read(fd, &raw, sizeof(raw)) < sizeof(raw)) + err(1, "Error reading command byte"); + if (!(raw & 0x80)) continue; - } - event.type = raw & CMD_MASK; - event.channel = raw & CHANNEL_MASK; - switch (event.type) { + + type = raw & CMD_MASK; + channel = raw & CHANNEL_MASK; + + if (read(fd, &b1, sizeof(b1)) < sizeof(b1)) + err(1, "Error reading byte 1"); + if (read(fd, &b2, sizeof(b2)) < sizeof(b2)) + err(1, "Error reading byte 2"); + + switch (type) { case NOTE_ON: - case NOTE_OFF: - case CONTROLLER_ON: - if ((l = read(midi_config.fd, &(event.note), sizeof(event.note))) == -1) { - perror("Error reading MIDI note"); - exit(1); - } - if ((l = read(midi_config.fd, &(event.velocity), sizeof(event.velocity))) == -1) { - perror("Error reading MIDI velocity"); - exit(1); - } + printf("Channel %d, note on %d, velocity %d\n", + channel, b1, b2); break; - } - switch (event.type) { - case NOTE_ON: case NOTE_OFF: - printf("Channel %d, note %d, velocity %d\n", event.channel, event.note, event.velocity); + printf("Channel %d, note off %d, velocity %d\n", + channel, b1, b2); break; - case CONTROLLER_ON: - printf("Channel %d, controller %d, value %d\n", event.channel, event.controller, event.value); + case CTL_CHANGE: + printf("Channel %d, controller change %d, value %d\n", + channel, b1, b2); break; default: - printf("Unknown event type %d\n", event.type); + printf("Unknown event type %d\n", type); + break; } } - return 0; + + close(fd); + + return (0); } diff --git a/share/examples/sound/README b/share/examples/sound/oss/README index 0188a26348c8..0188a26348c8 100644 --- a/share/examples/sound/README +++ b/share/examples/sound/oss/README diff --git a/share/examples/sound/ossinit.h b/share/examples/sound/oss/audio.c index 83920712286d..4dd3c8b82575 100644 --- a/share/examples/sound/ossinit.h +++ b/share/examples/sound/oss/audio.c @@ -2,6 +2,10 @@ * SPDX-License-Identifier: BSD-2-Clause * * Copyright (c) 2021 Goran Mekić + * Copyright (c) 2024 The FreeBSD Foundation + * + * Portions of this software were developed by Christos Margiolis + * <christos@FreeBSD.org> under sponsorship from the FreeBSD Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -26,6 +30,8 @@ */ #include <sys/soundcard.h> + +#include <err.h> #include <errno.h> #include <fcntl.h> #include <stdio.h> @@ -33,7 +39,6 @@ #include <string.h> #include <unistd.h> - #ifndef SAMPLE_SIZE #define SAMPLE_SIZE 16 #endif @@ -55,8 +60,6 @@ int format = AFMT_S32_NE; /* Not a real value, just silencing * compiler errors */ #endif - - /* * Minimal configuration for OSS * For real world applications, this structure will probably contain many @@ -77,74 +80,69 @@ typedef struct config { audio_buf_info buffer_info; } config_t; - /* - * Error state is indicated by value=-1 in which case application exits - * with error + * Error state is indicated by value=-1 in which case application exits with + * error */ static inline void check_error(const int value, const char *message) { - if (value == -1) { - fprintf(stderr, "OSS error: %s %s\n", message, strerror(errno)); - exit(1); - } + if (value == -1) + err(1, "OSS error: %s\n", message); } - /* Calculate frag by giving it minimal size of buffer */ static inline int size2frag(int x) { int frag = 0; - while ((1 << frag) < x) { + while ((1 << frag) < x) ++frag; - } - return frag; -} + return (frag); +} /* * Split input buffer into channels. Input buffer is in interleaved format - * which means if we have 2 channels (L and R), this is what the buffer of - * 8 samples would contain: L,R,L,R,L,R,L,R. The result are two channels + * which means if we have 2 channels (L and R), this is what the buffer of 8 + * samples would contain: L,R,L,R,L,R,L,R. The result are two channels * containing: L,L,L,L and R,R,R,R. */ -void +static void oss_split(config_t *config, sample_t *input, sample_t *output) { - int channel; - int index; + int channel, index, i; - for (int i = 0; i < config->sample_count; ++i) { + for (i = 0; i < config->sample_count; ++i) { channel = i % config->channels; index = i / config->channels; output[channel * index] = input[i]; } } - /* * Convert channels into interleaved format and place it in output * buffer */ -void +static void oss_merge(config_t *config, sample_t *input, sample_t *output) { - for (int channel = 0; channel < config->channels; ++channel) { - for (int index = 0; index < config->chsamples; ++index) { - output[index * config->channels + channel] = input[channel * index]; + int channel, index; + + for (channel = 0; channel < config->channels; ++channel) { + for (index = 0; index < config->chsamples; ++index) { + output[index * config->channels + channel] = + input[channel * index]; } } } -void +static void oss_init(config_t *config) { - int error; - int tmp; + int error, tmp, min_frag; /* Open the device for read and write */ config->fd = open(config->device, O_RDWR); @@ -158,19 +156,19 @@ oss_init(config_t *config) printf("max_channels: %d\n", config->audio_info.max_channels); printf("latency: %d\n", config->audio_info.latency); printf("handle: %s\n", config->audio_info.handle); - if (config->audio_info.min_rate > config->sample_rate || config->sample_rate > config->audio_info.max_rate) { - fprintf(stderr, "%s doesn't support chosen ", config->device); - fprintf(stderr, "samplerate of %dHz!\n", config->sample_rate); - exit(1); + if (config->audio_info.min_rate > config->sample_rate || + config->sample_rate > config->audio_info.max_rate) { + errx(1, "%s doesn't support chosen samplerate of %dHz!\n", + config->device, config->sample_rate); } - if (config->channels < 1) { + if (config->channels < 1) config->channels = config->audio_info.max_channels; - } /* - * If device is going to be used in mmap mode, disable all format - * conversions. Official OSS documentation states error code should not be - * checked. http://manuals.opensound.com/developer/mmap_test.c.html#LOC10 + * If device is going to be used in mmap mode, disable all format + * conversions. Official OSS documentation states error code should not + * be checked. + * http://manuals.opensound.com/developer/mmap_test.c.html#LOC10 */ if (config->mmap) { tmp = 0; @@ -178,16 +176,16 @@ oss_init(config_t *config) } /* - * Set number of channels. If number of channels is chosen to the value - * near the one wanted, save it in config + * Set number of channels. If number of channels is chosen to the value + * near the one wanted, save it in config */ tmp = config->channels; error = ioctl(config->fd, SNDCTL_DSP_CHANNELS, &tmp); check_error(error, "SNDCTL_DSP_CHANNELS"); - if (tmp != config->channels) { /* or check if tmp is close enough? */ - fprintf(stderr, "%s doesn't support chosen ", config->device); - fprintf(stderr, "channel count of %d", config->channels); - fprintf(stderr, ", set to %d!\n", tmp); + /* Or check if tmp is close enough? */ + if (tmp != config->channels) { + errx(1, "%s doesn't support chosen channel count of %d set " + "to %d!\n", config->device, config->channels, tmp); } config->channels = tmp; @@ -196,8 +194,8 @@ oss_init(config_t *config) error = ioctl(config->fd, SNDCTL_DSP_SETFMT, &tmp); check_error(error, "SNDCTL_DSP_SETFMT"); if (tmp != config->format) { - fprintf(stderr, "%s doesn't support chosen sample format!\n", config->device); - exit(1); + errx(1, "%s doesn't support chosen sample format!\n", + config->device); } /* Most common values for samplerate (in kHz): 44.1, 48, 88.2, 96 */ @@ -208,40 +206,33 @@ oss_init(config_t *config) /* Get and check device capabilities */ error = ioctl(config->fd, SNDCTL_DSP_GETCAPS, &(config->audio_info.caps)); check_error(error, "SNDCTL_DSP_GETCAPS"); - if (!(config->audio_info.caps & PCM_CAP_DUPLEX)) { - fprintf(stderr, "Device doesn't support full duplex!\n"); - exit(1); - } + if (!(config->audio_info.caps & PCM_CAP_DUPLEX)) + errx(1, "Device doesn't support full duplex!\n"); + if (config->mmap) { - if (!(config->audio_info.caps & PCM_CAP_TRIGGER)) { - fprintf(stderr, "Device doesn't support triggering!\n"); - exit(1); - } - if (!(config->audio_info.caps & PCM_CAP_MMAP)) { - fprintf(stderr, "Device doesn't support mmap mode!\n"); - exit(1); - } + if (!(config->audio_info.caps & PCM_CAP_TRIGGER)) + errx(1, "Device doesn't support triggering!\n"); + if (!(config->audio_info.caps & PCM_CAP_MMAP)) + errx(1, "Device doesn't support mmap mode!\n"); } /* - * If desired frag is smaller than minimum, based on number of channels - * and format (size in bits: 8, 16, 24, 32), set that as frag. Buffer size - * is 2^frag, but the real size of the buffer will be read when the - * configuration of the device is successful + * If desired frag is smaller than minimum, based on number of channels + * and format (size in bits: 8, 16, 24, 32), set that as frag. Buffer + * size is 2^frag, but the real size of the buffer will be read when + * the configuration of the device is successful */ - int min_frag = size2frag(config->sample_size * config->channels); + min_frag = size2frag(config->sample_size * config->channels); - if (config->frag < min_frag) { + if (config->frag < min_frag) config->frag = min_frag; - } /* - * Allocate buffer in fragments. Total buffer will be split in number - * of fragments (2 by default) + * Allocate buffer in fragments. Total buffer will be split in number + * of fragments (2 by default) */ - if (config->buffer_info.fragments < 0) { + if (config->buffer_info.fragments < 0) config->buffer_info.fragments = 2; - } tmp = ((config->buffer_info.fragments) << 16) | config->frag; error = ioctl(config->fd, SNDCTL_DSP_SETFRAGMENT, &tmp); check_error(error, "SNDCTL_DSP_SETFRAGMENT"); @@ -250,13 +241,70 @@ oss_init(config_t *config) error = ioctl(config->fd, SNDCTL_DSP_GETOSPACE, &(config->buffer_info)); check_error(error, "SNDCTL_DSP_GETOSPACE"); if (config->buffer_info.bytes < 1) { - fprintf( - stderr, - "OSS buffer error: buffer size can not be %d\n", - config->buffer_info.bytes - ); - exit(1); + errx(1, "OSS buffer error: buffer size can not be %d\n", + config->buffer_info.bytes); } config->sample_count = config->buffer_info.bytes / config->sample_size; config->chsamples = config->sample_count / config->channels; } + +int +main(int argc, char *argv[]) +{ + int ret, bytes; + int8_t *ibuf, *obuf; + config_t config = { + .device = "/dev/dsp", + .channels = -1, + .format = format, + .frag = -1, + .sample_rate = 48000, + .sample_size = sizeof(sample_t), + .buffer_info.fragments = -1, + .mmap = 0, + }; + + /* Initialize device */ + oss_init(&config); + + /* + * Allocate input and output buffers so that their size match frag_size + */ + bytes = config.buffer_info.bytes; + ibuf = malloc(bytes); + obuf = malloc(bytes); + sample_t *channels = malloc(bytes); + + printf("bytes: %d, fragments: %d, fragsize: %d, fragstotal: %d, " + "samples: %d\n", + bytes, config.buffer_info.fragments, + config.buffer_info.fragsize, config.buffer_info.fragstotal, + config.sample_count); + + /* Minimal engine: read input and copy it to the output */ + for (;;) { + ret = read(config.fd, ibuf, bytes); + if (ret < bytes) { + fprintf(stderr, "Requested %d bytes, but read %d!\n", + bytes, ret); + break; + } + oss_split(&config, (sample_t *)ibuf, channels); + /* All processing will happen here */ + oss_merge(&config, channels, (sample_t *)obuf); + ret = write(config.fd, obuf, bytes); + if (ret < bytes) { + fprintf(stderr, "Requested %d bytes, but wrote %d!\n", + bytes, ret); + break; + } + } + + /* Cleanup */ + free(channels); + free(obuf); + free(ibuf); + close(config.fd); + + return (0); +} diff --git a/share/examples/sound/ossmidi.h b/share/examples/sound/ossmidi.h deleted file mode 100644 index 99a6bacffe73..000000000000 --- a/share/examples/sound/ossmidi.h +++ /dev/null @@ -1,63 +0,0 @@ -/* - * SPDX-License-Identifier: BSD-2-Clause - * - * Copyright (c) 2022 Goran Mekić - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -#include <stdlib.h> -#include <stdio.h> -#include <fcntl.h> - -#define CMD_MASK 0xF0 -#define NOTE_ON 0x90 -#define NOTE_OFF 0x80 -#define CHANNEL_MASK 0xF -#define CONTROLLER_ON 0xB0 - -typedef struct midi_event { - unsigned char type; - unsigned char channel; - union { - unsigned char note; - unsigned controller; - }; - union { - unsigned char velocity; - unsigned char value; - }; -} midi_event_t; - -typedef struct midi_config { - char *device; - int fd; -} midi_config_t; - -void -oss_midi_init(midi_config_t *config) -{ - if ((config->fd = open(config->device, O_RDWR)) == -1) { - perror("Error opening MIDI device"); - exit(1); - } -} diff --git a/share/examples/sound/sndstat_nv.c b/share/examples/sound/sndstat_nv.c new file mode 100644 index 000000000000..1056c1f4a08f --- /dev/null +++ b/share/examples/sound/sndstat_nv.c @@ -0,0 +1,206 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2024 The FreeBSD Foundation + * + * This software was developed by Christos Margiolis <christos@FreeBSD.org> + * under sponsorship from the FreeBSD Foundation. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/sndstat.h> +#include <sys/nv.h> + +#include <err.h> +#include <errno.h> +#include <fcntl.h> +#include <stdlib.h> +#include <unistd.h> + +/* + * Example program showcasing how to use sndstat(4)'s nvlist interface, and how + * to fetch all currently supported fields, with the appropriate error checks. + * + * For more detailed information on what each nvlist field represents, please + * read sndstat(4)'s man page. + */ + +int +main(int argc, char *argv[]) +{ + nvlist_t *nvl; + const nvlist_t * const *di; + const nvlist_t * const *cdi; + struct sndstioc_nv_arg arg; + size_t nitems, nchans, i, j; + int fd, pchan, rchan; + + if ((fd = open("/dev/sndstat", O_RDONLY)) < 0) + err(1, "open(/dev/sndstat)"); + + if (ioctl(fd, SNDSTIOC_REFRESH_DEVS, NULL) < 0) + err(1, "ioctl(SNDSTIOC_REFRESH_DEVS)"); + + arg.nbytes = 0; + arg.buf = NULL; + if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg) < 0) + err(1, "ioctl(SNDSTIOC_GET_DEVS#1)"); + + if ((arg.buf = malloc(arg.nbytes)) == NULL) + err(1, "malloc"); + + if (ioctl(fd, SNDSTIOC_GET_DEVS, &arg) < 0) + err(1, "ioctl(SNDSTIOC_GET_DEVS#2)"); + + if ((nvl = nvlist_unpack(arg.buf, arg.nbytes, 0)) == NULL) + err(1, "nvlist_unpack"); + + if (nvlist_empty(nvl) || !nvlist_exists(nvl, SNDST_DSPS)) + errx(1, "no soundcards attached"); + + di = nvlist_get_nvlist_array(nvl, SNDST_DSPS, &nitems); + for (i = 0; i < nitems; i++) { +#define NV(type, item) \ + nvlist_get_ ## type (di[i], SNDST_DSPS_ ## item) + printf("nameunit=%s\n", NV(string, NAMEUNIT)); + printf("\tfrom_user=%d\n", NV(bool, FROM_USER)); + printf("\tdevnode=%s\n", NV(string, DEVNODE)); + printf("\tdesc=%s\n", NV(string, DESC)); + printf("\tprovider=%s\n", NV(string, PROVIDER)); + printf("\tpchan=%d\n", (int)NV(number, PCHAN)); + printf("\trchan=%d\n", (int)NV(number, RCHAN)); + pchan = NV(number, PCHAN); + rchan = NV(number, RCHAN); +#undef NV + + if (pchan && !nvlist_exists(di[i], SNDST_DSPS_INFO_PLAY)) + errx(1, "playback channel list empty"); + if (rchan && !nvlist_exists(di[i], SNDST_DSPS_INFO_REC)) + errx(1, "recording channel list empty"); + +#define NV(type, mode, item) \ + nvlist_get_ ## type (nvlist_get_nvlist(di[i], \ + SNDST_DSPS_INFO_ ## mode), SNDST_DSPS_INFO_ ## item) + if (pchan) { + printf("\tplay_min_rate=%d\n", + (int)NV(number, PLAY, MIN_RATE)); + printf("\tplay_max_rate=%d\n", + (int)NV(number, PLAY, MAX_RATE)); + printf("\tplay_formats=%#08x\n", + (int)NV(number, PLAY, FORMATS)); + printf("\tplay_min_chn=%d\n", + (int)NV(number, PLAY, MIN_CHN)); + printf("\tplay_max_chn=%d\n", + (int)NV(number, PLAY, MAX_CHN)); + } + if (rchan) { + printf("\trec_min_rate=%d\n", + (int)NV(number, REC, MIN_RATE)); + printf("\trec_max_rate=%d\n", + (int)NV(number, REC, MAX_RATE)); + printf("\trec_formats=%#08x\n", + (int)NV(number, REC, FORMATS)); + printf("\trec_min_chn=%d\n", + (int)NV(number, REC, MIN_CHN)); + printf("\trec_max_chn=%d\n", + (int)NV(number, REC, MAX_CHN)); + } +#undef NV + + if (!nvlist_exists(di[i], SNDST_DSPS_PROVIDER_INFO)) + continue; + +#define NV(type, item) \ + nvlist_get_ ## type (nvlist_get_nvlist(di[i], \ + SNDST_DSPS_PROVIDER_INFO), SNDST_DSPS_SOUND4_ ## item) + printf("\tunit=%d\n", (int)NV(number, UNIT)); + printf("\tstatus=%s\n", NV(string, STATUS)); + printf("\tbitperfect=%d\n", NV(bool, BITPERFECT)); + printf("\tpvchan=%d\n", (int)NV(number, PVCHAN)); + printf("\tpvchanrate=%d\n", (int)NV(number, PVCHANRATE)); + printf("\tpvchanformat=%#08x\n", (int)NV(number, PVCHANFORMAT)); + printf("\trvchan=%d\n", (int)NV(number, RVCHAN)); + printf("\trvchanrate=%d\n", (int)NV(number, RVCHANRATE)); + printf("\trvchanformat=%#08x\n", (int)NV(number, RVCHANFORMAT)); +#undef NV + + if (!nvlist_exists(nvlist_get_nvlist(di[i], + SNDST_DSPS_PROVIDER_INFO), SNDST_DSPS_SOUND4_CHAN_INFO)) + errx(1, "channel info list empty"); + + cdi = nvlist_get_nvlist_array( + nvlist_get_nvlist(di[i], SNDST_DSPS_PROVIDER_INFO), + SNDST_DSPS_SOUND4_CHAN_INFO, &nchans); + for (j = 0; j < nchans; j++) { +#define NV(type, item) \ + nvlist_get_ ## type (cdi[j], SNDST_DSPS_SOUND4_CHAN_ ## item) + printf("\tchan=%s\n", NV(string, NAME)); + printf("\t\tparentchan=%s\n", NV(string, PARENTCHAN)); + printf("\t\tunit=%d\n", (int)NV(number, UNIT)); + printf("\t\tcaps=%#08x\n", (int)NV(number, CAPS)); + printf("\t\tlatency=%d\n", (int)NV(number, LATENCY)); + printf("\t\trate=%d\n", (int)NV(number, RATE)); + printf("\t\tformat=%#08x\n", (int)NV(number, FORMAT)); + printf("\t\tpid=%d\n", (int)NV(number, PID)); + printf("\t\tcomm=%s\n", NV(string, COMM)); + printf("\t\tintr=%d\n", (int)NV(number, INTR)); + printf("\t\txruns=%d\n", (int)NV(number, XRUNS)); + printf("\t\tfeedcnt=%d\n", (int)NV(number, FEEDCNT)); + printf("\t\tleftvol=%d\n", (int)NV(number, LEFTVOL)); + printf("\t\trightvol=%d\n", (int)NV(number, RIGHTVOL)); + printf("\t\thwbuf_format=%#08x\n", + (int)NV(number, HWBUF_FORMAT)); + printf("\t\thwbuf_size=%d\n", + (int)NV(number, HWBUF_SIZE)); + printf("\t\thwbuf_blksz=%d\n", + (int)NV(number, HWBUF_BLKSZ)); + printf("\t\thwbuf_blkcnt=%d\n", + (int)NV(number, HWBUF_BLKCNT)); + printf("\t\thwbuf_free=%d\n", + (int)NV(number, HWBUF_FREE)); + printf("\t\thwbuf_ready=%d\n", + (int)NV(number, HWBUF_READY)); + printf("\t\tswbuf_format=%#08x\n", + (int)NV(number, SWBUF_FORMAT)); + printf("\t\tswbuf_size=%d\n", + (int)NV(number, SWBUF_SIZE)); + printf("\t\tswbuf_blksz=%d\n", + (int)NV(number, SWBUF_BLKSZ)); + printf("\t\tswbuf_blkcnt=%d\n", + (int)NV(number, SWBUF_BLKCNT)); + printf("\t\tswbuf_free=%d\n", + (int)NV(number, SWBUF_FREE)); + printf("\t\tswbuf_ready=%d\n", + (int)NV(number, SWBUF_READY)); + printf("\t\tswbuf_feederchain=%s\n", + NV(string, FEEDERCHAIN)); +#undef NV + } + } + + free(arg.buf); + nvlist_destroy(nvl); + close(fd); + + return (0); +} diff --git a/share/examples/tests/Makefile b/share/examples/tests/Makefile index 8f257929d60f..6aea074e2544 100644 --- a/share/examples/tests/Makefile +++ b/share/examples/tests/Makefile @@ -1,4 +1,3 @@ - SUBDIR= tests .PATH: ${SRCTOP}/tests diff --git a/share/examples/tests/tests/Makefile b/share/examples/tests/tests/Makefile index ecaa1b5b9037..4530e341aa37 100644 --- a/share/examples/tests/tests/Makefile +++ b/share/examples/tests/tests/Makefile @@ -1,4 +1,3 @@ - .include <src.opts.mk> # Directory into which the Kyuafile provided by this directory will be diff --git a/share/examples/tests/tests/atf/Makefile b/share/examples/tests/tests/atf/Makefile index 7614767b6e0a..72c2e546d3f9 100644 --- a/share/examples/tests/tests/atf/Makefile +++ b/share/examples/tests/tests/atf/Makefile @@ -1,4 +1,3 @@ - # The release package to use for the tests contained within the directory # # This applies to components which rely on ^/projects/release-pkg support diff --git a/share/examples/tests/tests/plain/Makefile b/share/examples/tests/tests/plain/Makefile index 462324309f6a..40f4e7041b1a 100644 --- a/share/examples/tests/tests/plain/Makefile +++ b/share/examples/tests/tests/plain/Makefile @@ -1,4 +1,3 @@ - # The release package to use for the tests contained within the directory # # This applies to components which rely on ^/projects/release-pkg support diff --git a/share/examples/tests/tests/tap/Makefile b/share/examples/tests/tests/tap/Makefile index 86d3f6805045..af906b309358 100644 --- a/share/examples/tests/tests/tap/Makefile +++ b/share/examples/tests/tests/tap/Makefile @@ -1,4 +1,3 @@ - # The release package to use for the tests contained within the directory # # This applies to components which rely on ^/projects/release-pkg support |