Esempio n. 1
0
/************************************************************************
 *                  stack functions
 ***********************************************************************/
globus_result_t
globus_xio_stack_init(
    globus_xio_stack_t *                stack,
    globus_xio_attr_t                   stack_attr)
{
    globus_i_xio_stack_t *              xio_stack;
    GlobusXIOName(globus_xio_stack_init);

    GlobusXIODebugEnter();
    
    if(stack == NULL)
    {
        GlobusXIODebugExitWithError();
        return GlobusXIOErrorParameter("stack");
    }

    xio_stack = globus_malloc(sizeof(globus_i_xio_stack_t));
    memset(xio_stack, '\0', sizeof(globus_i_xio_stack_t));

    *stack = xio_stack;

    GlobusXIODebugExit();

    return GLOBUS_SUCCESS;
}
Esempio n. 2
0
globus_result_t
globus_xio_string_cntl_formated_int(
    void *                              attr,
    const char *                        key,
    const char *                        val,
    int                                 cmd,
    globus_xio_driver_attr_cntl_t       cntl_func)
{
    int                                 sc;
    int                                 i;
    globus_off_t                        o;
    globus_result_t                     result = GLOBUS_SUCCESS;
    GlobusXIOName(globus_xio_string_cntl_formated_int);

    GlobusXIODebugEnter();

    sc = globus_xio_string_cntl_tb_kmgint(val, &o);
    if(sc != 0)
    {
        result = GlobusXIOErrorParse(val);
    }
    else
    {
        i = (int) o;
        result = globus_xio_string_cntl_bouncer(cntl_func, attr, cmd, i);
    }
    GlobusXIODebugExit();
    return result;
}
Esempio n. 3
0
globus_result_t
globus_xio_string_cntl_float(
    void *                              attr,
    const char *                        key,
    const char *                        val,
    int                                 cmd,
    globus_xio_driver_attr_cntl_t       cntl_func)
{
    int                                 sc;
    float                               f;
    globus_result_t                     result = GLOBUS_SUCCESS;
    GlobusXIOName(globus_xio_string_cntl_float);

    GlobusXIODebugEnter();

    sc = sscanf(val, "%f", &f);
    if(sc != 1)
    {
        result = GlobusXIOErrorParse(val);
    }
    else
    {
        result = globus_xio_string_cntl_bouncer(cntl_func, attr, cmd, f);
    }
    GlobusXIODebugExit();
    return result;
}
static globus_result_t
globus_l_xio_bounce_init(
    globus_xio_driver_t *               out_driver)
{
    globus_xio_driver_t                 driver;
    globus_result_t                     res;
    GlobusXIOName(globus_l_xio_bounce_init);

    GlobusXIOTestDebugInternalEnter();
    res = globus_xio_driver_init(&driver, "bounce", NULL);
    if(res != GLOBUS_SUCCESS)
    {
        return res;
    }

    globus_xio_driver_set_transform(
        driver,
        globus_l_xio_bounce_open,
        globus_l_xio_bounce_close,
        globus_l_xio_bounce_read,
        globus_l_xio_bounce_write,
        globus_l_xio_bounce_cntl,
        NULL);

    *out_driver = driver;

    GlobusXIOTestDebugInternalExit();
    return GLOBUS_SUCCESS;
}
Esempio n. 5
0
globus_result_t
globus_xio_stack_destroy(
    globus_xio_stack_t                  stack)
{
    globus_result_t                     res;
    GlobusXIOName(globus_xio_stack_destroy);

    GlobusXIODebugEnter();
    
    if(stack == NULL)
    {
        res = GlobusXIOErrorParameter("stack");
        goto err;
    }

    globus_list_free(stack->driver_stack);
    globus_free(stack);

    GlobusXIODebugExit();
    return GLOBUS_SUCCESS;

  err:

    GlobusXIODebugExitWithError();
    return res;
}
void
bounce_cb(
    globus_xio_operation_t              op,
    globus_result_t                     result,
    void *                              user_arg)
{
    bounce_info_t *                     info;
    globus_result_t                     res;
    GlobusXIOName(bounce_cb);

    GlobusXIOTestDebugInternalEnter();
    info = (bounce_info_t *) user_arg;
    info->res = result;
    info->wait_for = 1024;
    info->iovec = &info->tmp_iovec;
    info->iovec->iov_base = (globus_byte_t *) 0x100;
    info->iovec->iov_len = 1024;
    info->iovec_count = 1;

    if(result != GLOBUS_SUCCESS)
    {
        GlobusXIOTestDebugPrintf(GLOBUS_XIO_TEST_DEBUG_STATE,
            ("[%s] : result != Success\n", _xio_name));
        info->next_op = TEST_FINISH;
    }

    res = test_bounce_next_op(info, op);
    if(res != GLOBUS_SUCCESS)
    {
        info->res = res;
        test_bounce_finish_op(info, op);
    }
    GlobusXIOTestDebugInternalExit();
}
void
bounce_data_cb(
    globus_xio_operation_t              op,
    globus_result_t                     result,
    globus_size_t                       nbytes,
    void *                              user_arg)
{
    bounce_info_t *                     info;
    globus_result_t                     res;
    GlobusXIOName(bounce_data_cb);

    GlobusXIOTestDebugInternalEnter();
    info = (bounce_info_t *) user_arg;
    info->res = result;
    info->nbytes = nbytes;

    if(result != GLOBUS_SUCCESS)
    {
        GlobusXIOTestDebugPrintf(GLOBUS_XIO_TEST_DEBUG_STATE,
            ("[%s] : result != Success\n", _xio_name));
        info->next_op = TEST_FINISH;
    }

    res = test_bounce_next_op(info, op);
    if(res != GLOBUS_SUCCESS)
    {
        info->res = res;
        test_bounce_finish_op(info, op);
    }
    GlobusXIOTestDebugInternalExit();
}
static
globus_result_t
globus_l_xio_popen_init_child_pipe(
    int                                 fd,
    globus_xio_system_file_handle_t *   out_system)
{
    globus_result_t                     result;
    GlobusXIOName(globus_l_xio_popen_init_child_pipe);

#ifndef WIN32
    fcntl(fd, F_SETFD, FD_CLOEXEC);
#endif

    result = globus_xio_system_file_init(out_system, fd);
    if(result != GLOBUS_SUCCESS)
    {
        result = GlobusXIOErrorWrapFailed(
            "globus_xio_system_file_init", result);
        goto error_init;
    }

    return GLOBUS_SUCCESS;

error_init:

    return result;
}
static
void
globus_l_xio_popen_system_write_cb(
    globus_result_t                     result,
    globus_size_t                       nbytes,
    void *                              user_arg)
{
    globus_xio_operation_t              op;
    xio_l_popen_handle_t *              handle;
    GlobusXIOName(globus_l_xio_popen_system_write_cb);
    
    GlobusXIOPOpenDebugEnter();
    
    op = (globus_xio_operation_t) user_arg;
    
    handle = (xio_l_popen_handle_t *) 
        globus_xio_operation_get_driver_specific(op);
        
    handle->canceled = globus_xio_operation_is_canceled(op);

    globus_l_xio_popen_update_position(
        handle,
        nbytes,
        SEEK_CUR);
        
    globus_xio_driver_finished_write(op, result, nbytes);
    
    GlobusXIOPOpenDebugExit();
}
static
globus_result_t
globus_l_xio_popen_handle_init(
    xio_l_popen_handle_t **             handle)
{
    globus_result_t                     result;
    GlobusXIOName(globus_l_xio_popen_handle_init);
    
    GlobusXIOPOpenDebugEnter();
    
    *handle = (xio_l_popen_handle_t *)
        globus_calloc(1, sizeof(xio_l_popen_handle_t));
    if(!*handle)
    {
        result = GlobusXIOErrorMemory("handle");
        goto error_handle;
    }
    
    globus_mutex_init(&(*handle)->lock, NULL);
    
    GlobusXIOPOpenDebugExit();
    return GLOBUS_SUCCESS;

error_handle:
    GlobusXIOPOpenDebugExitWithError();
    return result;    
}
static
int
globus_l_xio_popen_activate(void)
{
    int                                 rc;
    
    GlobusXIOName(globus_l_xio_popen_activate);
    
    GlobusDebugInit(GLOBUS_XIO_POPEN, TRACE INFO);
    
    GlobusXIOPOpenDebugEnter();
    
    rc = globus_module_activate(GLOBUS_XIO_SYSTEM_MODULE);
    if(rc != GLOBUS_SUCCESS)
    {
        goto error_activate;
    }
    
    GlobusXIORegisterDriver(popen);
    
    GlobusXIOPOpenDebugExit();
    return GLOBUS_SUCCESS;

error_activate:
    GlobusXIOPOpenDebugExitWithError();
    GlobusDebugDestroy(GLOBUS_XIO_POPEN);
    return rc;
}
globus_result_t
globus_i_xio_system_file_try_write(
    globus_xio_system_file_t            handle,
    const globus_xio_iovec_t *          iov,
    int                                 iovc,
    globus_size_t *                     nbytes)
{
    globus_result_t                     result;
    GlobusXIOName(globus_i_xio_system_file_try_write);

    GlobusXIOSystemDebugEnter();

    if(iovc == 1)
    {
        result = globus_i_xio_system_try_write(
            handle, iov->iov_base, iov->iov_len, nbytes);
    }
    else
    {
        result = globus_i_xio_system_try_writev(handle, iov, iovc, nbytes);
    }

    GlobusXIOSystemDebugExit();
    return result;
}
static
globus_result_t
globus_l_xio_pipe_attr_init(
    void **                             out_attr)
{
    xio_l_pipe_attr_t *                 attr;
    globus_result_t                     result;
    GlobusXIOName(globus_l_xio_pipe_attr_init);

    GlobusXIOPipeDebugEnter();
    /*
     *  create a file attr structure and intialize its values
     */
    attr = (xio_l_pipe_attr_t *) globus_malloc(sizeof(xio_l_pipe_attr_t));
    if(!attr)
    {
        result = GlobusXIOErrorMemory("attr");
        goto error_attr;
    }

    memcpy(attr, &xio_l_pipe_attr_default, sizeof(xio_l_pipe_attr_t));
    *out_attr = attr;

    GlobusXIOPipeDebugExit();
    return GLOBUS_SUCCESS;

error_attr:
    GlobusXIOPipeDebugExitWithError();
    return result;
}
/*
 *  copy an attribute structure
 */
