Пример #1
0
int
globus_l_args_create_error_msg( char **        error_msg,
				int            current_argc,
				char *         current_argv,
				char *         error_string,
				const char *   oneline_usage )
{
    char *      my_error_string;
    char *      p;
    int         usage_len;
    int         len;


#define error_format    _GCSL("\nError, argument #%d (%s) : %s\n\nSyntax : ")
#define error_epilogue  _GCSL("\n\nUse -help to display full usage.\n")

    my_error_string = (error_string) ? error_string : _GCSL("(no error message)");

    len = strlen(error_format)
        + strlen(current_argv)
        + strlen(my_error_string)
        + strlen(oneline_usage)
        + strlen(error_epilogue)
	+ 10;

    p = globus_l_args_malloc( char, len );
    globus_assert( p );
    globus_libc_sprintf( p,
			 error_format, 
			 current_argc, 
			 current_argv,
			 my_error_string  );

    usage_len = strlen( oneline_usage );

    len = strlen(p);
    strncpy( &p[len], oneline_usage, usage_len );
    sprintf( &p[len+usage_len], "%s", error_epilogue );

    if (error_msg)
	*error_msg = p;
    else
    {
	globus_libc_fprintf( stderr, "%s", p );
	free(p);
    }

    return GLOBUS_SUCCESS;
}
Пример #2
0
int
globus_validate_int( char *         value,
                     void *         parms,
                     char **        error_msg )
{
    int                             val;
    char *                          format;
    globus_validate_int_parms_t *   range;

    if (!parms)
    {
	*error_msg = _GCSL(globus_l_validate_error_null_parms);
	return GLOBUS_FAILURE;
    }

    format = "%d";
    range = (globus_validate_int_parms_t *) parms;

    /* if the string starts with '0', then it's octal or hex */
    /* if the string starts with '0x' or '0X', then it's hex */
    if ( value[0] == '0' )
    {
        format = "%o";
        if ( !strncmp(value, "0x",2) || !strncmp(value, "0X",2) )
            format = "%x";
    }

    if ( !sscanf(value, format, &val ) )
    {
        *error_msg = _GCSL(globus_l_validate_error_not_an_int);
        return GLOBUS_FAILURE;
    }

    if (range->range_type == GLOBUS_VALIDATE_INT_NOCHECK)
        return GLOBUS_SUCCESS;

    if (!(range->range_type & GLOBUS_VALIDATE_INT_MINMAX))
    {
        *error_msg = _GCSL(globus_l_validate_error_range_type);
        return GLOBUS_FAILURE;
    }
    if ((range->range_type & GLOBUS_VALIDATE_INT_MIN) &&
        (range->range_min > val))
    {
	globus_libc_sprintf(globus_l_validate_error_buf,
			    _GCSL("value is smaller than allowed min=%d"),
			    range->range_min);
	*error_msg = globus_l_validate_error_buf;
        return GLOBUS_FAILURE;
    }
    if ((range->range_type & GLOBUS_VALIDATE_INT_MAX) &&
        (range->range_max < val))
    {
	globus_libc_sprintf(globus_l_validate_error_buf,
			    _GCSL("value is larger than allowed max=%d"),
			    range->range_max);
        *error_msg = globus_l_validate_error_buf;
        return GLOBUS_FAILURE;
    }

    return GLOBUS_SUCCESS;
}
Пример #3
0
void
test1(void)
{
    globus_result_t			result;
    globus_object_t *			err;
    test_monitor_t 			monitor;
    globus_io_handle_t			handle;

    test_monitor_initialize(&monitor, GLOBUS_NULL);
    
    /* simple connection to known services with read and write */
    result = globus_io_tcp_register_connect(
	"localhost",
	25,
	GLOBUS_NULL,
	test1_connect_callback,
	(void *) &monitor,
	&handle);

    if(result != GLOBUS_SUCCESS)
    {
	globus_mutex_lock(&monitor.mutex);
	
	monitor.err = globus_error_get(result);
	monitor.use_err = GLOBUS_TRUE;
	monitor.done = GLOBUS_TRUE;

	globus_mutex_unlock(&monitor.mutex);
    }

    globus_mutex_lock(&monitor.mutex);
    while(!monitor.done)
    {
	globus_cond_wait(&monitor.cond,
			 &monitor.mutex);
    }
    globus_mutex_unlock(&monitor.mutex);

    if(monitor.use_err)
    {
	globus_libc_printf("test 1 failed connecting\n");
	globus_object_free(monitor.err);
	
	goto finish;
    }

    test_monitor_reset(&monitor);
    
    result = globus_io_register_read(&handle,
				     test_buffer,
				     test_buffer_size,
				     1,
				     test1_read_callback,
				     &monitor);
    if(result != GLOBUS_SUCCESS)
    {
	globus_mutex_lock(&monitor.mutex);
	
	monitor.err = globus_error_get(result);
	monitor.use_err = GLOBUS_TRUE;
	monitor.done = GLOBUS_TRUE;

	globus_mutex_unlock(&monitor.mutex);
    }

    globus_mutex_lock(&monitor.mutex);
    while(!monitor.done)
    {
	globus_cond_wait(&monitor.cond,
			 &monitor.mutex);
    }
    globus_mutex_unlock(&monitor.mutex);

    if(monitor.use_err)
    {
	globus_libc_printf("test 1 failed reading\n");
	globus_object_free(monitor.err);
	
	goto finish;
    }
    else
    {
	globus_libc_printf("test 1 read message:\n%s\n",
			   test_buffer);
    }
    
    test_monitor_reset(&monitor);

    globus_libc_sprintf((char *) test_buffer, "quit\n");
    
    result = globus_io_register_write(&handle,
				     test_buffer,
				     strlen((char *) test_buffer),
				     test1_write_callback,
				     &monitor);
    if(result != GLOBUS_SUCCESS)
    {
	globus_mutex_lock(&monitor.mutex);
	
	monitor.err = globus_error_get(result);
	monitor.use_err = GLOBUS_TRUE;
	monitor.done = GLOBUS_TRUE;

	globus_mutex_unlock(&monitor.mutex);
    }

    globus_mutex_lock(&monitor.mutex);
    while(!monitor.done)
    {
	globus_cond_wait(&monitor.cond,
			 &monitor.mutex);
    }
    globus_mutex_unlock(&monitor.mutex);

    if(monitor.use_err)
    {
	globus_libc_printf("test 1 failed writing\n");
	globus_object_free(monitor.err);
	
	goto finish;
    }
    else
    {
	globus_libc_printf("test 1 write message:\n%s\n",
			   test_buffer);
    }
    test_monitor_reset(&monitor);
    
    result = globus_io_register_read(&handle,
				     test_buffer,
				     test_buffer_size,
				     1,
				     test1_read_callback,
				     &monitor);
    if(result != GLOBUS_SUCCESS)
    {
	globus_mutex_lock(&monitor.mutex);
	
	monitor.err = globus_error_get(result);
	monitor.use_err = GLOBUS_TRUE;
	monitor.done = GLOBUS_TRUE;

	globus_mutex_unlock(&monitor.mutex);
    }

    globus_mutex_lock(&monitor.mutex);
    while(!monitor.done)
    {
	globus_cond_wait(&monitor.cond,
			 &monitor.mutex);
    }
    globus_mutex_unlock(&monitor.mutex);

    if(monitor.use_err)
    {
	globus_libc_printf("test 1 failed reading\n");
	globus_object_free(monitor.err);
	
	goto finish;
    }
    else
    {
	globus_libc_printf("test 1 read message:\n%s\n",
			   test_buffer);
    }

    test_monitor_reset(&monitor);

    result = globus_io_close(&handle);
    if(result != GLOBUS_SUCCESS)
    {
	err = globus_error_get(result);
	
	globus_libc_printf("test 1 failed closing\n");
    }

    globus_libc_printf("test 1 successful\n");
    
  finish:
    test_monitor_destroy(&monitor);
}
Пример #4
0
static int mpich_type_to_vmpi_type(
    MPI_Datatype			datatype)
{
    int					rc;
    
    DEBUG_FN_ENTRY(DEBUG_MODULE_TYPES);
    DEBUG_PRINTF(DEBUG_MODULE_TYPES, DEBUG_INFO_ARGS,
		 ("datatype=%d\n", datatype));

    /*
     g* Note: MPICH maps MPI_CHARACTER to MPI_CHAR and MPI_LONG_LONG to
     * MPI_LONG_LONG_INT so we have no way to distiguish the types from the
     * ones upon which they are mapped.
     */
    switch(datatype)
    {
      case MPI_CHAR:			rc = VMPI_CHAR;			break;
      case MPI_UNSIGNED_CHAR:		rc = VMPI_UNSIGNED_CHAR;	break;
      case MPI_BYTE:			rc = VMPI_BYTE;			break;
      case MPI_SHORT:			rc = VMPI_SHORT;		break;
      case MPI_UNSIGNED_SHORT:		rc = VMPI_UNSIGNED_SHORT;	break;
      case MPI_INT:			rc = VMPI_INT;			break;
      case MPI_UNSIGNED:		rc = VMPI_UNSIGNED;		break;
      case MPI_LONG:			rc = VMPI_LONG;			break;
      case MPI_UNSIGNED_LONG:		rc = VMPI_UNSIGNED_LONG;	break;
      case MPI_FLOAT:			rc = VMPI_FLOAT;		break;
      case MPI_DOUBLE:			rc = VMPI_DOUBLE;		break;
      case MPI_LONG_DOUBLE:		rc = VMPI_LONG_DOUBLE;		break;
      case MPI_LONG_LONG_INT:		rc = VMPI_LONG_LONG_INT;	break;
      case MPI_PACKED:			rc = VMPI_PACKED;		break;
      case MPI_LB:			rc = VMPI_LB;			break;
      case MPI_UB:			rc = VMPI_UB;			break;
      case MPI_FLOAT_INT:		rc = VMPI_FLOAT_INT;		break;
      case MPI_DOUBLE_INT:		rc = VMPI_DOUBLE_INT;		break;
      case MPI_LONG_INT:		rc = VMPI_LONG_INT;		break;
      case MPI_SHORT_INT:		rc = VMPI_SHORT_INT;		break;
      case MPI_2INT:			rc = VMPI_2INT;			break;
      case MPI_LONG_DOUBLE_INT:		rc = VMPI_LONG_DOUBLE_INT;	break;
      case MPI_COMPLEX:			rc = VMPI_COMPLEX;		break;
      case MPI_DOUBLE_COMPLEX:		rc = VMPI_DOUBLE_COMPLEX;	break;
      case MPI_LOGICAL:			rc = VMPI_LOGICAL;		break;
      case MPI_REAL:			rc = VMPI_REAL;			break;
      case MPI_DOUBLE_PRECISION:	rc = VMPI_DOUBLE_PRECISION;	break;
      case MPI_INTEGER:			rc = VMPI_INTEGER;		break;
      case MPI_2INTEGER:		rc = VMPI_2INTEGER;		break;
      case MPI_2COMPLEX:		rc = VMPI_2COMPLEX;		break;
      case MPI_2DOUBLE_COMPLEX:		rc = VMPI_2DOUBLE_COMPLEX;	break;
      case MPI_2REAL:			rc = VMPI_2REAL;		break;
      case MPI_2DOUBLE_PRECISION:	rc = VMPI_2DOUBLE_PRECISION;	break;

      default:
      {
	 char err[1024];
	 globus_libc_sprintf(
	    err, 
	    "mpich_type_to_vmpi_type() -  encountered unrecognizable type %d", 
	    datatype);
	  MPID_Abort(NULL,
                   0,
                   "MPICH-G2 (internal error)",
		   err);
       }
         break;
     } /* end switch */

  /* fn_exit: */
    DEBUG_PRINTF(DEBUG_MODULE_TYPES, DEBUG_INFO_RC,
		 ("rc=%d\n", rc));
    DEBUG_FN_EXIT(DEBUG_MODULE_TYPES);
    return rc;
}
/**
 * @brief Create a HTTP-framed copy of a GRAM request
 * @ingroup globus_gram_protocol_framing
 *
 * @details
 * The globus_gram_protocol_frame_request() function adds HTTP 1.1
 * framing around the input message. The framed message includes HTTP headers 
 * relating the the destination URL and the length of the message content.
 * The framed message is returned by modifying @a framedmsg to point to a
 * newly allocated string. The integer pointed to by the @a framedsize
 * parameter is set to the length of this message.
 *
 * @param url
 *        The URL of the GRAM resource to contact. This is parsed and used
 *        to generate the HTTP POST operation destination and the Host
 *        HTTP header.
 * @param msg
 *        A string containing the message content to be framed.
 * @param msgsize
 *        The length of the string pointed to by @a msg
 * @param framedmsg
 *        An output parameter which will be set to a copy of the @a msg string
 *        with an HTTP frame around it.
 * @param framedsize
 *        An output parameter which will be set to the length of the 
 *        framed message.
 *
 * @return
 *     Upon success, globus_gram_protocol_frame_request() will return
 *     GLOBUS_SUCCESS and the @a framedmsg and @a framedsize parameters will be
 *     modified to point to the new framed message string and its length
 *     respectively. When this occurs, the caller is responsible for freeing
 *     the string pointed to by @a framedmsg. If an error occurs, its value
 *     will returned and the @a framedmsg and @a framedsize parameters will 
 *     be uninitialized.
 *
 * @retval GLOBUS_SUCCESS
 *     Success
 * @retval GLOBUS_GRAM_PROTOCOL_ERROR_INVALID_JOB_CONTACT
 *     Invalid job contact
 */
