📄 socketprotocol.c
字号:
/* * Copyright (c) 1999-2002 Sun Microsystems, Inc., 901 San Antonio Road, * Palo Alto, CA 94303, U.S.A. All Rights Reserved. * * Sun Microsystems, Inc. has intellectual property rights relating * to the technology embodied in this software. In particular, and * without limitation, these intellectual property rights may include * one or more U.S. patents, foreign patents, or pending * applications. Sun, Sun Microsystems, the Sun logo, Java, KJava, * and all Sun-based and Java-based marks are trademarks or * registered trademarks of Sun Microsystems, Inc. in the United * States and other countries. * * This software is distributed under licenses restricting its use, * copying, distribution, and decompilation. No part of this * software may be reproduced in any form by any means without prior * written authorization of Sun and its licensors, if any. * * FEDERAL ACQUISITIONS: Commercial Software -- Government Users * Subject to Standard License Terms and Conditions *//*========================================================================= * KVM *========================================================================= * SYSTEM: KVM * SUBSYSTEM: networking (Generic Connection framework) * FILE: socketProtocol.c * OVERVIEW: This file provides a default implementation of the native * functions that are needed for supporting the "socket:" and * "serversocket:" Generic Connection protocols. * AUTHOR(s): Nik Shaylor, Efren Serra *=======================================================================*//*========================================================================= * Include files *=======================================================================*/#include "global.h"#include "async.h"/*========================================================================= * Definitions and declarations *=======================================================================*//* The following flag allows the code for server * sockets to be compiled out if necessary. */#ifndef NO_SERVER_SOCKETS#define NO_SERVER_SOCKETS 0 /* Include server sockets by default */#endif#if INCLUDEDEBUGCODE#define NDEBUG0(fmt) if (tracenetworking) { fprintf(stdout, fmt); }#define NDEBUG1(fmt, p1) if (tracenetworking) { fprintf(stdout, fmt, p1); }#define NDEBUG2(fmt, p1, p2) if (tracenetworking) { fprintf(stdout, fmt, p1, p2); }#define NDEBUG3(fmt, p1, p2, p3) if (tracenetworking) { fprintf(stdout, fmt, p1, p2, p3); }#define NDEBUG4(fmt, p1, p2, p3, p4) if (tracenetworking) { fprintf(stdout, fmt, p1, p2, p3, p4); }#define NDEBUG5(fmt, p1, p2, p3, p4, p5) if (tracenetworking) { fprintf(stdout, fmt, p1, p2, p3, p4, p5); }#define NDEBUG6(fmt, p1, p2, p3, p4, p5, p6) if (tracenetworking) { fprintf(stdout, fmt, p1, p2, p3, p4, p5, p6); }#else#define NDEBUG0(fmt) /**/#define NDEBUG1(fmt, p1) /**/#define NDEBUG2(fmt, p1, p2) /**/#define NDEBUG3(fmt, p1, p2, p3) /**/#define NDEBUG4(fmt, p1, p2, p3, p4) /**/#define NDEBUG5(fmt, p1, p2, p3, p4, p5) /**/#define NDEBUG6(fmt, p1, p2, p3, p4, p5, p6) /**/#endif#ifndef MAX_HOST_LENGTH#define MAX_HOST_LENGTH 256#endif /* MAX_HOST_LENGTH *//*========================================================================= * Protocol methods *=======================================================================*//*========================================================================= * FUNCTION: setSocketHandle() * TYPE: public instance-level operation * OVERVIEW: Set the contents of the handle field * INTERFACE: * parameters: instance, value * returns: <nothing> *=======================================================================*/static void setSocketHandle(ASYNCIOCB *aiocb, long value){ aiocb->instance->data[0].cell = value; /* 'handle' must be slot 0 */ NDEBUG1("setSocketHandle handle=%ld\n", (long)aiocb->instance->data[0].cell);}/*========================================================================= * function: getSocketHandle() * TYPE: private instance-level operation * OVERVIEW: Get the contents of the handle field * INTERFACE: * parameters: instance * returns: value *=======================================================================*/static int getSocketHandle(ASYNCIOCB *aiocb){ NDEBUG1("getSocketHandle handle=%ld\n", (long)aiocb->instance->data[0].cell); return aiocb->instance->data[0].cell; /* 'handle' must be slot 0 */}/*========================================================================= * FUNCTION: getPortNumber() * TYPE: private instance-level operation * OVERVIEW: Get the port number from the URL * INTERFACE: * parameters: string * returns: value *=======================================================================*/static int getPortNumber(char *string){ char *p = string; while (TRUE) { if (*p == '\0') { return -1; } if (*p++ == ':') { break; /* must have a ':' */ } } if (*p < '0' || *p > '9') { return -1; /* must have at least one digit' */ } string = p; while (*p != '\0') { if (*p < '0' || *p > '9') { return -1; } if (*p++ == ';') { break; /* port numbers may be terminated by EOL or ';' */ } } NDEBUG2("getPortNumber string='%s' port=%ld\n", string, (long)atoi(string)); return atoi(string);}/*========================================================================= * FUNCTION: getHostName() * TYPE: private instance-level operation * OVERVIEW: Get the name from the URL * INTERFACE: * parameters: string * returns: string * NOTE: *** The input string is modified by this function *** *=======================================================================*/static char *getHostName(char *string){ char *p = string; if (*p++ != '/' || *p++ != '/') { return NULL; } while (TRUE) { if (*p == '\0' || *p == ':' || *p == ';') { break; } ++p; } NDEBUG1("getHostName string='%s'", string); *p = '\0'; /* terminate the string there */ NDEBUG1(" name='%s'\n", string+2); return string + 2; /* skip past the "//" */}/*========================================================================= * FUNCTION: open0() * CLASS: com.sun.cldc.io.j2me.socket.Protocol * TYPE: virtual native function * OVERVIEW: Open a TCP socket * INTERFACE (operand stack manipulation): * parameters: this, name, mode, append * returns: none *=======================================================================*/ASYNC_FUNCTION_START(Java_com_sun_cldc_io_j2me_socket_Protocol_open0){ long stringlen; long append = ASYNC_popStack(); long mode = ASYNC_popStack(); STRING_INSTANCE string = ASYNC_popStackAsType(STRING_INSTANCE); INSTANCE instance = ASYNC_popStackAsType(INSTANCE); char *exception = NULL; int fd = -1; char name[MAX_HOST_LENGTH]; char *host; int port; aiocb->instance = instance; /* Save instance in ASYNCIOCB */ /* * The name string has the following format: "//<host>:<port>" */ (void)mode; (void)append; stringlen = string->length + 1; (void)getStringContentsSafely(string, name, stringlen); port = getPortNumber(name); /* Must be called before getHostName() */ if (port < 0 || port > 0xFFFF) { NDEBUG2("socket::open0 name='%s' port=%ld (ERROR)\n", name, (long)port); goto illarg; } host = getHostName(name); /* Must be the last parsing function */ if (host == NULL) { NDEBUG1("socket::open0 name='%s' host=null (ERROR)\n", name); goto illarg; } /* * We allow "socket://:nnnn" to mean "serversocket://:nnnn" but we * throw an InterruptedException to tell the calling Java code * about this */ if (*host == '\0') { ASYNC_raiseException("java/lang/InterruptedException"); goto fail; }#if INCLUDEDEBUGCODE if (tracenetworking) { fprintf(stdout, "socket::open0 name='%s' host='%s' port=%ld\n", name, host, (long)port); }#endif /* INCLUDEDEBUGCODE */ ASYNC_enableGarbageCollection(); fd = prim_com_sun_cldc_io_j2me_socket_Protocol_open0(host, port, &exception); ASYNC_disableGarbageCollection(); NDEBUG6("socket::open0 name='%s' host='%s' port=%ld fd = %ld exception = '%s' ne=%ld\n", name, host, (long)port, (long)fd, (exception == NULL) ? "null" : exception, (long)netError()); if (exception == NULL) { /* For non-blocking systems only */ prim_com_sun_cldc_io_j2me_socket_Protocol_setNonBlocking(fd); goto done; } ASYNC_raiseException(exception); goto fail;illarg: ASYNC_raiseException("java/lang/IllegalArgumentException");fail: fd = -1;done: setSocketHandle(aiocb, fd);}ASYNC_FUNCTION_END/*========================================================================= * FUNCTION: read0() * CLASS: com.sun.cldc.io.j2me.socket.Protocol * TYPE: virtual native function * OVERVIEW: Read from a TCP socket * INTERFACE (operand stack manipulation): * parameters: this, buffer, offset, length * returns: number of chars read or -1 if at EOF *=======================================================================*/ASYNC_FUNCTION_START(Java_com_sun_cldc_io_j2me_socket_Protocol_read0){ long length = ASYNC_popStack(); long offset = ASYNC_popStack(); BYTEARRAY array = ASYNC_popStackAsType(BYTEARRAY); INSTANCE instance = ASYNC_popStackAsType(INSTANCE); long fd; int res; aiocb->instance = instance; fd = getSocketHandle(aiocb); NDEBUG4("socket::read0 b=%lx o=%ld l=%ld fd=%ld\n", (long)array, offset, length, fd); if (array == 0) { ASYNC_raiseException("java/lang/NullPointerException"); res = 0; goto done; } if ((offset < 0) || (offset > (long)array->length) || (length < 0) || ((offset + length) > (long)array->length) || ((offset + length) < 0)) { ASYNC_raiseException("java/lang/IndexOutOfBoundsException"); res = 0; goto done; } {#if ASYNCHRONOUS_NATIVE_FUNCTIONS char buffer[ASYNC_BUFFER_SIZE]; /* * If necessary reduce the length to that of the buffer. The * Java code will call back with more I/O operations if needed. */ if (length > ASYNC_BUFFER_SIZE) { length = ASYNC_BUFFER_SIZE; } aiocb->array = array; ASYNC_enableGarbageCollection(); res = prim_com_sun_cldc_io_j2me_socket_Protocol_read0(fd, buffer, length); ASYNC_disableGarbageCollection(); if (res > 0) { memcpy((char *)aiocb->array->bdata + offset, buffer, res); }#else res = prim_com_sun_cldc_io_j2me_socket_Protocol_read0(fd, (char *)array->bdata + offset, length);#endif /* ASYNCHRONOUS_NATIVE_FUNCTIONS */ } NDEBUG2("socket::read0 res=%ld ne=%ld\n", (long)res, (long)netError()); if (res == -2) { res = 0; goto done; } if (res < 0) { if (res == -3) { ASYNC_raiseException("java/io/InterruptedIOException"); } else { ASYNC_raiseException("java/io/IOException"); } } if (res == 0) { res = -1; }done: ASYNC_pushStack(res);}ASYNC_FUNCTION_END/*========================================================================= * FUNCTION: write0() * CLASS: com.sun.cldc.io.j2me.socket.Protocol * TYPE: virtual native function * OVERVIEW: Write to a TCP socket * INTERFACE (operand stack manipulation):
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -