/**************************************************************** * * * Copyright 2001, 2007 Fidelity Information Services, Inc * * * * This source code contains the intellectual property * * of its copyright holder(s), and is made available * * under a license. If you do not know the terms of * * the license, please stop and do not read further. * * * ****************************************************************/ /* iosocket_close.c - close a socket connection * Parameters- * iod -- I/O descriptor for the current device. * * pp -- mval that carries the device parameters * */ #include "mdef.h" #include "gtm_string.h" #include "gtm_iconv.h" #include "gtm_stdio.h" #include "gtm_socket.h" #include "gtm_inet.h" #include "copy.h" #include "io_params.h" #include "io.h" #include "iotcpdef.h" #include "iotcproutine.h" #include "gt_timer.h" #include "iosocketdef.h" #include "stringpool.h" GBLREF tcp_library_struct tcp_routines; LITREF unsigned char io_params_size[]; void iosocket_close(io_desc *iod, mval *pp) { boolean_t socket_specified = FALSE; unsigned char ch; int handle_len; d_socket_struct *dsocketptr; socket_struct *socketptr; char sock_handle[MAX_HANDLE_LEN]; int4 ii, jj, start, end, index; int p_offset = 0; error_def(ERR_SOCKNOTFND); assert(iod->type == gtmsocket); dsocketptr = (d_socket_struct *)iod->dev_sp; while (iop_eol != (ch = *(pp->str.addr + p_offset++))) { switch (ch) { case iop_exception: iod->error_handler.len = *(pp->str.addr + p_offset); iod->error_handler.addr = (char *)(pp->str.addr + p_offset + 1); s2pool(&iod->error_handler); break; case iop_socket: handle_len = (short)(*(pp->str.addr + p_offset)); assert(handle_len > 0); memcpy(sock_handle, (char *)(pp->str.addr + p_offset + 1), handle_len); socket_specified = TRUE; break; case iop_ipchset: #if defined(KEEP_zOS_EBCDIC) || defined(VMS) if ( (iconv_t)0 != iod->input_conv_cd ) { ICONV_CLOSE_CD(iod->input_conv_cd); } SET_CODE_SET(iod->in_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->in_code_set) ICONV_OPEN_CD(iod->input_conv_cd, INSIDE_CH_SET, (char *)(pp->str.addr + p_offset + 1)); #endif break; case iop_opchset: #if defined(KEEP_zOS_EBCDIC) || defined(VMS) if ( (iconv_t)0 != iod->output_conv_cd ) { ICONV_CLOSE_CD(iod->output_conv_cd); } SET_CODE_SET(iod->out_code_set, (char *)(pp->str.addr + p_offset + 1)); if (DEFAULT_CODE_SET != iod->out_code_set) ICONV_OPEN_CD(iod->output_conv_cd, (char *)(pp->str.addr + p_offset + 1), INSIDE_CH_SET); #endif break; default: break; } p_offset += ((IOP_VAR_SIZE == io_params_size[ch]) ? (unsigned char)*(pp->str.addr + p_offset) + 1 : io_params_size[ch]); } if (socket_specified) { if (0 > (index = iosocket_handle(sock_handle, &handle_len, FALSE, dsocketptr))) { rts_error(VARLSTCNT(4) ERR_SOCKNOTFND, 2, handle_len, sock_handle); return; } start = end = index; } else { start = dsocketptr->n_socket - 1; end = 0; } for (ii = start; ii >= end; ii--) { socketptr = dsocketptr->socket[ii]; tcp_routines.aa_close(socketptr->sd); iosocket_delimiter((unsigned char *)NULL, 0, socketptr, TRUE); /* free the delimiter space */ free(socketptr->buffer); if (NULL != socketptr->zff.addr) free(socketptr->zff.addr); free(socketptr); if (dsocketptr->current_socket >= ii) dsocketptr->current_socket--; for (jj = ii + 1; jj <= dsocketptr->n_socket - 1; jj++) dsocketptr->socket[jj - 1] = dsocketptr->socket[jj]; dsocketptr->n_socket--; } if (!socket_specified) iod->state = dev_closed; }