int
globus_gram_protocol_frame_request(
    const char *			url,
    const globus_byte_t *		msg,
    globus_size_t			msgsize,
    globus_byte_t **			framedmsg,
    globus_size_t *			framedsize)
{
    char *				buf;
    globus_size_t			digits = 0;
    globus_size_t			tmp;
    globus_size_t			framedlen;
    globus_url_t			parsed;
    int					rc;

    rc = globus_url_parse(url, &parsed);

    if(rc != GLOBUS_SUCCESS)
    {
	rc = GLOBUS_GRAM_PROTOCOL_ERROR_INVALID_JOB_CONTACT;

        goto out;
    }

    if (parsed.url_path == NULL)
    {
	rc = GLOBUS_GRAM_PROTOCOL_ERROR_INVALID_JOB_CONTACT;

        goto destroy_out;
    }

    /*
     * HTTP request message framing:
     *    POST <uri> HTTP/1.1<CR><LF>
     *    Host: <hostname><CR><LF>
     *    Content-Type: application/x-globus-gram<CR><LF>
     *    Content-Length: <msgsize><CR><LF>
     *    <CR><LF>
     *    <msg>
     */
    tmp = msgsize;

    do
    {
	tmp /= 10;
	digits++;
    }
    while(tmp > 0);

    framedlen  = strlen(GLOBUS_GRAM_HTTP_REQUEST_LINE);
    framedlen += strlen((char *) parsed.url_path);
    framedlen += strlen(GLOBUS_GRAM_HTTP_HOST_LINE);
    framedlen += strlen((char *) parsed.host);
    framedlen += strlen(GLOBUS_GRAM_HTTP_CONTENT_TYPE_LINE);
    framedlen += strlen(GLOBUS_GRAM_HTTP_CONTENT_LENGTH_LINE);
    framedlen += digits;
    framedlen += 2;
    framedlen += msgsize;

    buf = (char *) globus_libc_malloc(framedlen + 1 /*null terminator*/);

    tmp  = 0;
    tmp += globus_libc_sprintf(buf + tmp,
			      GLOBUS_GRAM_HTTP_REQUEST_LINE,
			      parsed.url_path);
    tmp += globus_libc_sprintf(buf + tmp,
			      GLOBUS_GRAM_HTTP_HOST_LINE,
			      parsed.host);
    tmp += globus_libc_sprintf(buf + tmp,
			       GLOBUS_GRAM_HTTP_CONTENT_TYPE_LINE);
    tmp += globus_libc_sprintf(buf + tmp,
			       GLOBUS_GRAM_HTTP_CONTENT_LENGTH_LINE,
			       (long) msgsize);
    tmp += globus_libc_sprintf(buf + tmp,
			       CRLF);

    if (msgsize > 0)    /* allow for empty message body (msg==NULL) */
    {
	memcpy(buf + tmp,
	       msg,
	       msgsize);
    }

    *framedmsg = (globus_byte_t *) buf;
    *framedsize = tmp + msgsize;

destroy_out:
    globus_url_destroy(&parsed);
out:
    return rc;
}
/**
 * @brief Create a HTTP-framed copy of a GRAM reply
 * @ingroup globus_gram_protocol_framing
 *
 * @details
 * The globus_gram_protocol_frame_reply() function adds HTTP 1.1
 * framing around the input message. The framed message includes HTTP headers 
 * relating the the status of the operation being replied to and the length of
 * the message content.  The framed message is returned by modifying
 * @a framedmsg to point to a newly allocated string. The integer pointed to by
 * the @a framedsize
 * parameter is set to the length of this message.
 *
 * @param code
 *        The HTTP response code to send along with this reply.
 * @param msg
 *        A string containing the reply message content to be framed.
 * @param msgsize
 *        The length of the string pointed to by @a msg.
 * @param framedmsg
 *        An output parameter which will be set to a copy of the @a msg
 *        string with an HTTP reply frame around it.
 * @param framedsize
 *        An output parameter which will be set to the length of the 
 *        framed reply string pointed to by @a framedmsg.
 *
 * @return
 *     Upon success, globus_gram_protocol_frame_reply() will return
 *     GLOBUS_SUCCESS and the @a framedmsg and @a framedsize parameters will be
 *     modified to point to the new framed message string and its length
 *     respectively. When this occurs, the caller is responsible for freeing
 *     the string pointed to by @a framedmsg. If an error occurs, its value
 *     will returned and the @a framedmsg and @a framedsize parameters will 
 *     be uninitialized.
 *
 * @retval GLOBUS_SUCCESS
 *     Success
 */
