This source file includes following definitions.
- opal_output_init
- opal_output_open
- opal_output_reopen
- opal_output_switch
- opal_output_reopen_all
- opal_output_close
- opal_output
- opal_output_verbose
- opal_output_vverbose
- opal_output_string
- opal_output_vstring
- opal_output_set_verbosity
- opal_output_set_output_file_info
- opal_output_finalize
- construct
- destruct
- do_open
- open_file
- free_descriptor
- make_string
- output
- opal_output_get_verbosity
   1 
   2 
   3 
   4 
   5 
   6 
   7 
   8 
   9 
  10 
  11 
  12 
  13 
  14 
  15 
  16 
  17 
  18 
  19 
  20 
  21 
  22 
  23 
  24 
  25 
  26 
  27 
  28 
  29 
  30 #include "opal_config.h"
  31 
  32 #include <stdio.h>
  33 #include <stdarg.h>
  34 #include <stdlib.h>
  35 #ifdef HAVE_SYSLOG_H
  36 #include <syslog.h>
  37 #endif
  38 #include <string.h>
  39 #include <fcntl.h>
  40 #ifdef HAVE_UNISTD_H
  41 #include <unistd.h>
  42 #endif
  43 #ifdef HAVE_SYS_PARAM_H
  44 #include <sys/param.h>
  45 #endif
  46 
  47 #include "opal/util/opal_environ.h"
  48 #include "opal/util/output.h"
  49 #include "opal/util/string_copy.h"
  50 #include "opal/util/printf.h"
  51 #include "opal/threads/mutex.h"
  52 #include "opal/constants.h"
  53 #include "opal/mca/pmix/pmix.h"
  54 
  55 
  56 
  57 
  58 static int verbose_stream = -1;
  59 static opal_output_stream_t verbose;
  60 static char *output_dir = NULL;
  61 static char *output_prefix = NULL;
  62 
  63 
  64 
  65 
  66 
  67 
  68 typedef struct {
  69     bool ldi_used;
  70     bool ldi_enabled;
  71     int ldi_verbose_level;
  72 
  73     bool ldi_syslog;
  74     int ldi_syslog_priority;
  75 
  76     char *ldi_syslog_ident;
  77     char *ldi_prefix;
  78     int ldi_prefix_len;
  79 
  80     char *ldi_suffix;
  81     int ldi_suffix_len;
  82 
  83     bool ldi_stdout;
  84     bool ldi_stderr;
  85 
  86     bool ldi_file;
  87     bool ldi_file_want_append;
  88     char *ldi_file_suffix;
  89     int ldi_fd;
  90     int ldi_file_num_lines_lost;
  91 } output_desc_t;
  92 
  93 
  94 
  95 
  96 static void construct(opal_object_t *stream);
  97 static void destruct(opal_object_t *stream);
  98 static int do_open(int output_id, opal_output_stream_t * lds);
  99 static int open_file(int i);
 100 static void free_descriptor(int output_id);
 101 static int make_string(char **no_newline_string, output_desc_t *ldi,
 102                        const char *format, va_list arglist);
 103 static int output(int output_id, const char *format, va_list arglist);
 104 static void opal_output_finalize (void);
 105 
 106 
 107 #define OPAL_OUTPUT_MAX_STREAMS 64
 108 #if defined(HAVE_SYSLOG)
 109 #define USE_SYSLOG 1
 110 #else
 111 #define USE_SYSLOG 0
 112 #endif
 113 
 114 
 115 bool opal_output_redirected_to_syslog = false;
 116 int opal_output_redirected_syslog_pri = -1;
 117 
 118 
 119 
 120 
 121 static bool initialized = false;
 122 static int default_stderr_fd = -1;
 123 static output_desc_t info[OPAL_OUTPUT_MAX_STREAMS];
 124 static char *temp_str = 0;
 125 static size_t temp_str_len = 0;
 126 static opal_mutex_t mutex;
 127 #if defined(HAVE_SYSLOG)
 128 static bool syslog_opened = false;
 129 #endif
 130 static char *redirect_syslog_ident = NULL;
 131 
 132 OBJ_CLASS_INSTANCE(opal_output_stream_t, opal_object_t, construct, destruct);
 133 
 134 
 135 
 136 
 137 bool opal_output_init(void)
 138 {
 139     int i;
 140     char hostname[OPAL_MAXHOSTNAMELEN];
 141     char *str;
 142 
 143     if (initialized) {
 144         return true;
 145     }
 146 
 147     str = getenv("OPAL_OUTPUT_STDERR_FD");
 148     if (NULL != str) {
 149         default_stderr_fd = atoi(str);
 150     }
 151     str = getenv("OPAL_OUTPUT_REDIRECT");
 152     if (NULL != str) {
 153         if (0 == strcasecmp(str, "syslog")) {
 154             opal_output_redirected_to_syslog = true;
 155         }
 156     }
 157     str = getenv("OPAL_OUTPUT_SYSLOG_PRI");
 158 #ifdef HAVE_SYSLOG_H
 159     if (NULL != str) {
 160         if (0 == strcasecmp(str, "info")) {
 161             opal_output_redirected_syslog_pri = LOG_INFO;
 162         } else if (0 == strcasecmp(str, "error")) {
 163             opal_output_redirected_syslog_pri = LOG_ERR;
 164         } else if (0 == strcasecmp(str, "warn")) {
 165             opal_output_redirected_syslog_pri = LOG_WARNING;
 166         } else {
 167             opal_output_redirected_syslog_pri = LOG_ERR;
 168         }
 169     } else {
 170         opal_output_redirected_syslog_pri = LOG_ERR;
 171     }
 172 #endif  
 173     str = getenv("OPAL_OUTPUT_SYSLOG_IDENT");
 174     if (NULL != str) {
 175         redirect_syslog_ident = strdup(str);
 176     }
 177 
 178     OBJ_CONSTRUCT(&verbose, opal_output_stream_t);
 179     if (opal_output_redirected_to_syslog) {
 180         verbose.lds_want_syslog = true;
 181         verbose.lds_syslog_priority = opal_output_redirected_syslog_pri;
 182         if (NULL != str) {
 183             verbose.lds_syslog_ident = strdup(redirect_syslog_ident);
 184         }
 185         verbose.lds_want_stderr = false;
 186         verbose.lds_want_stdout = false;
 187     } else {
 188         str = getenv("OPAL_OUTPUT_INTERNAL_TO_STDOUT");
 189         if (NULL != str && str[0] == '1') {
 190             verbose.lds_want_stdout = true;
 191         }
 192         else {
 193             verbose.lds_want_stderr = true;
 194         }
 195     }
 196     gethostname(hostname, sizeof(hostname));
 197     opal_asprintf(&verbose.lds_prefix, "[%s:%05d] ", hostname, getpid());
 198 
 199     for (i = 0; i < OPAL_OUTPUT_MAX_STREAMS; ++i) {
 200         info[i].ldi_used = false;
 201         info[i].ldi_enabled = false;
 202 
 203         info[i].ldi_syslog = opal_output_redirected_to_syslog;
 204         info[i].ldi_file = false;
 205         info[i].ldi_file_suffix = NULL;
 206         info[i].ldi_file_want_append = false;
 207         info[i].ldi_fd = -1;
 208         info[i].ldi_file_num_lines_lost = 0;
 209     }
 210 
 211     
 212 
 213     OBJ_CONSTRUCT(&mutex, opal_mutex_t);
 214     initialized = true;
 215 
 216     
 217 
 218     opal_asprintf(&output_prefix, "output-pid%d-", getpid());
 219     output_dir = strdup(opal_tmp_directory());
 220 
 221     
 222     verbose_stream = opal_output_open(&verbose);
 223 
 224     
 225     opal_finalize_register_cleanup (opal_output_finalize);
 226 
 227     return true;
 228 }
 229 
 230 
 231 
 232 
 233 
 234 int opal_output_open(opal_output_stream_t * lds)
 235 {
 236     return do_open(-1, lds);
 237 }
 238 
 239 
 240 
 241 
 242 
 243 int opal_output_reopen(int output_id, opal_output_stream_t * lds)
 244 {
 245     return do_open(output_id, lds);
 246 }
 247 
 248 
 249 
 250 
 251 
 252 bool opal_output_switch(int output_id, bool enable)
 253 {
 254     bool ret = false;
 255 
 256     
 257 
 258     if (!initialized) {
 259         opal_output_init();
 260     }
 261 
 262     if (output_id >= 0 && output_id < OPAL_OUTPUT_MAX_STREAMS) {
 263         ret = info[output_id].ldi_enabled;
 264         info[output_id].ldi_enabled = enable;
 265     }
 266 
 267     return ret;
 268 }
 269 
 270 
 271 
 272 
 273 
 274 void opal_output_reopen_all(void)
 275 {
 276     char *str;
 277     char hostname[OPAL_MAXHOSTNAMELEN];
 278 
 279     str = getenv("OPAL_OUTPUT_STDERR_FD");
 280     if (NULL != str) {
 281         default_stderr_fd = atoi(str);
 282     } else {
 283         default_stderr_fd = -1;
 284     }
 285 
 286     gethostname(hostname, sizeof(hostname));
 287     if( NULL != verbose.lds_prefix ) {
 288         free(verbose.lds_prefix);
 289         verbose.lds_prefix = NULL;
 290     }
 291     opal_asprintf(&verbose.lds_prefix, "[%s:%05d] ", hostname, getpid());
 292 #if 0
 293     int i;
 294     opal_output_stream_t lds;
 295 
 296     for (i = 0; i < OPAL_OUTPUT_MAX_STREAMS; ++i) {
 297 
 298         
 299 
 300         if (!info[i].ldi_used) {
 301             break;
 302         }
 303 
 304         
 305 
 306 
 307 
 308         info[i].ldi_used = false;
 309 
 310 #if USE_SYSLOG
 311         lds.lds_want_syslog = info[i].ldi_syslog;
 312         lds.lds_syslog_priority = info[i].ldi_syslog_priority;
 313         lds.lds_syslog_ident = info[i].ldi_syslog_ident;
 314 #else
 315         lds.lds_want_syslog = false;
 316 #endif
 317         lds.lds_prefix = info[i].ldi_prefix;
 318         lds.lds_suffix = info[i].ldi_suffix;
 319         lds.lds_want_stdout = info[i].ldi_stdout;
 320         lds.lds_want_stderr = info[i].ldi_stderr;
 321         lds.lds_want_file = (-1 == info[i].ldi_fd) ? false : true;
 322         
 323         lds.lds_want_file_append = true;
 324         lds.lds_file_suffix = info[i].ldi_file_suffix;
 325 
 326         
 327 
 328 
 329 
 330         opal_output_open(&lds);
 331     }
 332 #endif
 333 }
 334 
 335 
 336 
 337 
 338 
 339 void opal_output_close(int output_id)
 340 {
 341     int i;
 342 
 343     
 344 
 345     if (!initialized || output_id < 0) {
 346         return;
 347     }
 348 
 349     
 350 
 351 
 352     OPAL_THREAD_LOCK(&mutex);
 353     if (output_id < OPAL_OUTPUT_MAX_STREAMS &&
 354         info[output_id].ldi_used && info[output_id].ldi_enabled) {
 355         free_descriptor(output_id);
 356 
 357         
 358 
 359         for (i = 0; i < OPAL_OUTPUT_MAX_STREAMS; ++i) {
 360             if (info[i].ldi_used && info[i].ldi_syslog) {
 361                 break;
 362             }
 363         }
 364 
 365 #if defined(HAVE_SYSLOG) && defined(HAVE_SYSLOG_H)
 366         if (i >= OPAL_OUTPUT_MAX_STREAMS && syslog_opened) {
 367             closelog();
 368         }
 369 #endif
 370     }
 371 
 372     OPAL_THREAD_UNLOCK(&mutex);
 373 }
 374 
 375 
 376 
 377 
 378 
 379 void opal_output(int output_id, const char *format, ...)
 380 {
 381     if (output_id >= 0 && output_id < OPAL_OUTPUT_MAX_STREAMS) {
 382         va_list arglist;
 383         va_start(arglist, format);
 384         output(output_id, format, arglist);
 385         va_end(arglist);
 386     }
 387 }
 388 
 389 
 390 
 391 
 392 
 393 void opal_output_verbose(int level, int output_id, const char *format, ...)
 394 {
 395     if (output_id >= 0 && output_id < OPAL_OUTPUT_MAX_STREAMS &&
 396         info[output_id].ldi_verbose_level >= level) {
 397         va_list arglist;
 398         va_start(arglist, format);
 399         output(output_id, format, arglist);
 400         va_end(arglist);
 401     }
 402 }
 403 
 404 
 405 
 406 
 407 
 408 void opal_output_vverbose(int level, int output_id, const char *format,
 409                           va_list arglist)
 410 {
 411     if (output_id >= 0 && output_id < OPAL_OUTPUT_MAX_STREAMS &&
 412         info[output_id].ldi_verbose_level >= level) {
 413         output(output_id, format, arglist);
 414     }
 415 }
 416 
 417 
 418 
 419 
 420 
 421 char *opal_output_string(int level, int output_id, const char *format, ...)
 422 {
 423     int rc;
 424     char *ret = NULL;
 425 
 426     if (output_id >= 0 && output_id < OPAL_OUTPUT_MAX_STREAMS &&
 427         info[output_id].ldi_verbose_level >= level) {
 428         va_list arglist;
 429         va_start(arglist, format);
 430         rc = make_string(&ret, &info[output_id], format, arglist);
 431         va_end(arglist);
 432         if (OPAL_SUCCESS != rc) {
 433             ret = NULL;
 434         }
 435     }
 436 
 437     return ret;
 438 }
 439 
 440 
 441 
 442 
 443 
 444 char *opal_output_vstring(int level, int output_id, const char *format,
 445                           va_list arglist)
 446 {
 447     int rc;
 448     char *ret = NULL;
 449 
 450     if (output_id >= 0 && output_id < OPAL_OUTPUT_MAX_STREAMS &&
 451         info[output_id].ldi_verbose_level >= level) {
 452         rc = make_string(&ret, &info[output_id], format, arglist);
 453         if (OPAL_SUCCESS != rc) {
 454             ret = NULL;
 455         }
 456     }
 457 
 458     return ret;
 459 }
 460 
 461 
 462 
 463 
 464 
 465 void opal_output_set_verbosity(int output_id, int level)
 466 {
 467     if (output_id >= 0 && output_id < OPAL_OUTPUT_MAX_STREAMS) {
 468         info[output_id].ldi_verbose_level = level;
 469     }
 470 }
 471 
 472 
 473 
 474 
 475 
 476 void opal_output_set_output_file_info(const char *dir,
 477                                       const char *prefix,
 478                                       char **olddir,
 479                                       char **oldprefix)
 480 {
 481     if (NULL != olddir) {
 482         *olddir = strdup(output_dir);
 483     }
 484     if (NULL != oldprefix) {
 485         *oldprefix = strdup(output_prefix);
 486     }
 487 
 488     if (NULL != dir) {
 489         free(output_dir);
 490         output_dir = strdup(dir);
 491     }
 492     if (NULL != prefix) {
 493         free(output_prefix);
 494         output_prefix = strdup(prefix);
 495     }
 496 }
 497 
 498 
 499 
 500 
 501 
 502 static void opal_output_finalize(void)
 503 {
 504     if (initialized) {
 505         if (verbose_stream != -1) {
 506             opal_output_close(verbose_stream);
 507         }
 508         free(verbose.lds_prefix);
 509         verbose.lds_prefix = NULL;
 510 
 511         verbose_stream = -1;
 512 
 513         free (output_prefix);
 514         output_prefix = NULL;
 515 
 516         free (output_dir);
 517         output_dir = NULL;
 518 
 519         if(NULL != temp_str) {
 520             free(temp_str);
 521             temp_str = NULL;
 522             temp_str_len = 0;
 523         }
 524         OBJ_DESTRUCT(&verbose);
 525         OBJ_DESTRUCT(&mutex);
 526     }
 527 
 528     initialized = false;
 529 }
 530 
 531 
 532 
 533 
 534 
 535 
 536 static void construct(opal_object_t *obj)
 537 {
 538     opal_output_stream_t *stream = (opal_output_stream_t*) obj;
 539 
 540     stream->lds_verbose_level = 0;
 541     stream->lds_syslog_priority = 0;
 542     stream->lds_syslog_ident = NULL;
 543     stream->lds_prefix = NULL;
 544     stream->lds_suffix = NULL;
 545     stream->lds_is_debugging = false;
 546     stream->lds_want_syslog = false;
 547     stream->lds_want_stdout = false;
 548     stream->lds_want_stderr = false;
 549     stream->lds_want_file = false;
 550     stream->lds_want_file_append = false;
 551     stream->lds_file_suffix = NULL;
 552 }
 553 static void destruct(opal_object_t *obj)
 554 {
 555     opal_output_stream_t *stream = (opal_output_stream_t*) obj;
 556 
 557     if( NULL != stream->lds_file_suffix ) {
 558         free(stream->lds_file_suffix);
 559         stream->lds_file_suffix = NULL;
 560     }
 561 }
 562 
 563 
 564 
 565 
 566 
 567 
 568 static int do_open(int output_id, opal_output_stream_t * lds)
 569 {
 570     int i;
 571     bool redirect_to_file = false;
 572     char *str, *sfx;
 573 
 574     
 575 
 576     if (!initialized) {
 577         opal_output_init();
 578     }
 579 
 580     str = getenv("OPAL_OUTPUT_REDIRECT");
 581     if (NULL != str && 0 == strcasecmp(str, "file")) {
 582         redirect_to_file = true;
 583     }
 584     sfx = getenv("OPAL_OUTPUT_SUFFIX");
 585 
 586     
 587 
 588 
 589     if (-1 == output_id) {
 590         OPAL_THREAD_LOCK(&mutex);
 591         for (i = 0; i < OPAL_OUTPUT_MAX_STREAMS; ++i) {
 592             if (!info[i].ldi_used) {
 593                 break;
 594             }
 595         }
 596         if (i >= OPAL_OUTPUT_MAX_STREAMS) {
 597             OPAL_THREAD_UNLOCK(&mutex);
 598             return OPAL_ERR_OUT_OF_RESOURCE;
 599         }
 600     }
 601 
 602     
 603 
 604 
 605     else {
 606         free_descriptor(output_id);
 607         i = output_id;
 608     }
 609 
 610     
 611 
 612 
 613     if (NULL == lds) {
 614         lds = &verbose;
 615     }
 616 
 617     
 618 
 619     info[i].ldi_used = true;
 620     if (-1 == output_id) {
 621         OPAL_THREAD_UNLOCK(&mutex);
 622     }
 623     info[i].ldi_enabled = lds->lds_is_debugging ?
 624         (bool) OPAL_ENABLE_DEBUG : true;
 625     info[i].ldi_verbose_level = lds->lds_verbose_level;
 626 
 627 #if USE_SYSLOG
 628 #if defined(HAVE_SYSLOG) && defined(HAVE_SYSLOG_H)
 629     if (opal_output_redirected_to_syslog) {
 630         info[i].ldi_syslog = true;
 631         info[i].ldi_syslog_priority = opal_output_redirected_syslog_pri;
 632         if (NULL != redirect_syslog_ident) {
 633             info[i].ldi_syslog_ident = strdup(redirect_syslog_ident);
 634             openlog(redirect_syslog_ident, LOG_PID, LOG_USER);
 635         } else {
 636             info[i].ldi_syslog_ident = NULL;
 637             openlog("opal", LOG_PID, LOG_USER);
 638         }
 639         syslog_opened = true;
 640     } else {
 641 #endif
 642         info[i].ldi_syslog = lds->lds_want_syslog;
 643         if (lds->lds_want_syslog) {
 644 
 645 #if defined(HAVE_SYSLOG) && defined(HAVE_SYSLOG_H)
 646             if (NULL != lds->lds_syslog_ident) {
 647                 info[i].ldi_syslog_ident = strdup(lds->lds_syslog_ident);
 648                 openlog(lds->lds_syslog_ident, LOG_PID, LOG_USER);
 649             } else {
 650                 info[i].ldi_syslog_ident = NULL;
 651                 openlog("opal", LOG_PID, LOG_USER);
 652             }
 653 #endif
 654             syslog_opened = true;
 655             info[i].ldi_syslog_priority = lds->lds_syslog_priority;
 656         }
 657 
 658 #if defined(HAVE_SYSLOG) && defined(HAVE_SYSLOG_H)
 659     }
 660 #endif
 661 
 662 #else
 663     info[i].ldi_syslog = false;
 664 #endif
 665 
 666     if (NULL != lds->lds_prefix) {
 667         info[i].ldi_prefix = strdup(lds->lds_prefix);
 668         info[i].ldi_prefix_len = (int)strlen(lds->lds_prefix);
 669     } else {
 670         info[i].ldi_prefix = NULL;
 671         info[i].ldi_prefix_len = 0;
 672     }
 673 
 674     if (NULL != lds->lds_suffix) {
 675         info[i].ldi_suffix = strdup(lds->lds_suffix);
 676         info[i].ldi_suffix_len = (int)strlen(lds->lds_suffix);
 677     } else {
 678         info[i].ldi_suffix = NULL;
 679         info[i].ldi_suffix_len = 0;
 680     }
 681 
 682     if (opal_output_redirected_to_syslog) {
 683         
 684 
 685 
 686         info[i].ldi_stdout = false;
 687         info[i].ldi_stderr = false;
 688         info[i].ldi_file = false;
 689         info[i].ldi_fd = -1;
 690     } else {
 691         
 692 
 693 
 694         if (NULL != str && redirect_to_file) {
 695             info[i].ldi_stdout = false;
 696             info[i].ldi_stderr = false;
 697             info[i].ldi_file = true;
 698         } else {
 699             info[i].ldi_stdout = lds->lds_want_stdout;
 700             info[i].ldi_stderr = lds->lds_want_stderr;
 701 
 702             info[i].ldi_fd = -1;
 703             info[i].ldi_file = lds->lds_want_file;
 704         }
 705         if (NULL != sfx) {
 706             info[i].ldi_file_suffix = strdup(sfx);
 707         } else {
 708             info[i].ldi_file_suffix = (NULL == lds->lds_file_suffix) ? NULL :
 709                 strdup(lds->lds_file_suffix);
 710         }
 711         info[i].ldi_file_want_append = lds->lds_want_file_append;
 712         info[i].ldi_file_num_lines_lost = 0;
 713     }
 714 
 715     
 716 
 717 
 718 
 719     if( verbose_stream == i ) {
 720         verbose.lds_want_syslog     = info[i].ldi_syslog;
 721         verbose.lds_syslog_priority = info[i].ldi_syslog_priority;
 722         verbose.lds_syslog_ident    = info[i].ldi_syslog_ident;
 723         verbose.lds_want_stdout     = info[i].ldi_stdout;
 724         verbose.lds_want_stderr     = info[i].ldi_stderr;
 725     }
 726 
 727     
 728 
 729 
 730     return i;
 731 }
 732 
 733 
 734 static int open_file(int i)
 735 {
 736     int flags;
 737     char *filename;
 738     int n;
 739 
 740     
 741 
 742 
 743 
 744     for (n=0; n < OPAL_OUTPUT_MAX_STREAMS; n++) {
 745         if (i == n) {
 746             continue;
 747         }
 748         if (!info[n].ldi_used) {
 749             continue;
 750         }
 751         if (!info[n].ldi_file) {
 752             continue;
 753         }
 754         if (NULL != info[i].ldi_file_suffix &&
 755             NULL != info[n].ldi_file_suffix) {
 756             if (0 != strcmp(info[i].ldi_file_suffix, info[n].ldi_file_suffix)) {
 757                 break;
 758             }
 759         }
 760         if (NULL == info[i].ldi_file_suffix &&
 761             NULL != info[n].ldi_file_suffix) {
 762             break;
 763         }
 764         if (NULL != info[i].ldi_file_suffix &&
 765             NULL == info[n].ldi_file_suffix) {
 766             break;
 767         }
 768         if (info[n].ldi_fd < 0) {
 769             break;
 770         }
 771         info[i].ldi_fd = info[n].ldi_fd;
 772         return OPAL_SUCCESS;
 773     }
 774 
 775     
 776 
 777     if (NULL != output_dir) {
 778         filename = (char *) malloc(OPAL_PATH_MAX);
 779         if (NULL == filename) {
 780             return OPAL_ERR_OUT_OF_RESOURCE;
 781         }
 782         opal_string_copy(filename, output_dir, OPAL_PATH_MAX);
 783         strcat(filename, "/");
 784         if (NULL != output_prefix) {
 785             strcat(filename, output_prefix);
 786         }
 787         if (info[i].ldi_file_suffix != NULL) {
 788             strcat(filename, info[i].ldi_file_suffix);
 789         } else {
 790             info[i].ldi_file_suffix = NULL;
 791             strcat(filename, "output.txt");
 792         }
 793         flags = O_CREAT | O_RDWR;
 794         if (!info[i].ldi_file_want_append) {
 795             flags |= O_TRUNC;
 796         }
 797 
 798         
 799         info[i].ldi_fd = open(filename, flags, 0644);
 800         if (-1 == info[i].ldi_fd) {
 801             info[i].ldi_used = false;
 802             free(filename);  
 803             return OPAL_ERR_IN_ERRNO;
 804         }
 805 
 806         
 807 
 808         if (-1 == fcntl(info[i].ldi_fd, F_SETFD, 1)) {
 809             free(filename);  
 810             return OPAL_ERR_IN_ERRNO;
 811         }
 812 
 813         
 814         if (NULL != opal_pmix.register_cleanup) {
 815             opal_pmix.register_cleanup(filename, false, true, false);
 816         }
 817         free(filename);  
 818     }
 819 
 820     
 821 
 822 
 823     return OPAL_SUCCESS;
 824 }
 825 
 826 
 827 
 828 
 829 
 830 static void free_descriptor(int output_id)
 831 {
 832     output_desc_t *ldi;
 833 
 834     if (output_id >= 0 && output_id < OPAL_OUTPUT_MAX_STREAMS &&
 835         info[output_id].ldi_used && info[output_id].ldi_enabled) {
 836         ldi = &info[output_id];
 837 
 838         if (-1 != ldi->ldi_fd) {
 839             close(ldi->ldi_fd);
 840         }
 841         ldi->ldi_used = false;
 842 
 843         
 844 
 845         if (NULL != ldi->ldi_prefix) {
 846             free(ldi->ldi_prefix);
 847         }
 848         ldi->ldi_prefix = NULL;
 849 
 850     if (NULL != ldi->ldi_suffix) {
 851         free(ldi->ldi_suffix);
 852     }
 853     ldi->ldi_suffix = NULL;
 854 
 855     if (NULL != ldi->ldi_file_suffix) {
 856             free(ldi->ldi_file_suffix);
 857         }
 858         ldi->ldi_file_suffix = NULL;
 859 
 860         if (NULL != ldi->ldi_syslog_ident) {
 861             free(ldi->ldi_syslog_ident);
 862         }
 863         ldi->ldi_syslog_ident = NULL;
 864     }
 865 }
 866 
 867 
 868 static int make_string(char **no_newline_string, output_desc_t *ldi,
 869                        const char *format, va_list arglist)
 870 {
 871     size_t len, total_len;
 872     bool want_newline = false;
 873 
 874     
 875 
 876     opal_vasprintf(no_newline_string, format, arglist);
 877     total_len = len = strlen(*no_newline_string);
 878     if ('\n' != (*no_newline_string)[len - 1]) {
 879         want_newline = true;
 880         ++total_len;
 881     } else if (NULL != ldi->ldi_suffix) {
 882         
 883 
 884 
 885         (*no_newline_string)[len - 1] = '\0';
 886         want_newline = true; 
 887         
 888 
 889 
 890     }
 891     if (NULL != ldi->ldi_prefix) {
 892         total_len += strlen(ldi->ldi_prefix);
 893     }
 894     if (NULL != ldi->ldi_suffix) {
 895         total_len += strlen(ldi->ldi_suffix);
 896     }
 897     if (temp_str_len < total_len + want_newline) {
 898         if (NULL != temp_str) {
 899             free(temp_str);
 900         }
 901         temp_str = (char *) malloc(total_len * 2);
 902         if (NULL == temp_str) {
 903             return OPAL_ERR_OUT_OF_RESOURCE;
 904         }
 905         temp_str_len = total_len * 2;
 906     }
 907     if (NULL != ldi->ldi_prefix && NULL != ldi->ldi_suffix) {
 908         if (want_newline) {
 909             snprintf(temp_str, temp_str_len, "%s%s%s\n",
 910                      ldi->ldi_prefix, *no_newline_string, ldi->ldi_suffix);
 911         } else {
 912             snprintf(temp_str, temp_str_len, "%s%s%s", ldi->ldi_prefix,
 913                      *no_newline_string, ldi->ldi_suffix);
 914         }
 915     } else if (NULL != ldi->ldi_prefix) {
 916         if (want_newline) {
 917             snprintf(temp_str, temp_str_len, "%s%s\n",
 918                      ldi->ldi_prefix, *no_newline_string);
 919         } else {
 920             snprintf(temp_str, temp_str_len, "%s%s", ldi->ldi_prefix,
 921                      *no_newline_string);
 922         }
 923     } else if (NULL != ldi->ldi_suffix) {
 924         if (want_newline) {
 925             snprintf(temp_str, temp_str_len, "%s%s\n",
 926                      *no_newline_string, ldi->ldi_suffix);
 927         } else {
 928             snprintf(temp_str, temp_str_len, "%s%s",
 929                      *no_newline_string, ldi->ldi_suffix);
 930         }
 931     } else {
 932         if (want_newline) {
 933             snprintf(temp_str, temp_str_len, "%s\n", *no_newline_string);
 934         } else {
 935             snprintf(temp_str, temp_str_len, "%s", *no_newline_string);
 936         }
 937     }
 938 
 939     return OPAL_SUCCESS;
 940 }
 941 
 942 
 943 
 944 
 945 
 946 
 947 static int output(int output_id, const char *format, va_list arglist)
 948 {
 949     int rc = OPAL_SUCCESS;
 950     char *str, *out = NULL;
 951     output_desc_t *ldi;
 952 
 953     
 954 
 955     if (!initialized) {
 956         opal_output_init();
 957     }
 958 
 959     
 960 
 961     if (output_id >= 0 && output_id < OPAL_OUTPUT_MAX_STREAMS &&
 962         info[output_id].ldi_used && info[output_id].ldi_enabled) {
 963         OPAL_THREAD_LOCK(&mutex);
 964         ldi = &info[output_id];
 965 
 966         
 967         if (OPAL_SUCCESS != (rc = make_string(&str, ldi, format, arglist))) {
 968             OPAL_THREAD_UNLOCK(&mutex);
 969             return rc;
 970         }
 971 
 972         
 973 #if defined(HAVE_SYSLOG) && defined(HAVE_SYSLOG_H)
 974         if (ldi->ldi_syslog) {
 975             syslog(ldi->ldi_syslog_priority, "%s", str);
 976         }
 977 #endif
 978 
 979         
 980 
 981 
 982         out = temp_str;
 983 
 984         
 985         if (ldi->ldi_stdout) {
 986             write(fileno(stdout), out, (int)strlen(out));
 987             fflush(stdout);
 988         }
 989 
 990         
 991         if (ldi->ldi_stderr) {
 992             write((-1 == default_stderr_fd) ?
 993                   fileno(stderr) : default_stderr_fd,
 994                   out, (int)strlen(out));
 995             fflush(stderr);
 996         }
 997 
 998         
 999 
1000 
1001 
1002 
1003         if (ldi->ldi_file) {
1004             if (ldi->ldi_fd == -1) {
1005                 if (OPAL_SUCCESS != open_file(output_id)) {
1006                     ++ldi->ldi_file_num_lines_lost;
1007                 } else if (ldi->ldi_file_num_lines_lost > 0) {
1008                     char buffer[BUFSIZ];
1009                     char *out = buffer;
1010                     memset(buffer, 0, BUFSIZ);
1011                     snprintf(buffer, BUFSIZ - 1,
1012                              "[WARNING: %d lines lost because the Open MPI process session directory did\n not exist when opal_output() was invoked]\n",
1013                              ldi->ldi_file_num_lines_lost);
1014                    write(ldi->ldi_fd, buffer, (int)strlen(buffer));
1015                     ldi->ldi_file_num_lines_lost = 0;
1016                     if (out != buffer) {
1017                         free(out);
1018                     }
1019                 }
1020             }
1021             if (ldi->ldi_fd != -1) {
1022                 write(ldi->ldi_fd, out, (int)strlen(out));
1023             }
1024         }
1025         OPAL_THREAD_UNLOCK(&mutex);
1026         free(str);
1027     }
1028 
1029     return rc;
1030 }
1031 
1032 int opal_output_get_verbosity(int output_id)
1033 {
1034     if (output_id >= 0 && output_id < OPAL_OUTPUT_MAX_STREAMS && info[output_id].ldi_used) {
1035         return info[output_id].ldi_verbose_level;
1036     } else {
1037         return -1;
1038     }
1039 }