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