Changes in v9fs broke pipesrv. Fix it.
[npfs.git] / libnpfs / error.c
blobb91583f0689024d2253d168f50490d534e2932fc
1 /*
2 * Copyright (C) 2006 by Latchesar Ionkov <lucho@ionkov.net>
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * LATCHESAR IONKOV AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
19 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
20 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
23 #include <stdlib.h>
24 #include <stdio.h>
25 #include <string.h>
26 #include <errno.h>
27 #include <stdarg.h>
28 #include "npfs.h"
30 typedef struct Nperror Nperror;
31 struct Nperror {
32 char* ename;
33 int ecode;
36 static pthread_key_t error_key;
37 static pthread_once_t error_once = PTHREAD_ONCE_INIT;
39 static void
40 np_destroy_error(void *a)
42 Nperror *err;
44 err = a;
45 free(err->ename);
46 free(err);
49 void *
50 np_malloc(int size)
52 void *ret;
54 ret = malloc(size);
55 if (!ret)
56 np_werror(Ennomem, ENOMEM);
58 return ret;
61 static void
62 np_init_error_key(void)
64 pthread_key_create(&error_key, np_destroy_error);
67 static void
68 np_vwerror(Nperror *err, char *ename, int ecode, va_list ap)
70 if (err->ename && err->ename != Ennomem) {
71 free(err->ename);
72 err->ename = NULL;
75 err->ecode = ecode;
76 if (ename) {
77 /* RHEL5 has issues
78 vasprintf(&err->ename, ename, ap);
80 err->ename = malloc(1024);
81 if (!err->ename) {
82 err->ename = Ennomem;
83 err->ecode = ENOMEM;
84 } else
85 vsnprintf(err->ename, 1024, ename, ap);
88 void
89 np_werror(char *ename, int ecode, ...)
91 va_list ap;
92 Nperror *err;
94 pthread_once(&error_once, np_init_error_key);
95 err = pthread_getspecific(error_key);
96 if (!err) {
97 err = malloc(sizeof(*err));
98 if (!err) {
99 fprintf(stderr, "not enough memory\n");
100 return;
103 err->ename = NULL;
104 err->ecode = 0;
105 pthread_setspecific(error_key, err);
108 va_start(ap, ecode);
109 np_vwerror(err, ename, ecode, ap);
110 va_end(ap);
113 void
114 np_rerror(char **ename, int *ecode)
116 Nperror *err;
118 pthread_once(&error_once, np_init_error_key);
119 err = pthread_getspecific(error_key);
120 if (err) {
121 *ename = err->ename;
122 *ecode = err->ecode;
123 } else {
124 *ename = NULL;
125 *ecode = 0;
130 np_haserror()
132 Nperror *err;
134 pthread_once(&error_once, np_init_error_key);
135 err = pthread_getspecific(error_key);
136 if (err)
137 return err->ename != NULL;
138 else
139 return 0;
142 #ifdef _WIN32
143 void
144 np_uerror(int ecode)
146 char buf[100];
148 // XXX?
149 snprintf(buf, sizeof buf, "error %d\n", ecode);
150 np_werror(buf, ecode);
153 void
154 np_suerror(char *s, int ecode)
156 char buf[512];
158 // XXX?
159 snprintf(buf, sizeof buf, "error %d\n", ecode);
160 snprintf(buf, sizeof(buf), "%s: error %d", s, ecode);
161 np_werror(buf, ecode);
164 #else // !_WIN32
165 void
166 np_uerror(int ecode)
168 char buf[256];
170 strerror_r(ecode, buf, sizeof(buf));
171 np_werror(buf, ecode);
174 void
175 np_suerror(char *s, int ecode)
177 char err[256];
178 char buf[512];
180 strerror_r(ecode, err, sizeof(err));
181 snprintf(buf, sizeof(buf), "%s: %s", s, err);
182 np_werror(buf, ecode);
184 #endif