1/*- 2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD 3 * 4 * Copyright (C) 2018 Universita` di Pisa 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 * 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 18 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 21 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 23 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 25 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 26 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 27 * SUCH DAMAGE. 28 * 29 * $FreeBSD$ 30 */ 31 32#include <sys/types.h> 33#include <sys/stat.h> 34#include <sys/ioctl.h> 35#include <sys/mman.h> 36#include <fcntl.h> 37#include <stdlib.h> 38#include <stdio.h> 39#include <stdarg.h> 40#include <string.h> 41#include <unistd.h> 42#include <errno.h> 43#include <net/netmap_user.h> 44#define LIBNETMAP_NOTHREADSAFE 45#include "libnetmap.h" 46 47static void 48nmctx_default_error(struct nmctx *ctx, const char *errmsg) 49{ 50 fprintf(stderr, "%s\n", errmsg); 51} 52 53static void * 54nmctx_default_malloc(struct nmctx *ctx, size_t sz) 55{ 56 (void)ctx; 57 return malloc(sz); 58} 59 60static void 61nmctx_default_free(struct nmctx *ctx, void *p) 62{ 63 (void)ctx; 64 free(p); 65} 66 67static struct nmctx nmctx_global = { 68 .verbose = 1, 69 .error = nmctx_default_error, 70 .malloc = nmctx_default_malloc, 71 .free = nmctx_default_free, 72 .lock = NULL, 73}; 74 75static struct nmctx *nmctx_default = &nmctx_global; 76 77struct nmctx * 78nmctx_get(void) 79{ 80 return nmctx_default; 81} 82 83struct nmctx * 84nmctx_set_default(struct nmctx *ctx) 85{ 86 struct nmctx *old = nmctx_default; 87 nmctx_default = ctx; 88 return old; 89} 90 91#define MAXERRMSG 1000 92void 93nmctx_ferror(struct nmctx *ctx, const char *fmt, ...) 94{ 95 char errmsg[MAXERRMSG]; 96 va_list ap; 97 int rv; 98 99 if (!ctx->verbose) 100 return; 101 102 va_start(ap, fmt); 103 rv = vsnprintf(errmsg, MAXERRMSG, fmt, ap); 104 va_end(ap); 105 106 if (rv > 0) { 107 if (rv < MAXERRMSG) { 108 ctx->error(ctx, errmsg); 109 } else { 110 ctx->error(ctx, "error message too long"); 111 } 112 } else { 113 ctx->error(ctx, "internal error"); 114 } 115} 116 117void * 118nmctx_malloc(struct nmctx *ctx, size_t sz) 119{ 120 return ctx->malloc(ctx, sz); 121} 122 123void 124nmctx_free(struct nmctx *ctx, void *p) 125{ 126 ctx->free(ctx, p); 127} 128 129void 130nmctx_lock(struct nmctx *ctx) 131{ 132 if (ctx->lock != NULL) 133 ctx->lock(ctx, 1); 134} 135 136void 137nmctx_unlock(struct nmctx *ctx) 138{ 139 if (ctx->lock != NULL) 140 ctx->lock(ctx, 0); 141} 142