int
globus_gram_protocol_frame_reply(
    int					code,
    const globus_byte_t *		msg,
    globus_size_t			msgsize,
    globus_byte_t **			framedmsg,
    globus_size_t *			framedsize)
{
    char *				buf;
    char *				reason;
    globus_size_t			digits = 0;
    globus_size_t			tmp;
    globus_size_t			framedlen;

    /*
     * HTTP reply message framing:
     *    HTTP/1.1 <3 digit code> Reason String<CR><LF>
     *    Connection: close<CR><LF>
     *    <CR><LF>
     *
     * or
     *    HTTP/1.1 <3 digit code> Reason String<CR><LF>
     *    Content-Type: application/x-globus-gram<CR><LF>
     *    Content-Length: <msgsize><CR><LF>
     *    <CR><LF>
     *    msg
     */

    reason = globus_l_gram_protocol_lookup_reason(code);

    if(msgsize == 0)
    {
	framedlen = 0;
	framedlen += strlen(GLOBUS_GRAM_HTTP_REPLY_LINE);
	framedlen += strlen(reason);
	framedlen += strlen(GLOBUS_GRAM_HTTP_CONNECTION_LINE);

	buf = (char *) globus_malloc(framedlen + 1 /* null terminator */);

	tmp = 0;
	tmp += globus_libc_sprintf(buf + tmp,
				   GLOBUS_GRAM_HTTP_REPLY_LINE,
				   code,
				   reason);
	tmp += globus_libc_sprintf(buf + tmp,
				   GLOBUS_GRAM_HTTP_CONNECTION_LINE);
	tmp += globus_libc_sprintf(buf + tmp,
				   CRLF);
    }
    else
    {
	tmp = msgsize;

	do
	{
	    tmp /= 10;
	    digits++;
	}
	while(tmp > 0);

	framedlen = 0;
	framedlen += strlen(GLOBUS_GRAM_HTTP_REPLY_LINE);
	framedlen += strlen(reason);
	framedlen += strlen(GLOBUS_GRAM_HTTP_CONTENT_TYPE_LINE);
	framedlen += strlen(GLOBUS_GRAM_HTTP_CONTENT_LENGTH_LINE);
	framedlen += digits;
	framedlen += 2;
	framedlen += msgsize;

	buf = (char *) globus_malloc(framedlen);
	tmp = 0;
	tmp += globus_libc_sprintf(buf + tmp,
				   GLOBUS_GRAM_HTTP_REPLY_LINE,
				   code,
				   reason);
	tmp += globus_libc_sprintf(buf + tmp,
		       GLOBUS_GRAM_HTTP_CONTENT_TYPE_LINE);
	tmp += globus_libc_sprintf(buf + tmp,
		       GLOBUS_GRAM_HTTP_CONTENT_LENGTH_LINE,
		       (long)msgsize);
	tmp += globus_libc_sprintf(buf + tmp,
		       CRLF);

	if (msgsize > 0)   /* this allows msg = NULL */
	{
	    memcpy(buf + tmp,
		   msg,
		   msgsize);
	}
    }


    *framedmsg = (globus_byte_t *) buf;
    *framedsize = tmp + msgsize;

    return GLOBUS_SUCCESS;
}
/**
 * Create a string representation of a restart marker.
 * @ingroup globus_ftp_client_restart_marker
 *
 * This function sets the @a marker_string parameter to point to
 * a freshly allocated string suitable for sending as an argument to
 * the FTP REST command, or for a later call to
 * globus_ftp_client_restart_marker_from_string().
 *
 * The string pointed to by marker_string must be freed by the caller.
 *
 * @param marker
 *        An initialized FTP client restart marker.
 * @param marker_string
 *        A pointer to a char * to be set to a freshly allocated marker
 *        string.
 *
 * @see globus_ftp_client_restart_marker
 */
