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 47 static void 48 nmctx_default_error(struct nmctx *ctx, const char *errmsg) 49 { 50 fprintf(stderr, "%s\n", errmsg); 51 } 52 53 static void * 54 nmctx_default_malloc(struct nmctx *ctx, size_t sz) 55 { 56 (void)ctx; 57 return malloc(sz); 58 } 59 60 static void 61 nmctx_default_free(struct nmctx *ctx, void *p) 62 { 63 (void)ctx; 64 free(p); 65 } 66 67 static 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 75 static struct nmctx *nmctx_default = &nmctx_global; 76 77 struct nmctx * 78 nmctx_get(void) 79 { 80 return nmctx_default; 81 } 82 83 struct nmctx * 84 nmctx_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 92 void 93 nmctx_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 117 void * 118 nmctx_malloc(struct nmctx *ctx, size_t sz) 119 { 120 return ctx->malloc(ctx, sz); 121 } 122 123 void 124 nmctx_free(struct nmctx *ctx, void *p) 125 { 126 ctx->free(ctx, p); 127 } 128 129 void 130 nmctx_lock(struct nmctx *ctx) 131 { 132 if (ctx->lock != NULL) 133 ctx->lock(ctx, 1); 134 } 135 136 void 137 nmctx_unlock(struct nmctx *ctx) 138 { 139 if (ctx->lock != NULL) 140 ctx->lock(ctx, 0); 141 } 142