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]
22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
26 * The SPCS status support user utilities
27 * See spcs_s_u.h and the docs subdirectory for functional spec
35 #include <sys/types.h>
38 #include <sys/unistat/spcs_s.h>
39 #include <sys/unistat/spcs_s_u.h>
40 #include <sys/unistat/spcs_s_impl.h>
41 #include <sys/unistat/spcs_errors.h>
42 #include <sys/unistat/spcs_etext.h>
43 #include <sys/unistat/spcs_etrinkets.h>
44 #include <sys/unistat/spcs_dtrinkets.h>
47 * Initialize ioctl status storage to "remove" any old status present
51 spcs_s_uinit(spcs_s_info_t ustatus
)
53 spcs_s_pinfo_t
*p
= (spcs_s_pinfo_t
*)ustatus
;
54 p
->major
= SPCS_S_MAJOR_REV
;
55 p
->minor
= SPCS_S_MINOR_REV
;
62 * Create and initialize local status. Call this prior to invoking
69 static int need_to_bind
= 1;
70 spcs_s_pinfo_t
*ustatus
;
73 (void) setlocale(LC_ALL
, "");
74 (void) bindtextdomain("unistat", LIBUNISTAT_LOCALE
);
78 ustatus
= (spcs_s_pinfo_t
*)malloc(sizeof (spcs_s_pinfo_t
));
79 spcs_s_uinit((spcs_s_info_t
)ustatus
);
81 return ((spcs_s_info_t
)ustatus
);
85 * Return the idata index of the last status code in the array (i.e.
86 * the "youngest" code present). The assumption is that the caller has
87 * checked to see that pcount is nonzero.
91 last_code_idx(spcs_s_pinfo_t
*p
)
96 while (idx
< p
->icount
) {
98 idx
+= p
->idata
[idx
].f
.sup_count
+ 1;
104 * Return a string with the module label and error message text or NULL
109 spcs_s_string(spcs_s_info_t ustatus
, char *msg
)
111 spcs_s_pinfo_t
*p
= (spcs_s_pinfo_t
*)ustatus
;
116 char *sp
[SPCS_S_MAXSUPP
];
117 char mtemp
[SPCS_S_MAXLINE
];
120 idx
= last_code_idx(p
);
121 strcpy(msg
, module_names
[p
->idata
[idx
].f
.module
]);
123 sup
= p
->idata
[idx
].f
.sup_count
;
125 if (p
->idata
[idx
].f
.module
)
127 * The gettext formal parameter is a const char*
128 * I guess the gettext creator couldn't imagine
129 * needing a variable string. If there is an underlying
130 * routine that can be called it should be used.
131 * otherwise there will be a compiler warning about this
134 format
= (char *)dgettext("unistat",
135 SPCS_S_MSG
[p
->idata
[idx
].f
.module
]
136 [p
->idata
[idx
].f
.code
]);
139 format
= strerror(p
->idata
[idx
].f
.code
);
142 * step across the status code to the first supplemental data
149 * Initialize the array with empty string pointers so we don't
150 * seg fault if there are actually fewer values than "%s"
151 * format descriptors.
153 for (s
= 0; s
< SPCS_S_MAXSUPP
; s
++)
157 * Walk through the supplemental value descriptors and build
158 * an array of string pointers.
161 for (s
= 0; s
< sup
; s
++) {
162 sp
[s
] = (char *)(p
->sdata
+ p
->idata
[idx
+s
].su
.offset
);
166 * Now format the message. The unused string pointers will be
168 * NOTE: Any change to SPCS_S_MAXSUPP requires a change to
172 sprintf(mtemp
, format
, sp
[0], sp
[1], sp
[2], sp
[3], sp
[4], sp
[5],
175 /* remove the code and its supplemental info */
177 p
->icount
-= (sup
+ 1);
179 return (strcat(msg
, mtemp
));
189 spcs_s_report(spcs_s_info_t ustatus
, FILE *fd
)
191 spcs_s_pinfo_t
*p
= (spcs_s_pinfo_t
*)ustatus
;
192 short saved_count
= p
->icount
;
193 char msg
[SPCS_S_MAXTEXT
];
199 if (sp
= spcs_s_string(ustatus
, msg
))
200 fprintf(fd
, "%s\n", sp
);
201 else if (first_time
&& (errno
> 0)) {
203 * This covers the case where Solaris aborted the
204 * operation or the ioctl service code got an EFAULT
205 * or something from copyin or couldn't allocate the
206 * kernel status structure. If errno > 0 but not a
207 * valid Solaris error code the extended error is
208 * decoded and printed.
210 se
= strerror(errno
);
212 fprintf(fd
, "%s\n", se
);
214 spcs_s_udata_t spcs_errno
;
216 spcs_errno
.i
= errno
;
217 fprintf(fd
, "%s: %s\n",
218 module_names
[spcs_errno
.f
.module
],
220 SPCS_S_MSG
[spcs_errno
.f
.module
]
221 [spcs_errno
.f
.code
]));
228 p
->icount
= saved_count
;
233 spcs_s_exception(spcs_s_info_t ustatus
, void *env
)
238 * Release (free) ioctl status storage.
242 spcs_s_ufree(spcs_s_info_t
*ustatus_a
)
244 free((void *)*ustatus_a
);