4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
26 #include <sys/types.h>
40 #include <scsi/libsmp.h>
41 #include <scsi/libsmp_plugin.h>
44 __thread smp_errno_t _smp_errno
;
45 __thread
char _smp_errmsg
[LIBSMP_ERRMSGLEN
];
48 smp_assert(const char *expr
, const char *file
, int line
)
53 len
= snprintf(NULL
, 0,
54 "ABORT: \"%s\", line %d: assertion failed: %s\n", file
, line
, expr
);
56 msg
= alloca(len
+ 1);
58 (void) snprintf(msg
, len
+ 1,
59 "ABORT: \"%s\", line %d: assertion failed: %s\n", file
, line
, expr
);
61 (void) write(STDERR_FILENO
, msg
, strlen(msg
));
71 smp_set_errno(smp_errno_t err
)
74 _smp_errmsg
[0] = '\0';
80 * Internal routine for setting both _smp_errno and _smp_errmsg. We save
81 * and restore the UNIX errno across this routing so the caller can use either
82 * smp_set_errno(), smp_error(), or smp_verror() without this value changing.
85 smp_verror(smp_errno_t err
, const char *fmt
, va_list ap
)
91 * To allow the existing error message to itself be used in an error
92 * message, we put the new error message into a buffer on the stack,
93 * and then copy it into lsh_errmsg. We also need to set the errno,
94 * but because the call to smp_set_errno() is destructive to
95 * lsh_errmsg, we do this after we print into our temporary buffer
96 * (in case _smp_errmsg is part of the error message) and before we
97 * copy the temporary buffer on to _smp_errmsg (to prevent our new
98 * message from being nuked by the call to smp_set_errno()).
100 errmsg
= alloca(sizeof (_smp_errmsg
));
101 (void) vsnprintf(errmsg
, sizeof (_smp_errmsg
), fmt
, ap
);
102 (void) smp_set_errno(err
);
106 if (n
!= 0 && errmsg
[n
- 1] == '\n')
107 errmsg
[n
- 1] = '\0';
109 bcopy(errmsg
, _smp_errmsg
, n
+ 1);
115 smp_error(smp_errno_t err
, const char *fmt
, ...)
120 return (smp_set_errno(err
));
123 err
= smp_verror(err
, fmt
, ap
);
138 if (_smp_errmsg
[0] == '\0')
139 (void) strlcpy(_smp_errmsg
, smp_strerror(_smp_errno
),
140 sizeof (_smp_errmsg
));
142 return (_smp_errmsg
);
147 smp_alloc(size_t size
)
152 (void) smp_set_errno(ESMP_ZERO_LENGTH
);
156 if ((mem
= malloc(size
)) == NULL
)
157 (void) smp_set_errno(ESMP_NOMEM
);
163 smp_zalloc(size_t size
)
167 if ((mem
= smp_alloc(size
)) == NULL
)
176 smp_strdup(const char *str
)
178 size_t len
= strlen(str
);
179 char *dup
= smp_alloc(len
+ 1);
184 return (strcpy(dup
, str
));
194 * Trim any leading and/or trailing spaces from the fixed-length string
195 * argument and return a newly-allocated copy of it.
198 smp_trim_strdup(const char *str
, size_t len
)
203 for (p
= str
; p
- str
< len
&& isspace(*p
); p
++)
211 for (str
= p
+ len
- 1; str
> p
&& isspace(*str
); str
--, len
--)
217 r
= smp_alloc(len
+ 1);
228 smp_init(int version
)
230 if (version
!= LIBSMP_VERSION
)
231 return (smp_error(ESMP_VERSION
,
232 "library version %d does not match requested version %d",
233 LIBSMP_VERSION
, version
));