static void globus_l_xio_win32_socket_complete( globus_i_xio_system_op_info_t * op_info, globus_bool_t win32_thread) { SOCKET fd; globus_result_t result; GlobusXIOName(globus_l_xio_win32_socket_complete); fd = op_info->handle->socket; GlobusXIOSystemDebugEnterFD(fd); if(!op_info->op) { /* internal usage */ globus_l_xio_win32_socket_kickout(op_info); result = GLOBUS_SUCCESS; } else if(win32_thread) { result = globus_i_xio_win32_complete( globus_l_xio_win32_socket_kickout, op_info); } else { result = globus_callback_register_oneshot( 0, 0, globus_l_xio_win32_socket_kickout, op_info); } /* really cant do anything else */ if(result != GLOBUS_SUCCESS) { globus_panic( GLOBUS_XIO_SYSTEM_MODULE, result, _XIOSL("[%s:%d] Couldn't register callback"), _xio_name, __LINE__); } GlobusXIOSystemDebugExitFD(fd); }
static void globus_l_xio_win32_socket_cancel_cb( globus_xio_operation_t op, void * user_arg, globus_xio_error_type_t reason) { globus_i_xio_system_op_info_t * op_info; GlobusXIOName(globus_l_xio_win32_socket_cancel_cb); GlobusXIOSystemDebugEnter(); op_info = (globus_i_xio_system_op_info_t *) user_arg; /* this access of the handle is not safe if users destroy it * with outstanding callbacks. I don't think that is allowed, so we * should be ok. */ win32_mutex_lock(&op_info->handle->lock); { if(op_info->state != GLOBUS_I_XIO_SYSTEM_OP_COMPLETE && op_info->state != GLOBUS_I_XIO_SYSTEM_OP_CANCELED) { op_info->error = reason == GLOBUS_XIO_ERROR_TIMEOUT ? GlobusXIOErrorObjTimeout() : GlobusXIOErrorObjCanceled(); if(op_info->state == GLOBUS_I_XIO_SYSTEM_OP_NEW) { op_info->state = GLOBUS_I_XIO_SYSTEM_OP_CANCELED; GlobusXIOSystemDebugPrintf( GLOBUS_I_XIO_SYSTEM_DEBUG_INFO, ("[%s] fd=%lu, Canceling NEW\n", _xio_name, (unsigned long)op_info->handle->socket)); } else { globus_result_t result; op_info->state = GLOBUS_I_XIO_SYSTEM_OP_COMPLETE; GlobusXIOSystemDebugPrintf( GLOBUS_I_XIO_SYSTEM_DEBUG_INFO, ("[%s] fd=%lu, Canceling Pending\n", _xio_name, (unsigned long)op_info->handle->socket)); if(op_info->handle->read_info == op_info) { op_info->handle->read_info = 0; } else { globus_assert(op_info->handle->write_info == op_info); op_info->handle->write_info = 0; } /* unregister and kickout now */ result = globus_callback_register_oneshot( 0, 0, globus_l_xio_win32_socket_kickout, op_info); /* really cant do anything else */ if(result != GLOBUS_SUCCESS) { globus_panic( GLOBUS_XIO_SYSTEM_MODULE, result, _XIOSL("[%s:%d] Couldn't register callback"), _xio_name, __LINE__); } } } } win32_mutex_unlock(&op_info->handle->lock); GlobusXIOSystemDebugExit(); }
globus_result_t globus_xio_stack_push_driver( globus_xio_stack_t stack, globus_xio_driver_t driver) { globus_xio_driver_t p_d; globus_i_xio_stack_t * xio_stack; globus_result_t res = GLOBUS_SUCCESS; GlobusXIOName(globus_xio_stack_push_driver); GlobusXIODebugEnter(); if(stack == NULL) { res = GlobusXIOErrorParameter("stack"); goto err; } if(driver == NULL) { res = GlobusXIOErrorParameter("driver"); goto err; } xio_stack = (globus_i_xio_stack_t *) stack; /* if in the transport position and has a push stack */ if(driver->push_driver_func != NULL && xio_stack->pushing_driver != driver) { p_d = xio_stack->pushing_driver; xio_stack->pushing_driver = driver; res = driver->push_driver_func(driver, xio_stack); xio_stack->pushing_driver = p_d; if(res != GLOBUS_SUCCESS) { goto err; } } /* if a transport driver position */ else if(xio_stack->size == 0) { if(driver->transport_open_func == NULL) { res = GlobusXIOErrorInvalidDriver( _XIOSL("open function not defined")); goto err; } else { xio_stack->size++; globus_list_insert(&xio_stack->driver_stack, driver); } } else if(driver->transport_open_func != NULL) { res = GlobusXIOErrorInvalidDriver( _XIOSL("transport can only be at bottom of stack")); goto err; } else { xio_stack->size++; globus_list_insert(&xio_stack->driver_stack, driver); } GlobusXIODebugExit(); return GLOBUS_SUCCESS; err: GlobusXIODebugExitWithError(); return res; }
globus_result_t globus_xio_data_descriptor_init( globus_xio_data_descriptor_t * data_desc, globus_xio_handle_t handle) { globus_result_t res = GLOBUS_SUCCESS; globus_i_xio_op_t * op; globus_i_xio_context_t * context; GlobusXIOName(globus_xio_data_descriptor_init); GlobusXIODebugEnter(); if(data_desc == NULL) { res = GlobusXIOErrorParameter("data_desc"); goto err_parm; } if(handle == NULL) { res = GlobusXIOErrorParameter("handle"); goto err; } context = handle->context; globus_mutex_lock(&context->mutex); { GlobusXIOOperationCreate(op, context); if(op != NULL) { op->type = GLOBUS_XIO_OPERATION_TYPE_DD; handle->ref++; GlobusXIODebugPrintf( GLOBUS_XIO_DEBUG_INFO_VERBOSE, (_XIOSL("[globus_xio_data_descriptor_init] :: handle ref at %d.\n"), handle->ref)); op->_op_handle = handle; op->ref = 1; op->is_user_dd = GLOBUS_TRUE; } else { res = GlobusXIOErrorMemory("xio_dd"); } } globus_mutex_unlock(&context->mutex); if(res != GLOBUS_SUCCESS) { goto err; } *data_desc = op; globus_mutex_lock(&globus_i_xio_mutex); { globus_list_insert(&globus_i_xio_outstanding_dds_list, op); } globus_mutex_unlock(&globus_i_xio_mutex); GlobusXIODebugExit(); return GLOBUS_SUCCESS; err: *data_desc = NULL; err_parm: GlobusXIODebugExitWithError(); return res; }
globus_result_t globus_xio_attr_destroy( globus_xio_attr_t attr) { int ctr; globus_result_t res = GLOBUS_SUCCESS; globus_result_t tmp_res; GlobusXIOName(globus_xio_attr_destroy); GlobusXIODebugEnter(); if(attr == NULL) { res = GlobusXIOErrorParameter("attr"); goto err; } globus_mutex_lock(&globus_i_xio_mutex); { if(!attr->unloaded) { for(ctr = 0; ctr < attr->ndx; ctr++) { GlobusXIODebugPrintf( GLOBUS_XIO_DEBUG_INFO_VERBOSE, (_XIOSL("[globus_xio_attr_destroy]: destroying attr @0x%x " "driver @0x%x, %s\n"), attr, attr->entry[ctr].driver, attr->entry[ctr].driver->name)); /* report the last seen error but be sure to attempt to clean them all */ tmp_res = attr->entry[ctr].driver->attr_destroy_func( attr->entry[ctr].driver_data); if(tmp_res != GLOBUS_SUCCESS) { res = tmp_res; } } globus_list_remove( &globus_i_xio_outstanding_attrs_list, globus_list_search( globus_i_xio_outstanding_attrs_list, attr)); } } globus_mutex_unlock(&globus_i_xio_mutex); if(attr->user_open_sbj) { globus_free(attr->user_open_sbj); } if(attr->user_open_username) { globus_free(attr->user_open_username); } if(attr->user_open_pw) { globus_free(attr->user_open_pw); } globus_callback_space_destroy(attr->space); globus_free(attr->entry); globus_free(attr); if(res != GLOBUS_SUCCESS) { goto err; } GlobusXIODebugExit(); return GLOBUS_SUCCESS; err: GlobusXIODebugExitWithError(); return res; }
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(); }