static
globus_result_t
globus_l_xio_pipe_attr_copy(
    void **                             dst,
    void *                              src)
{
    xio_l_pipe_attr_t *                 attr;
    xio_l_pipe_attr_t *                 src_attr;
    globus_result_t                     result;
    GlobusXIOName(globus_l_xio_pipe_attr_copy);

    GlobusXIOPipeDebugEnter();

    src_attr = (xio_l_pipe_attr_t *) src;
    attr = (xio_l_pipe_attr_t *) globus_malloc(sizeof(xio_l_pipe_attr_t));
    if(!attr)
    {
        result = GlobusXIOErrorMemory("attr");
        goto error_attr;
    }

    memcpy(attr, src_attr, sizeof(xio_l_pipe_attr_t));
    *dst = attr;

    GlobusXIOPipeDebugExit();
    return GLOBUS_SUCCESS;

error_attr:
    GlobusXIOPipeDebugExitWithError();
    return result;
}
/**
 * Copy the contents of a header information structure.
 * @ingroup globus_i_xio_http_header_info
 *
 * All values associated with the @a src header information structure will
 * be copied to the @a dest one. If this function returns a failure, then the
 * @a dest structure should be considered uninitialized.
 *
 * @param dest
 *     Header information structure to initialize. This should not be
 *     initialized before this function is called, or memory may be leaked.
 * @param src
 *     Header information structure containing valid values.
 *
 * @retval GLOBUS_SUCCESS
 *     Structure successfully copied.
 * @retval GLOBUS_XIO_ERROR_MEMORY
 *     Copy failed due to memory constraints.
 */
