コード例 #1
0
ファイル: net.c プロジェクト: qyqx/Gauche
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;
}
コード例 #2
0
ファイル: charconv.c プロジェクト: Z-Shang/Gauche
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);
}
コード例 #3
0
ファイル: charconv.c プロジェクト: Z-Shang/Gauche
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;
    }
}
コード例 #4
0
ファイル: charconv.c プロジェクト: Z-Shang/Gauche
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;
    }
}