-: 0:Source:/home/MPI/testing/mpich2/mpich2/src/pmi/simple/simple_pmiutil.c
-: 0:Graph:simple_pmiutil.gcno
-: 0:Data:simple_pmiutil.gcda
-: 0:Runs:4380
-: 0:Programs:1376
-: 1:/* -*- Mode: C; c-basic-offset:4 ; -*- */
-: 2:/*
-: 3: * (C) 2001 by Argonne National Laboratory.
-: 4: * See COPYRIGHT in top-level directory.
-: 5: */
-: 6:
-: 7:/* Allow fprintf to logfile */
-: 8:/* style: allow:fprintf:1 sig:0 */
-: 9:
-: 10:/* Utility functions associated with PMI implementation, but not part of
-: 11: the PMI interface itself. Reading and writing on pipes, signals, and parsing
-: 12: key=value messages
-: 13:*/
-: 14:#include "pmiconf.h"
-: 15:
-: 16:#include <stdio.h>
-: 17:#ifdef HAVE_STDLIB_H
-: 18:#include <stdlib.h>
-: 19:#endif
-: 20:#include <stdarg.h>
-: 21:#ifdef HAVE_STRING_H
-: 22:#include <string.h>
-: 23:#endif
-: 24:#ifdef HAVE_UNISTD_H
-: 25:#include <unistd.h>
-: 26:#endif
-: 27:#include <errno.h>
-: 28:#include "simple_pmiutil.h"
-: 29:
-: 30:/* Use the memory definitions from mpich2/src/include */
-: 31:#include "mpimem.h"
-: 32:/* Use the MPI error message routines from mpich2/src/include */
-: 33:#include "mpibase.h"
-: 34:
-: 35:#define MAXVALLEN 1024
-: 36:#define MAXKEYLEN 32
-: 37:
-: 38:/* These are not the keyvals in the keyval space that is part of the
-: 39: PMI specification.
-: 40: They are just part of this implementation's internal utilities.
-: 41:*/
-: 42:struct PMIU_keyval_pairs {
-: 43: char key[MAXKEYLEN];
-: 44: char value[MAXVALLEN];
-: 45:};
-: 46:static struct PMIU_keyval_pairs PMIU_keyval_tab[64] = { { {0}, {0} } };
-: 47:static int PMIU_keyval_tab_idx = 0;
-: 48:
-: 49:/* This is used to prepend printed output. Set the initial value to
-: 50: "unset" */
-: 51:static char PMIU_print_id[PMIU_IDSIZE] = "unset";
-: 52:
-: 53:void PMIU_Set_rank( int PMI_rank )
4380: 54:{
4380: 55: MPIU_Snprintf( PMIU_print_id, PMIU_IDSIZE, "cli_%d", PMI_rank );
4380: 56:}
-: 57:void PMIU_SetServer( void )
|
#####: 58:{
#####: 59: MPIU_Strncpy( PMIU_print_id, "server", PMIU_IDSIZE );
#####: 60:}
-: 61:
-: 62:/* Note that vfprintf is part of C89 */
-: 63:
-: 64:/* style: allow:fprintf:1 sig:0 */
-: 65:/* style: allow:vfprintf:1 sig:0 */
-: 66:/* This should be combined with the message routines */
-: 67:void PMIU_printf( int print_flag, const char *fmt, ... )
|
6: 68:{
-: 69: va_list ap;
-: 70: static FILE *logfile= 0;
-: 71:
-: 72: /* In some cases when we are debugging, the handling of stdout or
-: 73: stderr may be unreliable. In that case, we make it possible to
-: 74: select an output file. */
6: 75: if (!logfile) {
-: 76: char *p;
6: 77: p = getenv("PMI_USE_LOGFILE");
6: 78: if (p) {
-: 79: char filename[1024];
|
#####: 80: p = getenv("PMI_ID");
#####: 81: if (p) {
#####: 82: MPIU_Snprintf( filename, sizeof(filename),
-: 83: "testclient-%s.out", p );
#####: 84: logfile = fopen( filename, "w" );
-: 85: }
-: 86: else {
#####: 87: logfile = fopen( "testserver.out", "w" );
-: 88: }
-: 89: }
-: 90: else
|
6: 91: logfile = stderr;
-: 92: }
-: 93:
6: 94: if ( print_flag ) {
-: 95: /* MPIU_Error_printf( "[%s]: ", PMIU_print_id ); */
-: 96: /* FIXME: Decide what role PMIU_printf should have (if any) and
-: 97: select the appropriate MPIU routine */
6: 98: fprintf( logfile, "[%s]: ", PMIU_print_id );
6: 99: va_start( ap, fmt );
6: 100: vfprintf( logfile, fmt, ap );
6: 101: va_end( ap );
6: 102: fflush( logfile );
-: 103: }
6: 104:}
-: 105:
-: 106:#define MAX_READLINE 1024
-: 107:/*
-: 108: * Return the next newline-terminated string of maximum length maxlen.
-: 109: * This is a buffered version, and reads from fd as necessary. A
-: 110: */
-: 111:int PMIU_readline( int fd, char *buf, int maxlen )
49011: 112:{
-: 113: static char readbuf[MAX_READLINE];
-: 114: static char *nextChar = 0, *lastChar = 0; /* lastChar is really one past
-: 115: last char */
-: 116: static int lastErrno = 0;
-: 117: static int lastfd = -1;
-: 118: int curlen, n;
-: 119: char *p, ch;
-: 120:
-: 121: /* Note: On the client side, only one thread at a time should
-: 122: be calling this, and there should only be a single fd.
-: 123: Server side code should not use this routine (see the
-: 124: replacement version in src/pm/util/pmiserv.c) */
49011: 125: if (nextChar != lastChar && fd != lastfd) {
|
#####: 126: MPIU_Internal_error_printf( "Panic - buffer inconsistent\n" );
#####: 127: return -1;
-: 128: }
-: 129:
|
49011: 130: p = buf;
49011: 131: curlen = 1; /* Make room for the null */
2364371: 132: while (curlen < maxlen) {
2315360: 133: if (nextChar == lastChar) {
49011: 134: lastfd = fd;
-: 135: do {
49011: 136: n = read( fd, readbuf, sizeof(readbuf)-1 );
49011: 137: } while (n == -1 && errno == EINTR);
49011: 138: if (n == 0) {
-: 139: /* EOF */
|
#####: 140: break;
-: 141: }
|
49011: 142: else if (n < 0) {
-: 143: /* Error. Return a negative value if there is no
-: 144: data. Save the errno in case we need to return it
-: 145: later. */
|
#####: 146: lastErrno = errno;
#####: 147: if (curlen == 1) {
#####: 148: curlen = 0;
-: 149: }
-: 150: break;
-: 151: }
|
49011: 152: nextChar = readbuf;
49011: 153: lastChar = readbuf + n;
-: 154: /* Add a null at the end just to make it easier to print
-: 155: the read buffer */
49011: 156: readbuf[n] = 0;
-: 157: /* FIXME: Make this an optional output */
-: 158: /* printf( "Readline %s\n", readbuf ); */
-: 159: }
-: 160:
2315360: 161: ch = *nextChar++;
2315360: 162: *p++ = ch;
2315360: 163: curlen++;
2315360: 164: if (ch == '\n') break;
-: 165: }
-: 166:
-: 167: /* We null terminate the string for convenience in printing */
49011: 168: *p = 0;
-: 169:
-: 170: /* Return the number of characters, not counting the null */
49011: 171: return curlen-1;
-: 172:}
-: 173:
-: 174:int PMIU_writeline( int fd, char *buf )
49668: 175:{
-: 176: int size, n;
-: 177:
49668: 178: size = strlen( buf );
49668: 179: if ( size > PMIU_MAXLINE ) {
|
#####: 180: buf[PMIU_MAXLINE-1] = '\0';
#####: 181: PMIU_printf( 1, "write_line: message string too big: :%s:\n", buf );
-: 182: }
|
49668: 183: else if ( buf[strlen( buf ) - 1] != '\n' ) /* error: no newline at end */
|
#####: 184: PMIU_printf( 1, "write_line: message string doesn't end in newline: :%s:\n",
-: 185: buf );
-: 186: else {
-: 187: do {
|
49668: 188: n = write( fd, buf, size );
49668: 189: } while (n == -1 && errno == EINTR);
-: 190:
49668: 191: if ( n < 0 ) {
|
#####: 192: PMIU_printf( 1, "write_line error; fd=%d buf=:%s:\n", fd, buf );
#####: 193: perror("system msg for write_line failure ");
#####: 194: return(-1);
-: 195: }
|
49668: 196: if ( n < size)
|
#####: 197: PMIU_printf( 1, "write_line failed to write entire message\n" );
-: 198: }
|
49668: 199: return 0;
-: 200:}
-: 201:
-: 202:/*
-: 203: * Given an input string st, parse it into internal storage that can be
-: 204: * queried by routines such as PMIU_getval.
-: 205: */
-: 206:int PMIU_parse_keyvals( char *st )
49011: 207:{
-: 208: char *p, *keystart, *valstart;
-: 209: int offset;
-: 210:
49011: 211: if ( !st )
|
#####: 212: return( -1 );
-: 213:
|
49011: 214: PMIU_keyval_tab_idx = 0;
49011: 215: p = st;
-: 216: while ( 1 ) {
192001: 217: while ( *p == ' ' )
71495: 218: p++;
-: 219: /* got non-blank */
120506: 220: if ( *p == '=' ) {
|
#####: 221: PMIU_printf( 1, "PMIU_parse_keyvals: unexpected = at character %d in %s\n",
-: 222: p - st, st );
#####: 223: return( -1 );
-: 224: }
|
120506: 225: if ( *p == '\n' || *p == '\0' )
|
#####: 226: return( 0 ); /* normal exit */
-: 227: /* got normal character */
|
120506: 228: keystart = p; /* remember where key started */
836199: 229: while ( *p != ' ' && *p != '=' && *p != '\n' && *p != '\0' )
595187: 230: p++;
120506: 231: if ( *p == ' ' || *p == '\n' || *p == '\0' ) {
|
#####: 232: PMIU_printf( 1,
-: 233: "PMIU_parse_keyvals: unexpected key delimiter at character %d in %s\n",
-: 234: p - st, st );
#####: 235: return( -1 );
-: 236: }
-: 237: /* Null terminate the key */
|
120506: 238: *p = 0;
-: 239: /* store key */
120506: 240: MPIU_Strncpy( PMIU_keyval_tab[PMIU_keyval_tab_idx].key, keystart,
-: 241: MAXKEYLEN );
-: 242:
120506: 243: valstart = ++p; /* start of value */
1720173: 244: while ( *p != ' ' && *p != '\n' && *p != '\0' )
1479161: 245: p++;
-: 246: /* store value */
120506: 247: MPIU_Strncpy( PMIU_keyval_tab[PMIU_keyval_tab_idx].value, valstart,
-: 248: MAXVALLEN );
120506: 249: offset = p - valstart;
-: 250: /* When compiled with -fPIC, the pgcc compiler generates incorrect
-: 251: code if "p - valstart" is used instead of using the
-: 252: intermediate offset */
120506: 253: PMIU_keyval_tab[PMIU_keyval_tab_idx].value[offset] = '\0';
120506: 254: PMIU_keyval_tab_idx++;
120506: 255: if ( *p == ' ' )
71495: 256: continue;
49011: 257: if ( *p == '\n' || *p == '\0' )
49011: 258: return( 0 ); /* value has been set to empty */
-: 259: }
-: 260:}
-: 261:
-: 262:void PMIU_dump_keyvals( void )
|
#####: 263:{
-: 264: int i;
#####: 265: for (i=0; i < PMIU_keyval_tab_idx; i++)
#####: 266: PMIU_printf(1, " %s=%s\n",PMIU_keyval_tab[i].key, PMIU_keyval_tab[i].value);
#####: 267:}
-: 268:
-: 269:char *PMIU_getval( const char *keystr, char *valstr, int vallen )
|
111637: 270:{
-: 271: int i, rc;
-: 272:
209854: 273: for (i = 0; i < PMIU_keyval_tab_idx; i++) {
209854: 274: if ( strcmp( keystr, PMIU_keyval_tab[i].key ) == 0 ) {
111637: 275: rc = MPIU_Strncpy( valstr, PMIU_keyval_tab[i].value, vallen );
111637: 276: if (rc != 0) {
|
#####: 277: PMIU_printf( 1, "MPIU_Strncpy failed in PMIU_getval\n" );
#####: 278: return NULL;
-: 279: }
|
111637: 280: return valstr;
-: 281: }
-: 282: }
|
#####: 283: valstr[0] = '\0';
#####: 284: return NULL;
-: 285:}
-: 286:
-: 287:void PMIU_chgval( const char *keystr, char *valstr )
#####: 288:{
-: 289: int i;
-: 290:
#####: 291: for ( i = 0; i < PMIU_keyval_tab_idx; i++ ) {
#####: 292: if ( strcmp( keystr, PMIU_keyval_tab[i].key ) == 0 ) {
#####: 293: MPIU_Strncpy( PMIU_keyval_tab[i].value, valstr, MAXVALLEN - 1 );
#####: 294: PMIU_keyval_tab[i].value[MAXVALLEN - 1] = '\0';
-: 295: }
-: 296: }
#####: 297:}
|