globus_result_t
globus_i_xio_http_header_info_copy(
    globus_i_xio_http_header_info_t *   dest,
    const globus_i_xio_http_header_info_t *
                                        src)
{
    int                                 rc;
    globus_result_t                     result = GLOBUS_SUCCESS;

    GlobusXIOName(globus_i_xio_http_header_info_init);
    rc = globus_hashtable_copy(
            &dest->headers,
            (globus_hashtable_t *) &src->headers,
            globus_i_xio_http_header_copy);
    if (rc != GLOBUS_SUCCESS)
    {
        result = GlobusXIOErrorMemory("hashtable");

        goto error_exit;
    }

    dest->content_length = src->content_length;
    dest->transfer_encoding = src->transfer_encoding;
    dest->flags = src->flags;

    return result;

error_exit:
    return result;
}
Esempio n. 16
0
static int
globus_l_xio_telnet_deactivate(void)
{
    GlobusXIOName(globus_l_xio_telnet_deactivate);
    GlobusXIOUnRegisterDriver(telnet);
    return globus_module_deactivate(GLOBUS_XIO_MODULE);
}
Esempio n. 17
0
static globus_result_t
globus_l_xio_telnet_accept(
    void *                              driver_server,
    globus_xio_operation_t              accept_op)
{
    globus_result_t                     res;
    globus_l_xio_telnet_attr_t *        attr;
    GlobusXIOName(globus_l_xio_telnet_accept);
   
    res = globus_l_xio_telnet_attr_copy((void **) (void *) &attr, driver_server);
    if(res != GLOBUS_SUCCESS)
    {
        goto error;
    }
    res = globus_xio_driver_pass_accept(
        accept_op, globus_l_xio_telnet_accept_cb, attr);
    if(res != GLOBUS_SUCCESS)
    {
        goto error_pass;
    }
    return GLOBUS_SUCCESS;
error_pass:
    globus_l_xio_telnet_server_destroy(attr);
error:
    return res;
}
Esempio n. 18
0
static void
globus_l_xio_telnet_destroy(
    globus_xio_driver_t                 driver)
{
    GlobusXIOName(globus_l_xio_telnet_destroy);
    globus_xio_driver_destroy(driver);
}
Esempio n. 19
0
static globus_result_t
globus_l_xio_telnet_attr_cntl(
    void *                              driver_attr,
    int                                 cmd,
    va_list                             ap)
{
    globus_l_xio_telnet_attr_t *        attr;
    globus_result_t                     res;
    GlobusXIOName(globus_l_xio_telnet_attr_cntl);

    attr = (globus_l_xio_telnet_attr_t *) driver_attr;

    switch(cmd)
    {
        case GLOBUS_XIO_TELNET_BUFFER:
            attr->create_buffer_mode = va_arg(ap, globus_bool_t);
            break;

        case GLOBUS_XIO_TELNET_FORCE_SERVER:
            attr->force_server = va_arg(ap, globus_bool_t);
            break;

        default:
            res = GlobusXIOErrorInvalidCommand(cmd);
            return res;
    }

    return GLOBUS_SUCCESS;
}
Esempio n. 20
0
static
globus_result_t
globus_l_xio_telnet_server_init(
    void *                              driver_attr,
    const globus_xio_contact_t *        contact_info,
    globus_xio_operation_t              op)
{
    globus_result_t                     res;
    globus_l_xio_telnet_attr_t *        attr;
    GlobusXIOName(globus_l_xio_telnet_server_init);

    res = globus_l_xio_telnet_attr_copy((void **) (void *) &attr, driver_attr);
    if(res != GLOBUS_SUCCESS)
    {
        goto error;
    }
    res = globus_xio_driver_pass_server_init(op, contact_info, attr);
    if(res != GLOBUS_SUCCESS)
    {
        goto error_pass;
    }
    return GLOBUS_SUCCESS;
error_pass:
    globus_l_xio_telnet_server_destroy(attr);
error:
    return res;
}
void
globus_xio_system_socket_destroy(
    globus_xio_system_socket_handle_t   handle)
{
    unsigned long                       flag = 0;
    GlobusXIOName(globus_xio_system_socket_destroy);
    
    GlobusXIOSystemDebugEnterFD(handle->socket);
    
    globus_assert(!handle->read_info && !handle->write_info);
    
    /* no need to ensure entry is still registered, as I always return true
     * in the callback and this is only place i unregister
     */
    globus_i_xio_win32_event_lock(handle->event_entry);
    
    GlobusXIOSystemDebugPrintf(
        GLOBUS_I_XIO_SYSTEM_DEBUG_INFO,
        ("[%s] Unregistering event handle=%lu for socket %ld\n",
            _xio_name, (unsigned long) handle->event, (long) handle->socket));
            
    globus_i_xio_win32_event_unregister(handle->event_entry);
    globus_i_xio_win32_event_unlock(handle->event_entry);
    
    WSAEventSelect(handle->socket, 0, 0);
    ioctlsocket(handle->socket, FIONBIO, &flag);
    WSACloseEvent(handle->event);
    win32_mutex_destroy(&handle->lock);
    
    GlobusXIOSystemDebugExitFD(handle->socket);
    globus_free(handle);
}
Esempio n. 22
0
static globus_result_t
globus_l_xio_telnet_attr_copy(
    void **                             out_driver_attr,
    void *                              src_driver_attr)
{
    globus_l_xio_telnet_attr_t *        src_attr;
    globus_l_xio_telnet_attr_t *       dest_attr;
    globus_result_t                     res;
    GlobusXIOName(globus_l_xio_telnet_attr_init);

    if(src_driver_attr == NULL)
    {
        *out_driver_attr = NULL;
        return GLOBUS_SUCCESS;
    }

    res = globus_l_xio_telnet_attr_init((void **) (void *) &dest_attr);
    if(res == GLOBUS_SUCCESS)
    {
        src_attr = (globus_l_xio_telnet_attr_t *) src_driver_attr;
        dest_attr->create_buffer_mode = src_attr->create_buffer_mode;
        dest_attr->force_server = src_attr->force_server;
        
        *out_driver_attr = dest_attr;
    }
    
    return res;
}
globus_result_t
globus_xio_system_socket_create(
    globus_xio_system_socket_t *        sock,
    int                                 domain,
    int                                 type,
    int                                 protocol)
{
    globus_result_t                     result;
    GlobusXIOName(globus_xio_system_socket_create);
    
    *sock = INVALID_SOCKET;
    GlobusXIOSystemDebugEnter();
    
    *sock = socket(domain, type, protocol);
    if(*sock == INVALID_SOCKET)
    {
        result = GlobusXIOErrorSystemError("socket", WSAGetLastError());
        goto error_socket;
    }

    /* all handles created by me are closed on exec */
    SetHandleInformation((HANDLE)*sock, HANDLE_FLAG_INHERIT, 0);

    GlobusXIOSystemDebugExitFD(*sock);
    return GLOBUS_SUCCESS;

error_socket:
    GlobusXIOSystemDebugExitWithErrorFD(*sock);
    return result;
}
globus_result_t
globus_xio_system_socket_getsockopt(
    globus_xio_system_socket_t          socket,
    int                                 level,
    int                                 optname,
    void *                              optval,
    socklen_t *                         optlen)
{
    globus_result_t                     result;
    GlobusXIOName(globus_xio_system_socket_getsockopt);
    
    GlobusXIOSystemDebugEnterFD(socket);
    
    if(getsockopt(socket, level, optname, optval, optlen) == SOCKET_ERROR)
    {
        result = GlobusXIOErrorSystemError("getsockopt", WSAGetLastError());
        goto error_getsockopt;
    }
    
    GlobusXIOSystemDebugExitFD(socket);
    return GLOBUS_SUCCESS;

error_getsockopt:
    GlobusXIOSystemDebugExitWithErrorFD(socket);
    return result;
}
static
int
globus_l_xio_pipe_activate(void)
{
    int                                 rc;
    
    GlobusXIOName(globus_l_xio_pipe_activate);
    
    GlobusDebugInit(GLOBUS_XIO_PIPE, TRACE INFO);
    
    GlobusXIOPipeDebugEnter();
    
    rc = globus_module_activate(GLOBUS_XIO_SYSTEM_MODULE);
    if(rc != GLOBUS_SUCCESS)
    {
        goto error_activate;
    }
#   ifdef _WIN32
    xio_l_pipe_attr_default.infd = GetStdHandle(STD_INPUT_HANDLE);
    xio_l_pipe_attr_default.outfd = GetStdHandle(STD_OUTPUT_HANDLE);
#   endif
    
    GlobusXIORegisterDriver(pipe);
    
    GlobusXIOPipeDebugExit();
    return GLOBUS_SUCCESS;

error_activate:
    GlobusXIOPipeDebugExitWithError();
    GlobusDebugDestroy(GLOBUS_XIO_PIPE);
    return rc;
}
/*
 *  close a file
 */
