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