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 }