void* WsThreadHelper::wsThreadEntryFunc(void* arg) { _ws->onSubThreadStarted(); while (!_needQuit) { if (_ws->onSubThreadLoop()) { break; } } _ws->onSubThreadEnded(); return (void*)0; }
void WsThreadHelper::update(float dt) { WsMessage *msg = nullptr; // Returns quickly if no message _UIWsMessageQueueMutex.lock(); if (0 == _UIWsMessageQueue->size()) { _UIWsMessageQueueMutex.unlock(); return; } // Gets message msg = *(_UIWsMessageQueue->begin()); _UIWsMessageQueue->pop_front(); _UIWsMessageQueueMutex.unlock(); if (_ws) { _ws->onUIThreadReceiveMessage(msg); } CC_SAFE_DELETE(msg); }
EncodedJSValue JSC_HOST_CALL jsWebSocketPrototypeFunctionDispatchEvent(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); if (!thisValue.inherits(&JSWebSocket::s_info)) return throwVMTypeError(exec); JSWebSocket* castedThis = static_cast<JSWebSocket*>(asObject(thisValue)); WebSocket* imp = static_cast<WebSocket*>(castedThis->impl()); ExceptionCode ec = 0; Event* evt(toEvent(exec->argument(0))); if (exec->hadException()) return JSValue::encode(jsUndefined()); JSC::JSValue result = jsBoolean(imp->dispatchEvent(evt, ec)); setDOMException(exec, ec); return JSValue::encode(result); }
void SIOClientImpl::connectToEndpoint(const std::string& endpoint) { std::string path = endpoint == "/" ? "" : endpoint; std::string s = "1::" + path; _ws->send(s); }
void SIOClientImpl::heartbeat(float dt) { std::string s = "2::"; _ws->send(s); log("Heartbeat sent"); }
void run(void* data) { uint8_t buffer[1000]; WebSocket *pWebSocket = (WebSocket*) data; // do something Socket peerSocket = pWebSocket->getSocket(); ESP_LOGD(LOG_TAG, "Waiting on socket data for socket %s", peerSocket.toString().c_str()); int length = peerSocket.receive_cpp(buffer, sizeof(buffer)); ESP_LOGD(LOG_TAG, "Received data from web socket. Length: %d", length); GeneralUtils::hexDump(buffer, length); dumpFrame(*(Frame *)buffer); // The following section parses the WebSocket frame. if (length > 0) { Frame* pFrame = (Frame*)buffer; uint32_t payloadLen = 0; uint8_t* pMask = nullptr; uint8_t* pData; if (pFrame->len < 126) { payloadLen = pFrame->len; pMask = buffer + 2; } else if (pFrame->len == 126) { payloadLen = *(uint16_t*)(buffer+2); pMask = buffer + 4; } else if (pFrame->len == 127) { ESP_LOGE(LOG_TAG, "Too much data!"); return; } if (pFrame->mask == 1) { pData = pMask + 4; for (int i=0; i<payloadLen; i++) { *pData = *pData ^ pMask[i%4]; pData++; } pData = pMask + 4; } else { pData = pMask; } std::string retData = std::string((char *)pData, payloadLen); ESP_LOGD(LOG_TAG, "Resulting payload:"); GeneralUtils::hexDump(pData, payloadLen); } } // run
void SIOClientImpl::disconnect() { if(_ws->getReadyState() == WebSocket::State::OPEN) { std::string s = "0::"; _ws->send(s); log("Disconnect sent"); _ws->close(); } Director::getInstance()->getScheduler()->unscheduleAllForTarget(this); _connected = false; SocketIO::getInstance()->removeSocket(_uri); }
EncodedJSValue JSC_HOST_CALL jsWebSocketPrototypeFunctionSend(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); if (!thisValue.inherits(&JSWebSocket::s_info)) return throwVMTypeError(exec); JSWebSocket* castedThis = static_cast<JSWebSocket*>(asObject(thisValue)); WebSocket* imp = static_cast<WebSocket*>(castedThis->impl()); if (exec->argumentCount() < 1) return JSValue::encode(jsUndefined()); ExceptionCode ec = 0; const String& data(ustringToString(exec->argument(0).toString(exec))); if (exec->hadException()) return JSValue::encode(jsUndefined()); JSC::JSValue result = jsBoolean(imp->send(data, ec)); setDOMException(exec, ec); return JSValue::encode(result); }
void WebSocketServer::listen() { // First check existing connections: for( byte x=0; x < m_maxConnections; x++ ) { if( !m_connections[x] ) continue; WebSocket *s = m_connections[x]; if( !s->isConnected() ) { m_connectionCount--; delete s; m_connections[x] = NULL; continue; } s->listen(); } EthernetClient cli = m_server.available(); if( !cli ) return; // Find a slot: for( byte x=0; x < m_maxConnections; x++ ) { if( m_connections[x] ) continue; WebSocket *s = new WebSocket(this, cli); m_connections[x] = s; m_connectionCount++; #ifdef DEBUG Serial.println(F("Websocket client connected.")); #endif return; } // No room! #ifdef DEBUG Serial.println(F("Cannot accept new websocket client, maxConnections reached!")); #endif cli.stop(); }
/** * @author John M. Harris, Jr. * @internal */ int WebSocket::lua_close(lua_State* L){ WebSocket* LuaWebSocket = checkWebSocket(L, 1); if(LuaWebSocket){ if(LuaWebSocket->m_webSocket){ if(LuaWebSocket->m_webSocket->getState() == QAbstractSocket::ConnectedState){ ob_enum::LuaEnumItem* val = ob_enum::checkEnumItem(L, 2, ob_enum::LuaCloseCode); ob_enum::CloseCode cc = ob_enum::CloseCode::Normal; if(val){ cc = (ob_enum::CloseCode)val->value; } QString reason; if(lua_isstring(L, 3)){ reason = QString(lua_tostring(L, 3)); } LuaWebSocket->close(cc, reason); return 0; } } luaL_error(L, "WebSocket is already closed."); } return 0; }
bool HttpServer::initWebSocket(HttpServerConnection& connection, HttpRequest& request, HttpResponse& response) { if (!wsEnabled) return false; WebSocket *sock = new WebSocket(&connection); if (!sock->initialize(request, response)) return false; connection.setTimeOut(USHRT_MAX); //Disable disconnection on connection idle (no rx/tx) connection.setDisconnectionHandler(HttpServerConnectionDelegate(&HttpServer::onCloseWebSocket, this)); // auto remove on close response.sendHeader(connection); // Will push header before user data wsocks.addElement(sock); if (wsConnect) wsConnect(*sock); if (wsCommandEnabled && (request.getQueryParameter(wsCommandRequestParam) == "true")) { debugf("WebSocket Commandprocessor started"); sock->enableCommand(); } }
void SIOClientImpl::emit(std::string endpoint, std::string eventname, std::string args) { std::stringstream pre; std::string path = endpoint == "/" ? "" : endpoint; pre << "5::" << path << ":{\"name\":\"" << eventname << "\",\"args\":" << args << "}"; std::string msg = pre.str(); log("emitting event with data: %s", msg.c_str()); _ws->send(msg); }
void SIOClientImpl::send(std::string endpoint, std::string s) { std::stringstream pre; std::string path = endpoint == "/" ? "" : endpoint; pre << "3::" << path << ":" << s; std::string msg = pre.str(); log("sending message: %s", msg.c_str()); _ws->send(msg); }
int Server::_webSocketData(struct mg_connection *conn, string data) { WebSocket *websocket = websockets.getWebSocket(conn); if (websocket != NULL) { websocket->appendData(data); string fullPacket = websocket->flushData(); vector<Controller *>::iterator it; for (it=controllers.begin(); it!=controllers.end(); it++) { (*it)->webSocketData(websocket, fullPacket); } if (websocket->isClosed()) { websockets.remove(websocket); return 0; } else { return -1; } } else { return 0; } }
void SIOClientImpl::openSocket() { log("SIOClientImpl::openSocket() called"); std::stringstream s; s << _uri << "/socket.io/1/websocket/" << _sid; _ws = new WebSocket(); if (!_ws->init(*this, s.str())) { CC_SAFE_DELETE(_ws); } return; }
/*! \internal */ WebSocket *WebSocket::upgradeFrom(QTcpSocket *pTcpSocket, const HandshakeRequest &request, const HandshakeResponse &response, QObject *parent) { WebSocket *pWebSocket = new WebSocket(pTcpSocket, response.getAcceptedVersion(), parent); pWebSocket->setExtension(response.getAcceptedExtension()); pWebSocket->setOrigin(request.getOrigin()); pWebSocket->setRequestUrl(request.getRequestUrl()); pWebSocket->setProtocol(response.getAcceptedProtocol()); pWebSocket->setResourceName(request.getRequestUrl().toString(QUrl::RemoveUserInfo)); pWebSocket->enableMasking(false); //a server should not send masked frames return pWebSocket; }
void WebSocketTest::properties() { WebSocket websocket; QCOMPARE(websocket.messagesType(), WebSocket::BINARY_MESSAGE); websocket.setMessagesType(WebSocket::TEXT_MESSAGE); QCOMPARE(websocket.messagesType(), WebSocket::TEXT_MESSAGE); websocket.setMessagesType(WebSocket::BINARY_MESSAGE); QCOMPARE(websocket.messagesType(), WebSocket::BINARY_MESSAGE); }
void SIOClientImpl::disconnectFromEndpoint(const std::string& endpoint) { _clients.erase(endpoint); if (_clients.empty() || endpoint == "/") { log("SIOClientImpl::disconnectFromEndpoint out of endpoints, checking for disconnect"); if(_connected) this->disconnect(); } else { std::string path = endpoint == "/" ? "" : endpoint; std::string s = "0::" + path; _ws->send(s); } }
void WsThreadHelper::update(float dt) { WsMessage *msg = NULL; // Returns quickly if no message std::lock_guard<std::mutex> lk(_UIWsMessageQueueMutex); if (0 == _UIWsMessageQueue->size()) { return; } // Gets message msg = *(_UIWsMessageQueue->begin()); _UIWsMessageQueue->pop_front(); if (_ws) { _ws->onUIThreadReceiveMessage(msg); } CC_SAFE_DELETE(msg); }
int main( int argc, const char** argv ) { int camera_number = 0; char socket_url[512]; TopCodeScanner scanner; WebSocket *socket = NULL; if (argc < 2) { cerr << "expected: " << argv[0] << " <camera_number> [socket server]" << endl; cerr << " example: > topcodes 0 ws://localhost:8126/topcodes" << endl; return -1; } // get the camera number camera_number = atoi(argv[1]); // 0 if error if (argc >= 3) { socket = WebSocket::from_url(argv[2]); } else { socket = WebSocket::from_url("ws://localhost:8126/topcodes"); } // open the default camera VideoCapture cap(camera_number); if (!cap.isOpened()) { cerr << "Error: Unable to open webcam " << camera_number << endl; return -1; } for(;;) { Mat frame, grey, flipped; // capture the next still video frame cap >> frame; // flip the image horizontally so that it gives you a mirror reflection flip(frame, flipped, 1); // convert to greyscale cvtColor(flipped, grey, CV_RGB2GRAY); // scan for topcodes vector<TopCode*> *codes = scanner.scan(grey); // send topcode info through the websocket if (socket) { string json = "[\n"; for (int i=0; i<codes->size(); i++) { TopCode *code = (*codes)[i]; json += (" " + code->toJSON() + ",\n"); } json += "]"; socket->send(json); socket->poll(); socket->dispatch(handle_message); } // show the resulting image (debuggin) imshow("webcam", grey); // press the 'q' key to quit if (waitKey(30) >= 0) break; } if (socket) delete socket; }
void sendTextFrame(WebSocket& ws, const std::string& s) { ws.sendFrame(s.data(), s.size()); }
bool js_cocos2dx_extension_WebSocket_constructor(JSContext *cx, uint32_t argc, jsval *vp) { JS::CallArgs args = JS::CallArgsFromVp(argc, vp); if (argc == 1 || argc == 2) { std::string url; do { bool ok = jsval_to_std_string(cx, args.get(0), &url); JSB_PRECONDITION2( ok, cx, false, "Error processing arguments"); } while (0); JS::RootedObject proto(cx, js_cocos2dx_websocket_prototype); JS::RootedObject obj(cx, JS_NewObject(cx, js_cocos2dx_websocket_class, proto, JS::NullPtr())); //JS::RootedObject obj(cx, JS_NewObjectForConstructor(cx, js_cocos2dx_websocket_class, args)); WebSocket* cobj = new (std::nothrow) WebSocket(); JSB_WebSocketDelegate* delegate = new (std::nothrow) JSB_WebSocketDelegate(); delegate->setJSDelegate(obj); if (argc == 2) { std::vector<std::string> protocols; if (args.get(1).isString()) { std::string protocol; do { bool ok = jsval_to_std_string(cx, args.get(1), &protocol); JSB_PRECONDITION2( ok, cx, false, "Error processing arguments"); } while (0); protocols.push_back(protocol); } else if (args.get(1).isObject()) { bool ok = true; JS::RootedObject arg2(cx, args.get(1).toObjectOrNull()); JSB_PRECONDITION(JS_IsArrayObject( cx, arg2 ), "Object must be an array"); uint32_t len = 0; JS_GetArrayLength(cx, arg2, &len); for( uint32_t i=0; i< len;i++ ) { JS::RootedValue valarg(cx); JS_GetElement(cx, arg2, i, &valarg); std::string protocol; do { ok = jsval_to_std_string(cx, valarg, &protocol); JSB_PRECONDITION2( ok, cx, false, "Error processing arguments"); } while (0); protocols.push_back(protocol); } } cobj->init(*delegate, url, &protocols); } else { cobj->init(*delegate, url); } JS_DefineProperty(cx, obj, "URL", args.get(0), JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY); //protocol not support yet (always return "") JS::RootedValue jsprotocol(cx, c_string_to_jsval(cx, "")); JS_DefineProperty(cx, obj, "protocol", jsprotocol, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY); // link the native object with the javascript object js_proxy_t *p = jsb_new_proxy(cobj, obj); JS::AddNamedObjectRoot(cx, &p->obj, "WebSocket"); args.rval().set(OBJECT_TO_JSVAL(obj)); return true; } JS_ReportError(cx, "wrong number of arguments: %d, was expecting %d", argc, 0); return false; }
void wsMessageReceived(WebSocket& socket, const String& message) { Serial.printf("WebSocket message received:\r\n%s\r\n", message.c_str()); String response = "Echo: " + message; socket.sendString(response); }
void DirectWebReader::read() { WebSocket *socket = new WebSocket(m_request, this, new WebSocketOutput(m_socketHandler)); socket->readRequest(); }
void wsMessageReceived(WebSocket& socket, const String& message) { //Serial.printf("WebSocket message received:\r\n%s\r\n", message.c_str()); char buf[22]; dtostrf(pf, 10, 8, buf); socket.sendString(buf); }
JSBool js_cocos2dx_extension_WebSocket_constructor(JSContext *cx, uint32_t argc, jsval *vp) { jsval *argv = JS_ARGV(cx, vp); if (argc == 1 || argc == 2) { std::string url; do { JSBool ok = jsval_to_std_string(cx, argv[0], &url); JSB_PRECONDITION2( ok, cx, JS_FALSE, "Error processing arguments"); } while (0); JSObject *obj = JS_NewObject(cx, js_cocos2dx_websocket_class, js_cocos2dx_websocket_prototype, NULL); WebSocket* cobj = new WebSocket(); JSB_WebSocketDelegate* delegate = new JSB_WebSocketDelegate(); delegate->setJSDelegate(obj); if (argc == 2) { std::vector<std::string> protocols; if (JSVAL_IS_STRING(argv[1])) { std::string protocol; do { JSBool ok = jsval_to_std_string(cx, argv[1], &protocol); JSB_PRECONDITION2( ok, cx, JS_FALSE, "Error processing arguments"); } while (0); protocols.push_back(protocol); } else if (argv[1].isObject()) { JSBool ok = JS_TRUE; JSObject* arg2 = JSVAL_TO_OBJECT(argv[1]); JSB_PRECONDITION(JS_IsArrayObject( cx, arg2 ), "Object must be an array"); uint32_t len = 0; JS_GetArrayLength(cx, arg2, &len); for( uint32_t i=0; i< len;i++ ) { jsval valarg; JS_GetElement(cx, arg2, i, &valarg); std::string protocol; do { ok = jsval_to_std_string(cx, valarg, &protocol); JSB_PRECONDITION2( ok, cx, JS_FALSE, "Error processing arguments"); } while (0); protocols.push_back(protocol); } } cobj->init(*delegate, url, &protocols); } else { cobj->init(*delegate, url); } JS_DefineProperty(cx, obj, "URL", argv[0] , NULL, NULL, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY); //protocol not support yet (always return "") JS_DefineProperty(cx, obj, "protocol", c_string_to_jsval(cx, "") , NULL, NULL, JSPROP_ENUMERATE | JSPROP_PERMANENT | JSPROP_READONLY); // link the native object with the javascript object js_proxy_t *p = jsb_new_proxy(cobj, obj); JS_AddNamedObjectRoot(cx, &p->obj, "WebSocket"); JS_SET_RVAL(cx, vp, OBJECT_TO_JSVAL(obj)); return JS_TRUE; } JS_ReportError(cx, "wrong number of arguments: %d, was expecting %d", argc, 0); return JS_FALSE; }
int main() { AutoPtr<XMLConfiguration> pConf(new XMLConfiguration("settings.xml")); // instantiating the XMLConfiguration and reading from setting.xml char buffer[2048]; memset(buffer, 0, sizeof buffer); int flags; int n; string payload; string out; int msg_cnt = 0; pthread_t fifoReadThread; //indivudual thread for fifo so it doesn't block other stuff int iret1 = pthread_create(&fifoReadThread, NULL, CreatePiSocketFifo, NULL); //variables to be set in xml config file // string signalr_service_url = pConf->getString("signalr_url"); string signalr_url_endpoint = pConf->getString("signalr_url_endpoint"); int signalr_service_port = pConf->getInt("signalr_port"); int timeout_seconds = pConf->getInt("timeout"); string api_endpoint_url = pConf->getString("api_endpoint_url"); // "" //pipe_from_main = pConf->getString("pipe_from_main"); //string pipe_from_socket = pConf->getString("pipe_from_socket"); //--------------------------------------// //cout << endl << "=============================================================" << endl; //cout << "api_endpoint_url -> " << api_endpoint_url << endl; //cout << "signalr_url_endpoint -> " << signalr_url_endpoint << endl; //cout << "signalr_service_port -> " << signalr_service_port << endl; //cout << "timeout_seconds -> " << timeout_seconds << endl; //cout << "api_endpoint_url -> " << api_endpoint_url << endl; //cout << "pipe_from_main -> " << pipe_from_main; //cout << endl << "=============================================================" << endl << endl; //cout << "Opening pipe: " << pipe_from_main << endl; //fd = open(pipe_from_main.c_str(), O_WRONLY); // open pipe as readonly //write(fd, "Hello World", sizeof("Hello World")); //close(fd); conn: //label for the goto's in the catches try{ time_t seconds_past_epoch = time(0); cout << "STARTING " << endl; char port[100]; char id[100]; snprintf(port, sizeof(port), "%d", signalr_service_port); // converting int variables to char[] snprintf(id, sizeof(id), "%ld", (seconds_past_epoch * 1000)); // converting int variables to char[] string my_mac = getMACC(); //Get the mac address //compose the URI for getting the token URI uri("http://" + signalr_service_url + ":" + port + "/" + signalr_url_endpoint + "/negotiate?_" + id + "&UID=" + my_mac); HTTPClientSession session(uri.getHost(), uri.getPort()); // instantiating a client session //if there is a network problem between Pi and SignalR everything will break and the catch will point back to the goto label //we set this in order to a lower minimise the retry period thus the downtime session.setTimeout(timeout_seconds * 1e+6); // time in microseconds; string path(uri.getPathAndQuery()); // send the request HTTPRequest req(HTTPRequest::HTTP_GET, path, HTTPMessage::HTTP_1_1); session.sendRequest(req); StringTokenizer tokenizer(session.socket().address().toString(), ":", StringTokenizer::TOK_TRIM); // get the request originating address:ip from the session socket initiated by HTPP; tokenize it for IP extraction //string my_mac = getMAC((tokenizer[0]).c_str()); // call IP to MAC converter // get response HTTPResponse res; istream& is = session.receiveResponse(res); // stream the request cout << res.getStatus() << " " << res.getReason() << endl; // get the status code of the transaction // convert the istream to sting for further processing istreambuf_iterator<char> eos; string s(istreambuf_iterator<char>(is), eos); const char * cc = s.c_str(); // instantiate a rapidjson document and fill it up with the response of the negotiation request rapidjson::Document document; document.Parse<0>(cc); string token = document["ConnectionToken"].GetString(); // parse the response and get the connectionToken //============================================= //connect to signarR using the connectionToken got previously HTTPClientSession cs(signalr_service_url, signalr_service_port); // instantiate simple webclient string what = "/" + signalr_url_endpoint + "/connect?transport=webSockets&connectionToken=" + urlencode(token) + "&UID=" + my_mac + "&connectionData=%5B%7B%22name%22%3A%22myhub%22%7D%5D&tid=10"; // compose the request string HTTPRequest request(HTTPRequest::HTTP_GET, what, "HTTP/1.1"); // the protocol MUST be HTTP/1.1, as described in RFC6455; else the UPGRADE to websocket request will fail request.set("Host", signalr_service_url); // specify the Host header to be sent HTTPResponse response; // instantiate a http response cout << response.getStatus() << " " << response.getReason() << endl; WebSocket * ws = new WebSocket(cs, request, response); // instantiate a WebSocket transaction to the 'cs' session, sending the 'request' and storing the 'response' //sample of a message to be sent payload = "{\"H\":\"myhub\",\"M\":\"Send\",\"A\":[\"" + my_mac + "\",\"invoked from " + replaceInPlace(my_mac, std::string(":"), std::string("-")) + " client\"],\"I\":0}"; // cout << endl << payload << endl ; ws->sendFrame(payload.data(), payload.size(), WebSocket::FRAME_TEXT); // send the message to signalR using the payload and setting the type of frame to be sent as FRAME_TEXT flags = 1; // starting the receiving loop while( (flags & WebSocket::FRAME_OP_BITMASK) != WebSocket::FRAME_OP_CLOSE ) // while websocket session open { n = ws->receiveFrame(buffer, sizeof(buffer), flags); // n is the received frame // flags store the response flags of the frame // 129 = single frame response // 1 = start of multi-frame response // 0 = continuation frame of a multi-frame response // 128 = FIN frame os a multi-frame response // signalR send data in JSON format, and it send empty messages (empty json document) on a regular basis if( (n != 2) && flags !=1 ) // filter out empty jsons and multiframe responses (multiframe will be treated further on) { cout << "RCV[" << msg_cnt << "]=> " << buffer << " ===== " << unsigned(flags) << endl; } if(flags == 1){ // if I get a start frame of a multi-frame response means that I am getting something usefull from signalR string str(buffer); out += str; // due to flag == 1, we are expecting several frames, until we got flag == 128 do{ n = ws->receiveFrame(buffer, sizeof(buffer), flags); string str(buffer); out += str; // we add the next frame/frames to the out variable, to construct the whole JSON message str = ""; memset(buffer, 0, sizeof buffer); // be sure to empty the buffer to don't end up with junk }while(flags != 128); cout << endl << "=> " << out << endl; //not as we got a valid response from signalR endpoint, lets process it //convert the out variable and pass is as a Document to the JSON parser const char * c = out.c_str(); rapidjson::Document document; document.Parse<0>(c); out = document["M"][rapidjson::SizeType(0)]["A"][rapidjson::SizeType(1)].GetString(); // get out only the actual sent message from the response message SendMessageToMain(out.c_str()); cout << "Msg Received"; message_action(api_endpoint_url,out); // do something with the message in the message_action function out = ""; } msg_cnt++; memset(buffer, 0, sizeof buffer); // we always cleanup } ws->shutdown(); } // if something goes wrong with the connection, we try to recover catch (WebSocketException& exc0) { cout <<"WebSocketException "<< exc0.displayText() << endl; } catch (Poco::TimeoutException& exc1) // handle webclient errors { goto conn; // lets try again from the top cout <<"TimeoutException "<< exc1.displayText() << endl; // return 1; } catch (ConnectionResetException& exc) // handle connec errors { goto conn; // lets try again from the top cout << "!!!ConnectionResetException:" << exc.displayText() << endl; // return 1; } cout << strerror(errno) << endl; return 0; }