globus_result_t
globus_ftp_client_restart_marker_to_string(
    globus_ftp_client_restart_marker_t *	marker,
    char **					marker_string)
{
    int					length = 0, mylen;
    char *				buf = GLOBUS_NULL;
    char *				tbuf;
    globus_i_ftp_client_range_t *	range;
    globus_fifo_t *			tmp;
    globus_off_t			offset;
    globus_size_t			digits;
    globus_object_t *			err;
    GlobusFuncName(globus_ftp_client_restart_marker_to_string);

    if(marker == GLOBUS_NULL)
    {
        return globus_error_put(
		GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("marker"));
    }
    else if(marker_string == GLOBUS_NULL)
    {
        return globus_error_put(
		GLOBUS_I_FTP_CLIENT_ERROR_NULL_PARAMETER("marker_string"));
    }

    (*marker_string) = GLOBUS_NULL;

    if(marker->type == GLOBUS_FTP_CLIENT_RESTART_NONE)
    {
	return GLOBUS_SUCCESS;
    }
    else if(marker->type == GLOBUS_FTP_CLIENT_RESTART_STREAM)
    {
        if(marker->stream.ascii_offset > marker->stream.offset)
	{
	    offset = marker->stream.ascii_offset;
	}
	else
	{
	    offset = marker->stream.offset;
	}
        digits = globus_i_ftp_client_count_digits(offset);

	(*marker_string) = globus_libc_malloc(digits+1);

	if(!(*marker_string))
	{
	    err = GLOBUS_I_FTP_CLIENT_ERROR_OUT_OF_MEMORY();

	    if(!err)
	    {
	        err = GLOBUS_ERROR_NO_INFO;
	    }

	    goto error_exit;
	}

	globus_libc_sprintf((*marker_string),
	                    "%lu",
			    (unsigned long) offset);
    }
    else if(marker->type == GLOBUS_FTP_CLIENT_RESTART_EXTENDED_BLOCK &&
            !globus_fifo_empty(&marker->extended_block.ranges))
    {
        tmp = globus_fifo_copy(&marker->extended_block.ranges);

        while((! globus_fifo_empty(tmp)))
        {
	    range = (globus_i_ftp_client_range_t *) globus_fifo_dequeue(tmp);

	    mylen = globus_i_ftp_client_count_digits(range->offset);
	    mylen++;
	    mylen += globus_i_ftp_client_count_digits(range->end_offset);
	    mylen++;
            
            if(buf)
            {
	        tbuf = realloc(buf, length + mylen + 1);
            }
            else
            {
                tbuf = malloc(length + mylen + 1);
            }
            
	    if(!tbuf)
	    {
		err = GLOBUS_I_FTP_CLIENT_ERROR_OUT_OF_MEMORY();

	        if(!err)
	        {
	            err = GLOBUS_ERROR_NO_INFO;
	        }
		goto buf_err;
	    }
	    else
	    {
	        buf = tbuf;
	    }
	    length += globus_libc_sprintf(
	        buf + length,
	        "%"GLOBUS_OFF_T_FORMAT"-%"GLOBUS_OFF_T_FORMAT",",
	        range->offset,
	        range->end_offset);
        }
        buf[strlen(buf)-1] = '\0';
	(*marker_string) = buf;
	
	globus_fifo_destroy(tmp);
        globus_libc_free(tmp);
    }

    return GLOBUS_SUCCESS;

  buf_err:
	globus_fifo_destroy(tmp);
    globus_libc_free(buf);
  error_exit:
    return globus_error_put(err);
}