1 /*
2 (C) 2007 by Argonne National Laboratory.
3 See COPYRIGHT in top-level directory.
4 */
5 #include "mpe_callstack_conf.h"
6
7 #if defined( STDC_HEADERS ) || defined( HAVE_STDIO_H )
8 #include <stdio.h>
9 #endif
10 #if defined( STDC_HEADERS ) || defined( HAVE_STRING_H )
11 #include <string.h>
12 #endif
13 #if defined( HAVE_UNISTD_H )
14 #include <unistd.h>
15 #endif
16 #if defined( HAVE_FCNTL_H )
17 #include <fcntl.h>
18 #endif
19
20 #include "mpe_callstack.h"
21
22 #if defined( NEEDS_FDOPEN_DECL )
23 extern FILE* fdopen( int, const char * );
24 #endif
25
26 /*@
27 MPE_CallStack_iteratorInit() -- Initialize the iterator for the
28 back trace of the CallStack.
29
30 Input Parameters:
31 . cstk - Pointer to MPE_CallStack_t.
32 @*/
MPE_CallStack_iteratorInit(MPE_CallStack_t * cstk)33 void MPE_CallStack_iteratorInit( MPE_CallStack_t *cstk )
34 {
35 int pipefds[2];
36 /* Connect a pipe to the fd used in backtrace_symbols_fd(). */
37 #ifdef HAVE_WINDOWS_H
38 /*FIXME: CreatePipe() --- windows */
39 #else
40 int ierr;
41 ierr = pipe( pipefds );
42 #endif
43 /* Set the writing end of the pipe non-blocking */
44 #ifdef HAVE_WINDOWS_H
45 /*FIXME: Set write fd non-blocking */
46 #else
47 fcntl( pipefds[1], F_SETFL, O_NONBLOCK );
48 #endif
49 MPE_CallStack_print( cstk, pipefds[1] );
50 /* Close the pipe so EOF is sent to the reading end of the pipe */
51 close( pipefds[1] );
52 cstk->pipefile = fdopen( pipefds[0], "r" );
53 memset( cstk->line_buf, 0, MPE_CALLSTACK_MAXLINE );
54 #if defined( HAVE_PRINTSTACK )
55 /* Take off the stackframe that contains this function call. */
56 MPE_CallStack_iteratorHasMore( cstk );
57 #endif
58 }
59
60 /*@
61 MPE_CallStack_iteratorHasMore - Check if the iterator contains any
62 more of CallStack frame.
63
64 Input Parameters:
65 . cstk - Pointer to MPE_CallStack_t.
66
67 Returns:
68 true, 1, if a complete record (i.e. with '\n' ) of callstack is found
69 false, 0, if the end of stack output is reached or error in reading.
70 @*/
MPE_CallStack_iteratorHasMore(MPE_CallStack_t * cstk)71 int MPE_CallStack_iteratorHasMore( MPE_CallStack_t *cstk )
72 {
73 char *line_end;
74 if ( fgets( cstk->line_buf, MPE_CALLSTACK_MAXLINE, cstk->pipefile ) ) {
75 line_end = strchr( cstk->line_buf, '\n' );
76 if ( line_end != NULL ) {
77 *line_end = '\0';
78 return 1;
79 }
80 }
81 /* Since no more callstack record, close the reading end of the pipe */
82 fclose( cstk->pipefile );
83 return 0;
84 }
85
86 /*@
87 MPE_CallStack_iteratorFetchNext - Returns next frame in the
88 CallStack iterator.
89
90 Input Parameters:
91 . cstk - Pointer to MPE_CallStack_t.
92
93 Returns:
94 the next callstack string without the ending '\n'.
95 @*/
MPE_CallStack_iteratorFetchNext(MPE_CallStack_t * cstk)96 const char* MPE_CallStack_iteratorFetchNext( MPE_CallStack_t *cstk )
97 {
98 return (const char *) (cstk->line_buf);
99 }
100