Print this page
INTRO-118 enabling USDT probes in zones should be more scalable
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/libdtrace/common/dt_program.c
+++ new/usr/src/lib/libdtrace/common/dt_program.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
↓ open down ↓ |
14 lines elided |
↑ open up ↑ |
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21
22 22 /*
23 23 * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
24 24 * Copyright (c) 2011 by Delphix. All rights reserved.
25 + * Copyright (c) 2011, Joyent, Inc. All rights reserved.
25 26 */
26 27
27 28 #include <unistd.h>
28 29 #include <strings.h>
29 30 #include <stdlib.h>
30 31 #include <errno.h>
31 32 #include <assert.h>
32 33 #include <ctype.h>
33 34 #include <alloca.h>
34 35
35 36 #include <dt_impl.h>
36 37 #include <dt_program.h>
37 38 #include <dt_printf.h>
38 39 #include <dt_provider.h>
39 40
40 41 dtrace_prog_t *
41 42 dt_program_create(dtrace_hdl_t *dtp)
42 43 {
43 44 dtrace_prog_t *pgp = dt_zalloc(dtp, sizeof (dtrace_prog_t));
44 45
45 46 if (pgp != NULL) {
46 47 dt_list_append(&dtp->dt_programs, pgp);
47 48 } else {
48 49 (void) dt_set_errno(dtp, EDT_NOMEM);
49 50 return (NULL);
50 51 }
51 52
52 53 /*
53 54 * By default, programs start with DOF version 1 so that output files
54 55 * containing DOF are backward compatible. If a program requires new
55 56 * DOF features, the version is increased as needed.
56 57 */
57 58 pgp->dp_dofversion = DOF_VERSION_1;
58 59
59 60 return (pgp);
60 61 }
61 62
62 63 void
63 64 dt_program_destroy(dtrace_hdl_t *dtp, dtrace_prog_t *pgp)
64 65 {
65 66 dt_stmt_t *stp, *next;
66 67 uint_t i;
67 68
68 69 for (stp = dt_list_next(&pgp->dp_stmts); stp != NULL; stp = next) {
69 70 next = dt_list_next(stp);
70 71 dtrace_stmt_destroy(dtp, stp->ds_desc);
71 72 dt_free(dtp, stp);
72 73 }
73 74
74 75 for (i = 0; i < pgp->dp_xrefslen; i++)
75 76 dt_free(dtp, pgp->dp_xrefs[i]);
76 77
77 78 dt_free(dtp, pgp->dp_xrefs);
78 79 dt_list_delete(&dtp->dt_programs, pgp);
79 80 dt_free(dtp, pgp);
80 81 }
81 82
82 83 /*ARGSUSED*/
83 84 void
84 85 dtrace_program_info(dtrace_hdl_t *dtp, dtrace_prog_t *pgp,
85 86 dtrace_proginfo_t *pip)
86 87 {
87 88 dt_stmt_t *stp;
88 89 dtrace_actdesc_t *ap;
89 90 dtrace_ecbdesc_t *last = NULL;
90 91
91 92 if (pip == NULL)
92 93 return;
93 94
94 95 bzero(pip, sizeof (dtrace_proginfo_t));
95 96
96 97 if (dt_list_next(&pgp->dp_stmts) != NULL) {
97 98 pip->dpi_descattr = _dtrace_maxattr;
98 99 pip->dpi_stmtattr = _dtrace_maxattr;
99 100 } else {
100 101 pip->dpi_descattr = _dtrace_defattr;
101 102 pip->dpi_stmtattr = _dtrace_defattr;
102 103 }
103 104
104 105 for (stp = dt_list_next(&pgp->dp_stmts); stp; stp = dt_list_next(stp)) {
105 106 dtrace_ecbdesc_t *edp = stp->ds_desc->dtsd_ecbdesc;
106 107
107 108 if (edp == last)
108 109 continue;
109 110 last = edp;
110 111
111 112 pip->dpi_descattr =
112 113 dt_attr_min(stp->ds_desc->dtsd_descattr, pip->dpi_descattr);
113 114
114 115 pip->dpi_stmtattr =
115 116 dt_attr_min(stp->ds_desc->dtsd_stmtattr, pip->dpi_stmtattr);
116 117
117 118 /*
118 119 * If there aren't any actions, account for the fact that
119 120 * recording the epid will generate a record.
120 121 */
121 122 if (edp->dted_action == NULL)
122 123 pip->dpi_recgens++;
123 124
124 125 for (ap = edp->dted_action; ap != NULL; ap = ap->dtad_next) {
125 126 if (ap->dtad_kind == DTRACEACT_SPECULATE) {
126 127 pip->dpi_speculations++;
127 128 continue;
128 129 }
129 130
130 131 if (DTRACEACT_ISAGG(ap->dtad_kind)) {
131 132 pip->dpi_recgens -= ap->dtad_arg;
132 133 pip->dpi_aggregates++;
133 134 continue;
134 135 }
135 136
136 137 if (DTRACEACT_ISDESTRUCTIVE(ap->dtad_kind))
137 138 continue;
138 139
139 140 if (ap->dtad_kind == DTRACEACT_DIFEXPR &&
140 141 ap->dtad_difo->dtdo_rtype.dtdt_kind ==
141 142 DIF_TYPE_CTF &&
142 143 ap->dtad_difo->dtdo_rtype.dtdt_size == 0)
143 144 continue;
144 145
145 146 pip->dpi_recgens++;
146 147 }
↓ open down ↓ |
112 lines elided |
↑ open up ↑ |
147 148 }
148 149 }
149 150
150 151 int
151 152 dtrace_program_exec(dtrace_hdl_t *dtp, dtrace_prog_t *pgp,
152 153 dtrace_proginfo_t *pip)
153 154 {
154 155 void *dof;
155 156 int n, err;
156 157
158 + if (!dtp->dt_optset) {
159 + /*
160 + * If we have not yet ioctl'd down our options DOF, we'll
161 + * do that before enabling any probes (some options will
162 + * affect which probes we match).
163 + */
164 + if ((dof = dtrace_getopt_dof(dtp)) == NULL)
165 + return (-1); /* dt_errno has been set for us */
166 +
167 + err = dt_ioctl(dtp, DTRACEIOC_ENABLE, dof);
168 + dtrace_dof_destroy(dtp, dof);
169 +
170 + if (err == -1)
171 + return (-1);
172 +
173 + dtp->dt_optset = B_TRUE;
174 + }
175 +
157 176 dtrace_program_info(dtp, pgp, pip);
158 177
159 178 if ((dof = dtrace_dof_create(dtp, pgp, DTRACE_D_STRIP)) == NULL)
160 179 return (-1);
161 180
162 181 n = dt_ioctl(dtp, DTRACEIOC_ENABLE, dof);
163 182 dtrace_dof_destroy(dtp, dof);
164 183
165 184 if (n == -1) {
166 185 switch (errno) {
167 186 case EINVAL:
168 187 err = EDT_DIFINVAL;
169 188 break;
170 189 case EFAULT:
171 190 err = EDT_DIFFAULT;
172 191 break;
173 192 case E2BIG:
174 193 err = EDT_DIFSIZE;
175 194 break;
176 195 case EBUSY:
177 196 err = EDT_ENABLING_ERR;
178 197 break;
179 198 default:
180 199 err = errno;
181 200 }
182 201
183 202 return (dt_set_errno(dtp, err));
184 203 }
185 204
186 205 if (pip != NULL)
187 206 pip->dpi_matches += n;
188 207
189 208 return (0);
190 209 }
191 210
192 211 static void
193 212 dt_ecbdesc_hold(dtrace_ecbdesc_t *edp)
194 213 {
195 214 edp->dted_refcnt++;
196 215 }
197 216
198 217 void
199 218 dt_ecbdesc_release(dtrace_hdl_t *dtp, dtrace_ecbdesc_t *edp)
200 219 {
201 220 if (--edp->dted_refcnt > 0)
202 221 return;
203 222
204 223 dt_difo_free(dtp, edp->dted_pred.dtpdd_difo);
205 224 assert(edp->dted_action == NULL);
206 225 dt_free(dtp, edp);
207 226 }
208 227
209 228 dtrace_ecbdesc_t *
210 229 dt_ecbdesc_create(dtrace_hdl_t *dtp, const dtrace_probedesc_t *pdp)
211 230 {
212 231 dtrace_ecbdesc_t *edp;
213 232
214 233 if ((edp = dt_zalloc(dtp, sizeof (dtrace_ecbdesc_t))) == NULL) {
215 234 (void) dt_set_errno(dtp, EDT_NOMEM);
216 235 return (NULL);
217 236 }
218 237
219 238 edp->dted_probe = *pdp;
220 239 dt_ecbdesc_hold(edp);
221 240 return (edp);
222 241 }
223 242
224 243 dtrace_stmtdesc_t *
225 244 dtrace_stmt_create(dtrace_hdl_t *dtp, dtrace_ecbdesc_t *edp)
226 245 {
227 246 dtrace_stmtdesc_t *sdp;
228 247
229 248 if ((sdp = dt_zalloc(dtp, sizeof (dtrace_stmtdesc_t))) == NULL)
230 249 return (NULL);
231 250
232 251 dt_ecbdesc_hold(edp);
233 252 sdp->dtsd_ecbdesc = edp;
234 253 sdp->dtsd_descattr = _dtrace_defattr;
235 254 sdp->dtsd_stmtattr = _dtrace_defattr;
236 255
237 256 return (sdp);
238 257 }
239 258
240 259 dtrace_actdesc_t *
241 260 dtrace_stmt_action(dtrace_hdl_t *dtp, dtrace_stmtdesc_t *sdp)
242 261 {
243 262 dtrace_actdesc_t *new;
244 263 dtrace_ecbdesc_t *edp = sdp->dtsd_ecbdesc;
245 264
246 265 if ((new = dt_alloc(dtp, sizeof (dtrace_actdesc_t))) == NULL)
247 266 return (NULL);
248 267
249 268 if (sdp->dtsd_action_last != NULL) {
250 269 assert(sdp->dtsd_action != NULL);
251 270 assert(sdp->dtsd_action_last->dtad_next == NULL);
252 271 sdp->dtsd_action_last->dtad_next = new;
253 272 } else {
254 273 dtrace_actdesc_t *ap = edp->dted_action;
255 274
256 275 assert(sdp->dtsd_action == NULL);
257 276 sdp->dtsd_action = new;
258 277
259 278 while (ap != NULL && ap->dtad_next != NULL)
260 279 ap = ap->dtad_next;
261 280
262 281 if (ap == NULL)
263 282 edp->dted_action = new;
264 283 else
265 284 ap->dtad_next = new;
266 285 }
267 286
268 287 sdp->dtsd_action_last = new;
269 288 bzero(new, sizeof (dtrace_actdesc_t));
270 289 new->dtad_uarg = (uintptr_t)sdp;
271 290
272 291 return (new);
273 292 }
274 293
275 294 int
276 295 dtrace_stmt_add(dtrace_hdl_t *dtp, dtrace_prog_t *pgp, dtrace_stmtdesc_t *sdp)
277 296 {
278 297 dt_stmt_t *stp = dt_alloc(dtp, sizeof (dt_stmt_t));
279 298
280 299 if (stp == NULL)
281 300 return (-1); /* errno is set for us */
282 301
283 302 dt_list_append(&pgp->dp_stmts, stp);
284 303 stp->ds_desc = sdp;
285 304
286 305 return (0);
287 306 }
288 307
289 308 int
290 309 dtrace_stmt_iter(dtrace_hdl_t *dtp, dtrace_prog_t *pgp,
291 310 dtrace_stmt_f *func, void *data)
292 311 {
293 312 dt_stmt_t *stp, *next;
294 313 int status = 0;
295 314
296 315 for (stp = dt_list_next(&pgp->dp_stmts); stp != NULL; stp = next) {
297 316 next = dt_list_next(stp);
298 317 if ((status = func(dtp, pgp, stp->ds_desc, data)) != 0)
299 318 break;
300 319 }
301 320
302 321 return (status);
303 322 }
304 323
305 324 void
306 325 dtrace_stmt_destroy(dtrace_hdl_t *dtp, dtrace_stmtdesc_t *sdp)
307 326 {
308 327 dtrace_ecbdesc_t *edp = sdp->dtsd_ecbdesc;
309 328
310 329 /*
311 330 * We need to remove any actions that we have on this ECB, and
312 331 * remove our hold on the ECB itself.
313 332 */
314 333 if (sdp->dtsd_action != NULL) {
315 334 dtrace_actdesc_t *last = sdp->dtsd_action_last;
316 335 dtrace_actdesc_t *ap, *next;
317 336
318 337 assert(last != NULL);
319 338
320 339 for (ap = edp->dted_action; ap != NULL; ap = ap->dtad_next) {
321 340 if (ap == sdp->dtsd_action)
322 341 break;
323 342
324 343 if (ap->dtad_next == sdp->dtsd_action)
325 344 break;
326 345 }
327 346
328 347 assert(ap != NULL);
329 348
330 349 if (ap == edp->dted_action)
331 350 edp->dted_action = last->dtad_next;
332 351 else
333 352 ap->dtad_next = last->dtad_next;
334 353
335 354 /*
336 355 * We have now removed our action list from its ECB; we can
337 356 * safely destroy the list.
338 357 */
339 358 last->dtad_next = NULL;
340 359
341 360 for (ap = sdp->dtsd_action; ap != NULL; ap = next) {
342 361 assert(ap->dtad_uarg == (uintptr_t)sdp);
343 362 dt_difo_free(dtp, ap->dtad_difo);
344 363 next = ap->dtad_next;
345 364 dt_free(dtp, ap);
346 365 }
347 366 }
348 367
349 368 if (sdp->dtsd_fmtdata != NULL)
350 369 dt_printf_destroy(sdp->dtsd_fmtdata);
351 370 dt_free(dtp, sdp->dtsd_strdata);
352 371
353 372 dt_ecbdesc_release(dtp, sdp->dtsd_ecbdesc);
354 373 dt_free(dtp, sdp);
355 374 }
356 375
357 376 typedef struct dt_header_info {
358 377 dtrace_hdl_t *dthi_dtp; /* consumer handle */
359 378 FILE *dthi_out; /* output file */
360 379 char *dthi_pmname; /* provider macro name */
361 380 char *dthi_pfname; /* provider function name */
362 381 int dthi_empty; /* should we generate empty macros */
363 382 } dt_header_info_t;
364 383
365 384 static void
366 385 dt_header_fmt_macro(char *buf, const char *str)
367 386 {
368 387 for (;;) {
369 388 if (islower(*str)) {
370 389 *buf++ = *str++ + 'A' - 'a';
371 390 } else if (*str == '-') {
372 391 *buf++ = '_';
373 392 str++;
374 393 } else if (*str == '.') {
375 394 *buf++ = '_';
376 395 str++;
377 396 } else if ((*buf++ = *str++) == '\0') {
378 397 break;
379 398 }
380 399 }
381 400 }
382 401
383 402 static void
384 403 dt_header_fmt_func(char *buf, const char *str)
385 404 {
386 405 for (;;) {
387 406 if (*str == '-') {
388 407 *buf++ = '_';
389 408 *buf++ = '_';
390 409 str++;
391 410 } else if ((*buf++ = *str++) == '\0') {
392 411 break;
393 412 }
394 413 }
395 414 }
396 415
397 416 /*ARGSUSED*/
398 417 static int
399 418 dt_header_decl(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
400 419 {
401 420 dt_header_info_t *infop = data;
402 421 dtrace_hdl_t *dtp = infop->dthi_dtp;
403 422 dt_probe_t *prp = idp->di_data;
404 423 dt_node_t *dnp;
405 424 char buf[DT_TYPE_NAMELEN];
406 425 char *fname;
407 426 const char *p;
408 427 int i;
409 428
410 429 p = prp->pr_name;
411 430 for (i = 0; (p = strchr(p, '-')) != NULL; i++)
412 431 p++;
413 432
414 433 fname = alloca(strlen(prp->pr_name) + 1 + i);
415 434 dt_header_fmt_func(fname, prp->pr_name);
416 435
417 436 if (fprintf(infop->dthi_out, "extern void __dtrace_%s___%s(",
418 437 infop->dthi_pfname, fname) < 0)
419 438 return (dt_set_errno(dtp, errno));
420 439
421 440 for (dnp = prp->pr_nargs, i = 0; dnp != NULL; dnp = dnp->dn_list, i++) {
422 441 if (fprintf(infop->dthi_out, "%s",
423 442 ctf_type_name(dnp->dn_ctfp, dnp->dn_type,
424 443 buf, sizeof (buf))) < 0)
425 444 return (dt_set_errno(dtp, errno));
426 445
427 446 if (i + 1 != prp->pr_nargc &&
428 447 fprintf(infop->dthi_out, ", ") < 0)
429 448 return (dt_set_errno(dtp, errno));
430 449 }
431 450
432 451 if (i == 0 && fprintf(infop->dthi_out, "void") < 0)
433 452 return (dt_set_errno(dtp, errno));
434 453
435 454 if (fprintf(infop->dthi_out, ");\n") < 0)
436 455 return (dt_set_errno(dtp, errno));
437 456
438 457 if (fprintf(infop->dthi_out,
439 458 "#ifndef\t__sparc\n"
440 459 "extern int __dtraceenabled_%s___%s(void);\n"
441 460 "#else\n"
442 461 "extern int __dtraceenabled_%s___%s(long);\n"
443 462 "#endif\n",
444 463 infop->dthi_pfname, fname, infop->dthi_pfname, fname) < 0)
445 464 return (dt_set_errno(dtp, errno));
446 465
447 466 return (0);
448 467 }
449 468
450 469 /*ARGSUSED*/
451 470 static int
452 471 dt_header_probe(dt_idhash_t *dhp, dt_ident_t *idp, void *data)
453 472 {
454 473 dt_header_info_t *infop = data;
455 474 dtrace_hdl_t *dtp = infop->dthi_dtp;
456 475 dt_probe_t *prp = idp->di_data;
457 476 char *mname, *fname;
458 477 const char *p;
459 478 int i;
460 479
461 480 p = prp->pr_name;
462 481 for (i = 0; (p = strchr(p, '-')) != NULL; i++)
463 482 p++;
464 483
465 484 mname = alloca(strlen(prp->pr_name) + 1);
466 485 dt_header_fmt_macro(mname, prp->pr_name);
467 486
468 487 fname = alloca(strlen(prp->pr_name) + 1 + i);
469 488 dt_header_fmt_func(fname, prp->pr_name);
470 489
471 490 if (fprintf(infop->dthi_out, "#define\t%s_%s(",
472 491 infop->dthi_pmname, mname) < 0)
473 492 return (dt_set_errno(dtp, errno));
474 493
475 494 for (i = 0; i < prp->pr_nargc; i++) {
476 495 if (fprintf(infop->dthi_out, "arg%d", i) < 0)
477 496 return (dt_set_errno(dtp, errno));
478 497
479 498 if (i + 1 != prp->pr_nargc &&
480 499 fprintf(infop->dthi_out, ", ") < 0)
481 500 return (dt_set_errno(dtp, errno));
482 501 }
483 502
484 503 if (!infop->dthi_empty) {
485 504 if (fprintf(infop->dthi_out, ") \\\n\t") < 0)
486 505 return (dt_set_errno(dtp, errno));
487 506
488 507 if (fprintf(infop->dthi_out, "__dtrace_%s___%s(",
489 508 infop->dthi_pfname, fname) < 0)
490 509 return (dt_set_errno(dtp, errno));
491 510
492 511 for (i = 0; i < prp->pr_nargc; i++) {
493 512 if (fprintf(infop->dthi_out, "arg%d", i) < 0)
494 513 return (dt_set_errno(dtp, errno));
495 514
496 515 if (i + 1 != prp->pr_nargc &&
497 516 fprintf(infop->dthi_out, ", ") < 0)
498 517 return (dt_set_errno(dtp, errno));
499 518 }
500 519 }
501 520
502 521 if (fprintf(infop->dthi_out, ")\n") < 0)
503 522 return (dt_set_errno(dtp, errno));
504 523
505 524 if (!infop->dthi_empty) {
506 525 if (fprintf(infop->dthi_out,
507 526 "#ifndef\t__sparc\n"
508 527 "#define\t%s_%s_ENABLED() \\\n"
509 528 "\t__dtraceenabled_%s___%s()\n"
510 529 "#else\n"
511 530 "#define\t%s_%s_ENABLED() \\\n"
512 531 "\t__dtraceenabled_%s___%s(0)\n"
513 532 "#endif\n",
514 533 infop->dthi_pmname, mname,
515 534 infop->dthi_pfname, fname,
516 535 infop->dthi_pmname, mname,
517 536 infop->dthi_pfname, fname) < 0)
518 537 return (dt_set_errno(dtp, errno));
519 538
520 539 } else {
521 540 if (fprintf(infop->dthi_out, "#define\t%s_%s_ENABLED() (0)\n",
522 541 infop->dthi_pmname, mname) < 0)
523 542 return (dt_set_errno(dtp, errno));
524 543 }
525 544
526 545 return (0);
527 546 }
528 547
529 548 static int
530 549 dt_header_provider(dtrace_hdl_t *dtp, dt_provider_t *pvp, FILE *out)
531 550 {
532 551 dt_header_info_t info;
533 552 const char *p;
534 553 int i;
535 554
536 555 if (pvp->pv_flags & DT_PROVIDER_IMPL)
537 556 return (0);
538 557
539 558 /*
540 559 * Count the instances of the '-' character since we'll need to double
541 560 * those up.
542 561 */
543 562 p = pvp->pv_desc.dtvd_name;
544 563 for (i = 0; (p = strchr(p, '-')) != NULL; i++)
545 564 p++;
546 565
547 566 info.dthi_dtp = dtp;
548 567 info.dthi_out = out;
549 568 info.dthi_empty = 0;
550 569
551 570 info.dthi_pmname = alloca(strlen(pvp->pv_desc.dtvd_name) + 1);
552 571 dt_header_fmt_macro(info.dthi_pmname, pvp->pv_desc.dtvd_name);
553 572
554 573 info.dthi_pfname = alloca(strlen(pvp->pv_desc.dtvd_name) + 1 + i);
555 574 dt_header_fmt_func(info.dthi_pfname, pvp->pv_desc.dtvd_name);
556 575
557 576 if (fprintf(out, "#if _DTRACE_VERSION\n\n") < 0)
558 577 return (dt_set_errno(dtp, errno));
559 578
560 579 if (dt_idhash_iter(pvp->pv_probes, dt_header_probe, &info) != 0)
561 580 return (-1); /* dt_errno is set for us */
562 581 if (fprintf(out, "\n\n") < 0)
563 582 return (dt_set_errno(dtp, errno));
564 583 if (dt_idhash_iter(pvp->pv_probes, dt_header_decl, &info) != 0)
565 584 return (-1); /* dt_errno is set for us */
566 585
567 586 if (fprintf(out, "\n#else\n\n") < 0)
568 587 return (dt_set_errno(dtp, errno));
569 588
570 589 info.dthi_empty = 1;
571 590
572 591 if (dt_idhash_iter(pvp->pv_probes, dt_header_probe, &info) != 0)
573 592 return (-1); /* dt_errno is set for us */
574 593
575 594 if (fprintf(out, "\n#endif\n\n") < 0)
576 595 return (dt_set_errno(dtp, errno));
577 596
578 597 return (0);
579 598 }
580 599
581 600 int
582 601 dtrace_program_header(dtrace_hdl_t *dtp, FILE *out, const char *fname)
583 602 {
584 603 dt_provider_t *pvp;
585 604 char *mfname, *p;
586 605
587 606 if (fname != NULL) {
588 607 if ((p = strrchr(fname, '/')) != NULL)
589 608 fname = p + 1;
590 609
591 610 mfname = alloca(strlen(fname) + 1);
592 611 dt_header_fmt_macro(mfname, fname);
593 612 if (fprintf(out, "#ifndef\t_%s\n#define\t_%s\n\n",
594 613 mfname, mfname) < 0)
595 614 return (dt_set_errno(dtp, errno));
596 615 }
597 616
598 617 if (fprintf(out, "#include <unistd.h>\n\n") < 0)
599 618 return (-1);
600 619
601 620 if (fprintf(out, "#ifdef\t__cplusplus\nextern \"C\" {\n#endif\n\n") < 0)
602 621 return (-1);
603 622
604 623 for (pvp = dt_list_next(&dtp->dt_provlist);
605 624 pvp != NULL; pvp = dt_list_next(pvp)) {
606 625 if (dt_header_provider(dtp, pvp, out) != 0)
607 626 return (-1); /* dt_errno is set for us */
608 627 }
609 628
610 629 if (fprintf(out, "\n#ifdef\t__cplusplus\n}\n#endif\n") < 0)
611 630 return (dt_set_errno(dtp, errno));
612 631
613 632 if (fname != NULL && fprintf(out, "\n#endif\t/* _%s */\n", mfname) < 0)
614 633 return (dt_set_errno(dtp, errno));
615 634
616 635 return (0);
617 636 }
↓ open down ↓ |
451 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX