extern "C" JNIEXPORT void JNICALL Java_java_nio_channels_SocketChannel_natThrowWriteError(JNIEnv *e, jclass, jint socket) { int error; socklen_t size = sizeof(int); int r = getsockopt(socket, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&error), &size); if (r != 0 or size != sizeof(int)) { throwIOException(e); } else if (error != 0) { throwIOException(e, socketErrorString(e, error)); } }
// Fire error events on up to two objects if there is an error, returns true if there is an error // The error events have a code field and a message field. static bool fireErrorEvent(int error, JsVar *obj1, JsVar *obj2) { bool hadError = error < 0 && error != SOCKET_ERR_CLOSED; JsVar *params[1]; if (hadError) { params[0] = jsvNewObject(); jsvObjectSetChildAndUnLock(params[0], "code", jsvNewFromInteger(error)); jsvObjectSetChildAndUnLock(params[0], "message", jsvNewFromString(socketErrorString(error))); if (obj1 != NULL) jsiQueueObjectCallbacks(obj1, HTTP_NAME_ON_ERROR, params, 1); if (obj2 != NULL) jsiQueueObjectCallbacks(obj2, HTTP_NAME_ON_ERROR, params, 1); jsvUnLock(params[0]); } return hadError; }
/** * Set the given socket as being in error supplying the espconn code. * This translates the espconn code to an Espruino socket error code. */ static void setSocketInError( struct socketData *pSocketData, //!< The socket that is being flagged as in error. int code //!< The espconn error code ) { assert(pSocketData != NULL); assert(pSocketData->state != SOCKET_STATE_UNUSED); if (pSocketData->errorCode != 0) return; // don't overwrite previous error int err = code; switch (code) { case ESPCONN_MEM: err = SOCKET_ERR_MEM; break; case ESPCONN_ABRT: err = SOCKET_ERR_RESET; break; case ESPCONN_CLSD: err = SOCKET_ERR_CLOSED; break; case ESPCONN_IF: err = SOCKET_ERR_UNKNOWN; break; case ESPCONN_ISCONN: err = SOCKET_ERR_BUSY; break; case ESPCONN_HANDSHAKE: err = SOCKET_ERR_SSL_HAND; break; case ESPCONN_SSL_INVALID_DATA: err = SOCKET_ERR_SSL_INVALID; break; } pSocketData->errorCode = err; DBG("%s: error %d->%d on socket %d: %s\n", DBG_LIB, code, err, pSocketData->socketId, socketErrorString(err)); }
extern "C" JNIEXPORT jint JNICALL Java_java_nio_channels_SocketSelector_natDoSocketSelect(JNIEnv *e, jclass, jlong state, jint max, jlong interval) { SelectorState* s = reinterpret_cast<SelectorState*>(state); if (s->control.reader() >= 0) { int socket = s->control.reader(); FD_SET(static_cast<unsigned>(socket), &(s->read)); if (max < socket) max = socket; } #ifdef PLATFORM_WINDOWS if (s->control.listener() >= 0) { int socket = s->control.listener(); FD_SET(static_cast<unsigned>(socket), &(s->read)); if (max < socket) max = socket; } if (not s->control.connected()) { int socket = s->control.writer(); FD_SET(static_cast<unsigned>(socket), &(s->write)); FD_SET(static_cast<unsigned>(socket), &(s->except)); if (max < socket) max = socket; } #endif timeval time; if (interval > 0) { time.tv_sec = interval / 1000; time.tv_usec = (interval % 1000) * 1000; } else if (interval < 0) { time.tv_sec = 0; time.tv_usec = 0; } else { time.tv_sec = 24 * 60 * 60 * 1000; time.tv_usec = 0; } int r = ::select(max + 1, &(s->read), &(s->write), &(s->except), &time); if (r < 0) { if (errno != EINTR) { throwIOException(e); return 0; } } #ifdef PLATFORM_WINDOWS if (FD_ISSET(s->control.writer(), &(s->write)) or FD_ISSET(s->control.writer(), &(s->except))) { int socket = s->control.writer(); FD_CLR(static_cast<unsigned>(socket), &(s->write)); FD_CLR(static_cast<unsigned>(socket), &(s->except)); int error; socklen_t size = sizeof(int); int r = getsockopt(socket, SOL_SOCKET, SO_ERROR, reinterpret_cast<char*>(&error), &size); if (r != 0 or size != sizeof(int)) { throwIOException(e); } else if (error != 0) { throwIOException(e, socketErrorString(e, error)); } s->control.setConnected(true); } if (s->control.listener() >= 0 and FD_ISSET(s->control.listener(), &(s->read))) { FD_CLR(static_cast<unsigned>(s->control.listener()), &(s->read)); s->control.setReader(::doAccept(e, s->control.listener())); s->control.setListener(-1); } #endif if (s->control.reader() >= 0 and FD_ISSET(s->control.reader(), &(s->read))) { FD_CLR(static_cast<unsigned>(s->control.reader()), &(s->read)); char c; int r = 1; while (r == 1) { r = ::doRead(s->control.reader(), &c, 1); } if (r < 0 and not eagain()) { throwIOException(e); } } return r; }