ScmObj Scm_SocketClose(ScmSocket *s) { if (s->status == SCM_SOCKET_STATUS_CLOSED) { return SCM_FALSE; } /* We don't shutdown the connection; forked process may have reference to the same socket. */ /* Clearing inPort/outPort helps them to be collected earlier. */ if (s->inPort) { Scm_ClosePort(s->inPort); /* ignore errors */ s->inPort = NULL; } if (s->outPort) { Scm_ClosePort(s->outPort); /* ignore errors */ s->outPort = NULL; } #if defined(GAUCHE_WINDOWS) if (s->cfd >= 0) { close(s->cfd); s->cfd = -1; } #endif /*GAUCHE_WINDOWS*/ closeSocket(s->fd); s->fd = INVALID_SOCKET; s->status = SCM_SOCKET_STATUS_CLOSED; return SCM_TRUE; }
static void conv_output_closer(ScmPort *port) { ScmConvInfo *info = (ScmConvInfo*)port->src.buf.data; /* if there's remaining bytes in buf, send them to the remote port. */ if (info->ptr > info->buf) { Scm_Putz(info->buf, (int)(info->ptr - info->buf), info->remote); info->ptr = info->buf; } /* sends out the closing sequence, if any */ int r = (int)jconv_reset(info, info->buf, info->bufsiz); #ifdef JCONV_DEBUG fprintf(stderr, "<= r=%d(reset), buf(%p)\n", r, info->buf); #endif if (r < 0) { Scm_Error("something wrong in resetting output character encoding conversion (%s -> %s). possibly an implementation error.", info->fromCode, info->toCode); } if (r > 0) { Scm_Putz(info->buf, r, info->remote); } /* flush remove port */ Scm_Flush(info->remote); if (info->ownerp) { Scm_ClosePort(info->remote); info->remoteClosed = TRUE; } jconv_close(info); }
static void conv_input_closer(ScmPort *p) { ScmConvInfo *info = (ScmConvInfo*)p->src.buf.data; jconv_close(info); if (info->ownerp) { Scm_ClosePort(info->remote); info->remoteClosed = TRUE; } }
static int conv_input_filler(ScmPort *port, int mincnt) { ScmConvInfo *info = (ScmConvInfo*)port->src.buf.data; const char *inbuf = info->buf; char *outbuf = port->src.buf.end; if (info->remoteClosed) return 0; /* Fill the input buffer. There may be some remaining bytes in the inbuf from the last conversion (insize), so we try to fill the rest. */ size_t insize = info->ptr - info->buf; int nread = Scm_Getz(info->ptr, info->bufsiz - (int)insize, info->remote); if (nread <= 0) { /* input reached EOF. finish the output state */ if (insize == 0) { size_t outroom = SCM_PORT_BUFFER_ROOM(port); size_t result = jconv_reset(info, outbuf, outroom); if (result == OUTPUT_NOT_ENOUGH) { /* The port buffer doesn't have enough space to contain the finishing sequence. Its unusual, for the port buffer must be almost empty at this time, and the finishing sequence is usually just a few bytes. We signal an error. */ Scm_Error("couldn't flush the ending escape sequence in the character encoding conversion port (%s -> %s). possibly an implementation error", info->fromCode, info->toCode); } if (info->ownerp) { Scm_ClosePort(info->remote); info->remoteClosed = TRUE; } #ifdef JCONV_DEBUG fprintf(stderr, "<= r=%d (reset), out(%p)%d\n", result, outbuf, outroom); #endif return (int)result; } } else { insize += nread; } /* Conversion. */ size_t inroom = insize; size_t outroom = SCM_PORT_BUFFER_ROOM(port); #ifdef JCONV_DEBUG fprintf(stderr, "=> in(%p)%d out(%p)%d\n", inbuf, insize, outbuf, outroom); #endif size_t result = jconv(info, &inbuf, &inroom, &outbuf, &outroom); #ifdef JCONV_DEBUG fprintf(stderr, "<= r=%d, in(%p)%d out(%p)%d\n", result, inbuf, inroom, outbuf, outroom); #endif /* we've got an error. */ if (result == INPUT_NOT_ENOUGH || result == OUTPUT_NOT_ENOUGH) { /* Conversion stopped due to an incomplete character at the end of the input buffer, or the output buffer is full. We shift the unconverted bytes to the beginning of input buffer. */ memmove(info->buf, info->buf+insize-inroom, inroom); info->ptr = info->buf + inroom; return info->bufsiz - (int)outroom; } else if (result == ILLEGAL_SEQUENCE) { /* it's likely that the input contains invalid sequence. */ int cnt = inroom >= 6 ? 6 : (int)inroom; ScmObj s = Scm_MakeString(info->buf+insize-inroom, cnt, cnt, SCM_STRING_COPYING|SCM_STRING_INCOMPLETE); Scm_Error("invalid character sequence in the input stream: %S ...", s); } /* Conversion is done completely. */ /* NB: There are cases that some bytes are left in the input buffer even iconv returns positive value. We need to shift those bytes. */ if (inroom > 0) { memmove(info->buf, info->buf+insize-inroom, inroom); info->ptr = info->buf + inroom; return info->bufsiz - (int)outroom; } else { info->ptr = info->buf; return info->bufsiz - (int)outroom; } }