static
globus_result_t
globus_l_xio_pipe_close(
    void *                              driver_specific_handle,
    void *                              attr,
    globus_xio_operation_t              op)
{
    xio_l_pipe_handle_t *               handle;
    GlobusXIOName(globus_l_xio_pipe_close);

    GlobusXIOPipeDebugEnter();
    
    handle = (xio_l_pipe_handle_t *) driver_specific_handle;
    
    globus_xio_system_file_destroy(handle->in_system);
    globus_xio_system_file_destroy(handle->out_system);
    
    globus_xio_system_file_close(handle->infd);
    globus_xio_system_file_close(handle->outfd);
    
    globus_xio_driver_finished_close(op, GLOBUS_SUCCESS);
    globus_l_xio_pipe_handle_destroy(handle);
    
    GlobusXIOPipeDebugExit();
    return GLOBUS_SUCCESS;
}
static
globus_result_t
globus_l_xio_pipe_handle_init(
    xio_l_pipe_handle_t **              handle,
    xio_l_pipe_attr_t *                 attr)
{
    globus_result_t                     result;
    GlobusXIOName(globus_l_xio_pipe_handle_init);
    
    GlobusXIOPipeDebugEnter();
    
    *handle = (xio_l_pipe_handle_t *)
        globus_calloc(1, sizeof(xio_l_pipe_handle_t));
    if(!*handle)
    {
        result = GlobusXIOErrorMemory("handle");
        goto error_handle;
    }
    
    globus_mutex_init(&(*handle)->lock, NULL);
    (*handle)->use_blocking_io = attr->use_blocking_io;
    (*handle)->infd = attr->infd;
    (*handle)->outfd = attr->outfd;

    GlobusXIOPipeDebugExit();
    return GLOBUS_SUCCESS;

error_handle:
    GlobusXIOPipeDebugExitWithError();
    return result;    
}
static
globus_result_t
globus_l_xio_pipe_attr_cntl(
    void *                              driver_attr,
    int                                 cmd,
    va_list                             ap)
{
    xio_l_pipe_attr_t *                 attr;
    GlobusXIOName(globus_l_xio_pipe_attr_cntl);

    GlobusXIOPipeDebugEnter();

    attr = (xio_l_pipe_attr_t *) driver_attr;

    switch(cmd)
    {
        case GLOBUS_XIO_PIPE_SET_BLOCKING_IO:
            attr->use_blocking_io = va_arg(ap, globus_bool_t);
            break;
        case GLOBUS_XIO_PIPE_SET_IN_HANDLE:
            attr->infd = va_arg(ap, globus_xio_system_file_t);
            break;
        case GLOBUS_XIO_PIPE_SET_OUT_HANDLE:
            attr->outfd = va_arg(ap, globus_xio_system_file_t);
            break;
            
        default:
            break;
    }

    GlobusXIOPipeDebugExit();
    return GLOBUS_SUCCESS;
}
globus_result_t
globus_i_xio_system_try_readv(
    globus_xio_system_file_t            fd,
    const globus_xio_iovec_t *          iov,
    int                                 iovc,
    globus_size_t *                     nbytes)
{
    globus_ssize_t                      rc;
    globus_result_t                     result;
    GlobusXIOName(globus_i_xio_system_try_readv);

    GlobusXIOSystemDebugEnterFD(fd);

    do
    {
#ifdef HAVE_READV
        rc = readv(fd, iov,
                (iovc > globus_l_xio_iov_max) ? globus_l_xio_iov_max : iovc);
#else
        rc = read(fd, iov[0].iov_base,iov[0].iov_len);
#endif
        GlobusXIOSystemUpdateErrno();
    } while(rc < 0 && errno == EINTR);

    if(rc < 0)
    {
        if(GlobusLXIOSystemWouldBlock(errno))
        {
            rc = 0;
        }
        else
        {
            result = GlobusXIOErrorSystemError("readv", errno);
            goto error_errno;
        }
    }
    else if(rc == 0)
    {
        result = GlobusXIOErrorEOF();
        goto error_eof;
    }

    *nbytes = rc;

    GlobusXIOSystemDebugPrintf(
        GLOBUS_I_XIO_SYSTEM_DEBUG_DATA,
        ("[%s] Read %d bytes\n", _xio_name, rc));

    GlobusXIOSystemDebugRawIovec(rc, iov);

    GlobusXIOSystemDebugExitFD(fd);
    return GLOBUS_SUCCESS;

error_errno:
error_eof:
    *nbytes = 0;
    GlobusXIOSystemDebugExitWithErrorFD(fd);
    return result;
}
globus_result_t
globus_i_xio_system_try_sendto(
    globus_xio_system_socket_t          fd,
    void *                              buf,
    globus_size_t                       buflen,
    int                                 flags,
    const globus_sockaddr_t *           to,
    globus_size_t *                     nbytes)
{
    globus_ssize_t                      rc = 0;
    globus_result_t                     result;
    GlobusXIOName(globus_i_xio_system_try_sendto);

    GlobusXIOSystemDebugEnterFD(fd);

    if(buflen)
    {
        do
        {
            rc = sendto(
                fd,
                buf,
                buflen,
                flags,
                (struct sockaddr *) to,
                GlobusLibcSockaddrLen(to));
            GlobusXIOSystemUpdateErrno();
        } while(rc < 0 && errno == EINTR);

        if(rc < 0)
        {
            if(GlobusLXIOSystemWouldBlock(errno))
            {
                rc = 0;
            }
            else
            {
                result = GlobusXIOErrorSystemError("sendto", errno);
                goto error_errno;
            }
        }

        GlobusXIOSystemDebugPrintf(
            GLOBUS_I_XIO_SYSTEM_DEBUG_DATA,
            ("[%s] Wrote %d bytes\n", _xio_name, rc));

        GlobusXIOSystemDebugRawBuffer(rc, buf);
    }

    *nbytes = rc;

    GlobusXIOSystemDebugExitFD(fd);
    return GLOBUS_SUCCESS;

error_errno:
    *nbytes = 0;
    GlobusXIOSystemDebugExitWithErrorFD(fd);
    return result;
}