/*
 *  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
void
globus_l_xio_net_manager_close_cb(
    globus_xio_operation_t              op,
    globus_result_t                     result,
    void *                              user_arg)
{
    globus_l_xio_net_manager_handle_t  *handle = user_arg;

    if (!handle)
    {
        goto no_handle;
    }
    if (result == GLOBUS_SUCCESS)
    {
        result = globus_net_manager_context_post_close(
                handle->attr->context,
                handle->attr->task_id ? handle->attr->task_id : "unset",
                handle->transport_name,
                handle->local_contact,
                handle->remote_contact,
                handle->attr->attr_array);
    }
    globus_l_xio_net_manager_attr_destroy(handle->attr);
    free(handle->remote_contact);
    free(handle->local_contact);
    free(handle);
no_handle:
    globus_xio_driver_finished_close(op, result);
}
예제 #3
0
static void
globus_l_xio_telnet_close_cb(
    globus_xio_operation_t              op,
    globus_result_t                     result,
    void *                              user_arg)
{
    globus_l_xio_telnet_handle_t *     handle;

    handle = (globus_l_xio_telnet_handle_t *) user_arg;

    globus_xio_driver_finished_close(op, result);

    globus_free(handle->read_buffer);
    globus_fifo_destroy(&handle->write_q);
    globus_mutex_destroy(&handle->mutex);
    globus_free(handle);
}
예제 #4
0
static void
test_bounce_finish_op(
    bounce_info_t *                     info,
    globus_xio_operation_t              op)
{
    GlobusXIOName(test_bounce_finish_op);

    GlobusXIOTestDebugInternalEnter();

    switch(info->start_op)
    {
        case TEST_READ:
            globus_xio_driver_finished_read(op, info->res, info->nbytes);
            break;

        case TEST_WRITE:
            globus_xio_driver_finished_write(op, info->res, info->nbytes);
            break;
    
        case TEST_OPEN:
            if(info->res != GLOBUS_SUCCESS)
            {
                bounce_handle_destroy(info->handle);
                info->handle = NULL;
            }
            globus_xio_driver_finished_open(
                info->handle, op, info->res);
            break;

        case TEST_CLOSE:
            globus_xio_driver_finished_close(op, info->res);
            bounce_handle_destroy(info->handle);
            break;

        default:
            globus_assert(0);
            break;
    }

    globus_free(info);

    GlobusXIOTestDebugInternalExit();
}
static
void
globus_l_xio_wrapblock_close_kickout(
    void *                              user_arg)
{
    xio_l_wrapblock_handle_t *          wrapblock_handle;
    globus_result_t                     result;
    xio_l_wrapblock_wrapper_t *         wrapper;

    globus_thread_blocking_will_block();

    wrapper = (xio_l_wrapblock_wrapper_t *) user_arg;
    wrapblock_handle = wrapper->wrapblock_handle;

    result = wrapper->wrapblock_handle->wrapblock_driver->close_func(
        wrapblock_handle->driver_handle,
        wrapper->attr);
    globus_xio_driver_finished_close(wrapper->op, result);

    xio_l_wrapblock_wrapper_destroy(wrapper);
    globus_free(wrapblock_handle);
}
static
globus_result_t
globus_l_xio_wrapblock_close(
    void *                              driver_specific_handle,
    void *                              attr,
    globus_xio_operation_t              op)
{
    globus_result_t                     result;
    xio_l_wrapblock_wrapper_t *         wrapper;
    xio_l_wrapblock_handle_t *          wrapblock_handle;

    wrapblock_handle = (xio_l_wrapblock_handle_t *) driver_specific_handle;
    if(globus_xio_driver_operation_is_blocking(op))
    {
        result = wrapblock_handle->wrapblock_driver->close_func(
            wrapblock_handle->driver_handle,
            attr);
        globus_xio_driver_finished_close(op, result);
        globus_free(wrapblock_handle);
    }
    else
    {
        wrapper = (xio_l_wrapblock_wrapper_t *)
            globus_calloc(1, sizeof(xio_l_wrapblock_wrapper_t));
        wrapper->attr = attr;
        wrapper->op = op;
        wrapper->wrapblock_handle = driver_specific_handle;

        globus_callback_register_oneshot(
            NULL,
            NULL,
            globus_l_xio_wrapblock_close_kickout,
            wrapper);
    }
    return GLOBUS_SUCCESS;
}
static
void
globus_l_popen_waitpid(
    xio_l_popen_handle_t *              handle,
    int                                 opts)
{
    globus_result_t                     result = GLOBUS_SUCCESS;
    int                                 status;
    int                                 rc;
    globus_reltime_t                    delay;
    GlobusXIOName(globus_l_popen_waitpid);

#ifdef WIN32
    result = GlobusXIOErrorSystemResource("not available for windows");
#else
    rc = waitpid(handle->pid, &status, opts);
    if(rc > 0)
    {
        /* if program exited normally, but with a nonzero code OR
         * program exited by signal, and we didn't signal it */
        if(((WIFEXITED(status) && WEXITSTATUS(status) != 0) || 
            (WIFSIGNALED(status) && handle->kill_state != GLOBUS_L_XIO_POPEN_NONE))
            && !handle->ignore_program_errors)
        {
            /* read programs stderr and dump it to an error result */
            globus_size_t                   nbytes = 0;
            globus_xio_iovec_t              iovec;
            char                            buf[8192];

            iovec.iov_base = buf;
            iovec.iov_len = sizeof(buf) - 1;
            
            result = globus_xio_system_file_read(
                handle->err_system, 0, &iovec, 1, 0, &nbytes);
            
            buf[nbytes] = 0;

            if(WIFEXITED(status))
            {
                result = globus_error_put(
                    globus_error_construct_error(
                        GLOBUS_XIO_MODULE,
                        GLOBUS_NULL,
                        GLOBUS_XIO_ERROR_SYSTEM_ERROR,
                        __FILE__,
                        _xio_name,
                        __LINE__,
                        _XIOSL("popened program exited with an error "
                               "(exit code: %d):\n%s"),
                        WEXITSTATUS(status), 
                        buf));
            }
            else
            {
                result = globus_error_put(
                    globus_error_construct_error(
                        GLOBUS_XIO_MODULE,
                        GLOBUS_NULL,
                        GLOBUS_XIO_ERROR_SYSTEM_ERROR,
                        __FILE__,
                        _xio_name,
                        __LINE__,
                        _XIOSL("popened program was terminated by a signal"
                               "(sig: %d)"),
                        WTERMSIG(status)));
            }
        }

        globus_xio_system_file_close(handle->errfd);
        globus_xio_system_file_destroy(handle->err_system);

        globus_xio_driver_finished_close(handle->close_op, result);
        globus_l_xio_popen_handle_destroy(handle);
    }
    else if(rc < 0 || opts == 0)
    {
        /* If the errno is ECHILD, either some other thread or part of the
         * program called wait and got this pid's exit status, or sigaction
         * with SA_NOCLDWAIT prevented the process from becoming a zombie. Not
         * really an error case.
         */
        if (errno != ECHILD)
        {
            result = GlobusXIOErrorSystemError("waitpid", errno);
        }

        globus_xio_system_file_close(handle->errfd);
        globus_xio_system_file_destroy(handle->err_system);

        globus_xio_driver_finished_close(handle->close_op, result);
        globus_l_xio_popen_handle_destroy(handle);
    }
    else
    {
        
        handle->wait_count++;
        
        if(handle->canceled)
        {
            switch(handle->kill_state)
            {
                case GLOBUS_L_XIO_POPEN_NONE:
                    if(handle->wait_count > 5000 / GLOBUS_L_XIO_POPEN_WAITPID_DELAY)
                    {
                        handle->kill_state = GLOBUS_L_XIO_POPEN_TERM;
                        kill(handle->pid, SIGTERM);
                    }
                    break;
                case GLOBUS_L_XIO_POPEN_TERM:
                    if(handle->wait_count > 15000 / GLOBUS_L_XIO_POPEN_WAITPID_DELAY)
                    {
                        handle->kill_state = GLOBUS_L_XIO_POPEN_KILL;
                        kill(handle->pid, SIGKILL);
                    }
                    break;
                default:
                    break;
            } 
        }
        
        GlobusTimeReltimeSet(delay, 0, GLOBUS_L_XIO_POPEN_WAITPID_DELAY);
        globus_callback_register_oneshot(
            NULL,
            &delay,
            globus_l_xio_popen_close_oneshot,
            handle);         
    }

#endif
    GlobusXIOPOpenDebugExit();
}