uint8_t REDFLY::socketClose(uint8_t socket) { uint8_t ret=0; while(available()) //check for new data, if socket already closed? { uint8_t sock=INVALID_SOCKET; uint16_t len=0; socketRead(&sock, &len, 0, 0, 0, 0); if(sock == socket) { while(len) //clear buffer { uint8_t b[8]; sock = socket; socketRead(&sock, &len, 0, 0, b, 8); } } else { break; } } //close socket if opened if(socket != INVALID_SOCKET) { for(uint8_t i=0; i<MAX_SOCKETS; i++) { if(socket_state[i].handle == socket) { socket_state[i].handle = INVALID_SOCKET; socket_state[i].state = SOCKET_CLOSED; for(i=3; i!=0; i--) //try 3 times { ret = cmd(PSTR(CMD_CLS), socket); if((ret == 0) || (ret == 0xFE)) //(0xFE = socket already closed) { ret = 0; break; } } break; } } } return ret; }
void Connection::doRead() { while (true) { in_.reserve(1024); int bytes_read = socketRead(client_fd_, in_.writePtr(), in_.writeSize()); if (bytes_read > 0) { in_.advance(bytes_read); } if ((bytes_read < 0) && (errno == EAGAIN)) { acquire(); io_desc_->readWhenReady(); break; } else if (bytes_read < 0) { LOG(LogMessage::WARNING) << "Error on read (" << client_fd_ << "): " << strerror(errno); break; } else if (bytes_read == 0) { // The socket was closed. break; } else if (!readDone()) { LOG(LogMessage::WARNING) << "Error procesing read (" << client_fd_ << ")"; break; } // Continue issuing reads. } // This release matches the acquire done when scheduling the // startRead() call. release(); }
/* Similar to readLine, except that a null terminats the string */ int socketReadString(SOCKET sock, char *buf, int len) { int rr = 0; int n = 0; int r; for( ; n < (len - 1); n++) { r = socketRead(sock, &(buf[n]), 1, 0); if(r != 1) { buf[n] = 0; // Terminate the string. break; } rr += 1; if(buf[n] == 0) // null marks the end of the string { n++; buf[n] = 0; // Terminate the string. break; } } buf[len - 1] = 0; // ensure termination return rr; }
int Q3Process::qt_metacall(QMetaObject::Call _c, int _id, void **_a) { _id = QObject::qt_metacall(_c, _id, _a); if (_id < 0) return _id; if (_c == QMetaObject::InvokeMetaMethod) { switch (_id) { case 0: readyReadStdout(); break; case 1: readyReadStderr(); break; case 2: processExited(); break; case 3: wroteToStdin(); break; case 4: launchFinished(); break; case 5: tryTerminate(); break; case 6: kill(); break; case 7: writeToStdin((*reinterpret_cast< const QByteArray(*)>(_a[1]))); break; case 8: writeToStdin((*reinterpret_cast< const QString(*)>(_a[1]))); break; case 9: closeStdin(); break; case 10: socketRead((*reinterpret_cast< int(*)>(_a[1]))); break; case 11: socketWrite((*reinterpret_cast< int(*)>(_a[1]))); break; case 12: timeout(); break; case 13: closeStdinLaunch(); break; } _id -= 14; } return _id; }
/** * Requests a key over the socket * @param key The key to be retrieved * @param target A pointer to a char to store the value in * @param max_len The maximum number of bytes to be written in target, must be * greater than 0 * @return 0 on success, non-zero on failure */ int bbsocket_query(const char *key, char *target, size_t max_len) { char buff[BUFFER_SIZE]; snprintf(buff, sizeof buff, "Query %s", key); if (!socketWrite(&bb_status.bb_socket, buff, strlen(buff) + 1)) { bb_log(LOG_DEBUG, "Write failed for query of %s\n", key); return 1; } while (bb_status.bb_socket != -1) { if (socketRead(&bb_status.bb_socket, buff, sizeof (buff))) { if (strncmp("Value: ", buff, strlen("Value: "))) { bb_log(LOG_DEBUG, "Failed to query for %s: %s\n", key, buff); return 1; } strncpy(target, buff + strlen("Value: "), max_len); target[max_len - 1] = 0; /* remove trailing newline */ if (strlen(target)) { target[strlen(target) - 1] = 0; } return 0; } } bb_log(LOG_DEBUG, "Read failed for query of %s\n", key); return 1; }
/* Return number of bytes read. Return -1 on errors and EOF. */ static ssize innerRead(Webs *wp, char *buf, ssize size) { Ms *ms; uchar *mbuf; ssize nbytes; int msize, readMore; ms = (Ms*) wp->ssl; do { if ((msize = matrixSslGetReadbuf(ms->handle, &mbuf)) < 0) { return -1; } readMore = 0; if ((nbytes = socketRead(wp->sid, mbuf, msize)) < 0) { return nbytes; } else if (nbytes > 0) { nbytes = processIncoming(wp, buf, size, nbytes, &readMore); if (nbytes < 0) { sp = socketPtr(wp->sid); sp->flags |= SOCKET_EOF; return nbytes; } if (nbytes > 0) { return nbytes; } } } while (readMore); return 0; }
/* Reads a newline terminated string into 'buf' from a socket, up to a maximum of 'len' bytes. Returns the number of bytes read or -1 if an error occured. The contents of buf will be 0-terminated and will have the trailing newline like fgets(). NOTE: This function is very inefficient as it reads one character at a time until it sees the newline. */ int socketReadLine(SOCKET sock, char *buf, int len) { int rr = 0; int n = 0; int r; for( ; n < (len - 1); n++) { r = socketRead(sock, &(buf[n]), 1, 0); if(r != 1) { buf[n] = 0; // Terminate the string. break; } rr += 1; if(buf[n] == 13) // Discard CR's { n--; continue; } if(buf[n] == 10) // LF marks the end of the line { n++; buf[n] = 0; // Terminate the string. break; } } buf[len - 1] = 0; // ensure termination return rr; }
/** * Robustly reads a line delimited by '\n' into a buffer. Adapted from CSAPP. */ ssize_t socketReadline(struct socketIO *sp, char *usrbuf, size_t maxlen) { int rc; unsigned int n; char c, *bufp = usrbuf; /* Read data until newline or error */ for (n = 1; n < maxlen; n++) { if ((rc = socketRead(sp, &c, 1)) == 1) { *bufp++ = c; if (c == '\n') { n++; break; } } else if (rc == 0) { if (n == 1) { return (0); } else { break; } } else { return (-1); } } *bufp = 0; /* Return size */ return (n - 1); }
int socketGets(int sid, char_t **buf) { socket_t *sp; ringq_t *lq; char c; int rc, len; a_assert(buf); *buf = NULL; if ((sp = socketPtr(sid)) == NULL) { return -1; } lq = &sp->lineBuf; while (1) { if ((rc = socketRead(sid, &c, 1)) < 0) { return rc; } if (rc == 0) { /* * If there is a partial line and we are at EOF, pretend we saw a '\n' */ if (ringqLen(lq) > 0 && (sp->flags & SOCKET_EOF)) { c = '\n'; } else { return -1; } } /* * Validate length of request. Ignore long strings without newlines to * safeguard against long URL attacks. */ if (ringqLen(lq) > E_MAX_REQUEST) { c = '\n'; } /* * If a newline is seen, return the data excluding the new line to the * caller. If carriage return is seen, just eat it. */ if (c == '\n') { len = ringqLen(lq); if (len > 0) { *buf = ballocAscToUni((char *)lq->servp, len); } else { *buf = NULL; } ringqFlush(lq); return len; } else if (c == '\r') { continue; } ringqPutcA(lq, c); } return 0; }
int32_t read_nbytes(BSOCK * bsock, char *ptr, int32_t nbytes) { int32_t nleft, nread; #ifdef HAVE_TLS if (bsock->tls) { /* TLS enabled */ return (tls_bsock_readn(bsock, ptr, nbytes)); } #endif /* HAVE_TLS */ nleft = nbytes; while (nleft > 0) { errno = 0; nread = socketRead(bsock->m_fd, ptr, nleft); if (bsock->is_timed_out() || bsock->is_terminated()) { return -1; } #ifdef HAVE_WIN32 /* * For Windows, we must simulate Unix errno on a socket * error in order to handle errors correctly. */ if (nread == SOCKET_ERROR) { DWORD err = WSAGetLastError(); nread = -1; if (err == WSAEINTR) { errno = EINTR; } else if (err == WSAEWOULDBLOCK) { errno = EAGAIN; } else { errno = EIO; /* some other error */ } } #endif if (nread == -1) { if (errno == EINTR) { continue; } if (errno == EAGAIN) { bmicrosleep(0, 20000); /* try again in 20ms */ continue; } } if (nread <= 0) { return -1; /* error, or EOF */ } nleft -= nread; ptr += nread; if (bsock->use_bwlimit()) { bsock->control_bwlimit(nread); } } return nbytes - nleft; /* return >= 0 */ }
uint32_t REDFLY::gettime(uint8_t *server, uint16_t port) { uint8_t buf[64]; //min. NTP_PACKETLEN uint32_t time=0UL, timeout; uint8_t hNTP, sock, buf_len, *ptr; uint16_t rd, len; if(port == 0) { port = NTP_PORT; } //open connection to server hNTP = socketConnect(PROTO_UDP, server, port, port); if(hNTP != INVALID_SOCKET) { //send NTP request memset(buf, 0, NTP_PACKETLEN); buf[NTP_FLAGOFFSET] = (0<<6)|(1<<3)|(3<<0); //NTP flags: LI=0 | VN=1 | Mode=3 -> Client if(socketSend(hNTP, buf, NTP_PACKETLEN) == 0) { //get data ptr = buf; buf_len = 0; for(timeout=F_CPU/16UL; timeout!=0; timeout--) //about 3s { sock = hNTP; rd = socketRead(&sock, &len, ptr, sizeof(buf)-buf_len); if((rd != 0) && (rd != 0xFFFF)) //0xFFFF = connection closed { ptr += rd; buf_len += rd; } if(buf_len && (len == 0)) //all data received? { break; } } //check data if((buf_len >= NTP_PACKETLEN) && ((buf[NTP_FLAGOFFSET]&0x07) == 4)) //NTP flags: Mode=4 -> Server { //time = (uint32_t)*((uint32_t*)&buf[NTP_TIMEOFFSET]); time = (((uint32_t)buf[NTP_TIMEOFFSET+0])<<24)| (((uint32_t)buf[NTP_TIMEOFFSET+1])<<16)| (((uint32_t)buf[NTP_TIMEOFFSET+2])<< 8)| (((uint32_t)buf[NTP_TIMEOFFSET+3])<< 0); //swap32 time -= 2208988800UL; //sub seconds 1900-1970 } } socketClose(hNTP); } return time; }
/** * Prints the status of the Bumblebee server if available * @return EXIT_SUCCESS if the status is succesfully retrieved, * EXIT_FAILURE otherwise */ static int report_daemon_status(void) { char buffer[BUFFER_SIZE]; int r = snprintf(buffer, BUFFER_SIZE, "Status?"); socketWrite(&bb_status.bb_socket, buffer, r + 1); while (bb_status.bb_socket != -1) { r = socketRead(&bb_status.bb_socket, buffer, BUFFER_SIZE); if (r > 0) { printf("Bumblebee status: %*s\n", r, buffer); socketClose(&bb_status.bb_socket); return EXIT_SUCCESS; } } return EXIT_FAILURE; }
static void handle_socket(struct clientsocket * C) { static char buffer[BUFFER_SIZE]; //since these are local sockets, we can safely assume we get whole messages at a time int r = socketRead(&C->sock, buffer, BUFFER_SIZE); if (r > 0) { switch (buffer[0]) { case 'S'://status if (bb_status.errors[0] != 0) { r = snprintf(buffer, BUFFER_SIZE, "Error (%s): %s\n", GITVERSION, bb_status.errors); } else { if (bb_is_running(bb_status.x_pid)) { r = snprintf(buffer, BUFFER_SIZE, "Ready (%s). X is PID %i, %i applications using bumblebeed.\n", GITVERSION, bb_status.x_pid, bb_status.appcount); } else { r = snprintf(buffer, BUFFER_SIZE, "Ready (%s). X inactive.\n", GITVERSION); } } socketWrite(&C->sock, buffer, r); //we assume the write is fully successful. break; case 'F'://force VirtualGL if possible case 'C'://check if VirtualGL is allowed /// \todo Handle power management cases and powering card on/off. //no X? attempt to start it if (!bb_is_running(bb_status.x_pid)) { start_secondary(); } if (bb_is_running(bb_status.x_pid)) { r = snprintf(buffer, BUFFER_SIZE, "Yes. X is active.\n"); if (C->inuse == 0) { C->inuse = 1; bb_status.appcount++; } } else { if (bb_status.errors[0] != 0) { r = snprintf(buffer, BUFFER_SIZE, "No - error: %s\n", bb_status.errors); } else { r = snprintf(buffer, BUFFER_SIZE, "No, secondary X is not active.\n"); } } socketWrite(&C->sock, buffer, r); //we assume the write is fully successful. break; case 'D'://done, close the socket. socketClose(&C->sock); break; default: bb_log(LOG_WARNING, "Unhandled message received: %*s\n", r, buffer); break; } } }
/* Use a timer for polling misc. stuff. */ void Q3Process::timeout() { // Disable the timer temporary since one of the slots that are connected to // the readyRead...(), etc. signals might trigger recursion if // processEvents() is called. d->lookup->stop(); // try to write pending data to stdin if ( !d->stdinBuf.isEmpty() ) socketWrite( 0 ); if ( ioRedirection ) { socketRead( 1 ); // try stdout socketRead( 2 ); // try stderr } if ( isRunning() ) { // enable timer again, if needed if ( !d->stdinBuf.isEmpty() || ioRedirection || notifyOnExit ) d->lookup->start( 100 ); } else if ( notifyOnExit ) { emit processExited(); } }
bool QProcess::qt_invoke( int _id, QUObject* _o ) { switch ( _id - staticMetaObject()->slotOffset() ) { case 0: tryTerminate(); break; case 1: kill(); break; case 2: writeToStdin((const QByteArray&)*((const QByteArray*)static_QUType_ptr.get(_o+1))); break; case 3: writeToStdin((const QString&)static_QUType_QString.get(_o+1)); break; case 4: closeStdin(); break; case 5: socketRead((int)static_QUType_int.get(_o+1)); break; case 6: socketWrite((int)static_QUType_int.get(_o+1)); break; case 7: timeout(); break; case 8: closeStdinLaunch(); break; default: return QObject::qt_invoke( _id, _o ); } return TRUE; }
/*! Constructs a new QxtPop3 whith parent \a parent. */ QxtPop3::QxtPop3(QObject* parent) : QObject(parent), d_ptr(new QxtPop3Private) { d_ptr->q_ptr = this; d_ptr->state = QxtPop3Private::Disconnected; #ifndef QT_NO_OPENSSL d_ptr->socket = new QSslSocket(this); QObject::connect(socket(), SIGNAL(encrypted()), this, SIGNAL(encrypted())); QObject::connect(socket(), SIGNAL(encrypted()), d_func(),SLOT(encrypted())); #else d_func()->socket = new QTcpSocket(this); #endif QObject::connect(socket(), SIGNAL(connected()), this, SIGNAL(connected())); QObject::connect(socket(), SIGNAL(disconnected()), this, SIGNAL(disconnected())); QObject::connect(socket(), SIGNAL(disconnected()), d_func(), SLOT(disconnected())); QObject::connect(socket(), SIGNAL(error(QAbstractSocket::SocketError)), d_func(), SLOT(socketError(QAbstractSocket::SocketError))); QObject::connect(socket(), SIGNAL(readyRead()), d_func(), SLOT(socketRead())); }
QxtSmtp::QxtSmtp(QObject* parent) : QObject(parent) { QXT_INIT_PRIVATE(QxtSmtp); qxt_d().state = QxtSmtpPrivate::Disconnected; qxt_d().nextID = 0; #ifndef QT_NO_OPENSSL qxt_d().socket = new QSslSocket(this); QObject::connect(socket(), SIGNAL(encrypted()), this, SIGNAL(encrypted())); //QObject::connect(socket(), SIGNAL(encrypted()), &qxt_d(), SLOT(ehlo())); #else qxt_d().socket = new QTcpSocket(this); #endif QObject::connect(socket(), SIGNAL(connected()), this, SIGNAL(connected())); QObject::connect(socket(), SIGNAL(disconnected()), this, SIGNAL(disconnected())); QObject::connect(socket(), SIGNAL(error(QAbstractSocket::SocketError)), &qxt_d(), SLOT(socketError(QAbstractSocket::SocketError))); QObject::connect(this, SIGNAL(authenticated()), &qxt_d(), SLOT(sendNext())); QObject::connect(socket(), SIGNAL(readyRead()), &qxt_d(), SLOT(socketRead())); }
uint8_t REDFLY::socketStatus(uint8_t socket) { if(available()) //check for new data, if socket closed? { uint8_t sock=INVALID_SOCKET; uint16_t len=0; socketRead(&sock, &len, 0, 0, 0, 0); } for(uint8_t i=0; i<MAX_SOCKETS; i++) { if(socket_state[i].handle == socket) { return cmd(PSTR(CMD_CTCP), socket); } } return 0xFF; }
bool QWebProcessor::newConnection(qint16 port, qintptr socketDescriptor) { qDebug()<<"QWebProcessor->newConnection()"<<socketDescriptor<<QTime::currentTime().toString(); if (socket) { QTcpSocket *sock = new QTcpSocket(); sock->setSocketDescriptor(socketDescriptor); sock->close(); sock->deleteLater(); return true; }else { this->port = port; socket = new QTcpSocket(); connect(socket, SIGNAL(readyRead()), this, SLOT(socketRead())); connect(socket, SIGNAL(disconnected()), this, SLOT(onSocketDisconnected())); socket->setSocketDescriptor(socketDescriptor); return true; } }
/* Return number of bytes read. Return -1 on errors and EOF. */ static ssize innerRead(Webs *wp, char *buf, ssize size) { Ms *ms; uchar *mbuf; ssize nbytes; int msize, readMore; ms = (Ms*) wp->ms; do { if ((msize = matrixSslGetReadbuf(ms->handle, &mbuf)) < 0) { return -1; } readMore = 0; if ((nbytes = socketRead(wp->sid, mbuf, msize)) > 0) { if ((nbytes = processIncoming(wp, buf, size, nbytes, &readMore)) > 0) { return nbytes; } } } while (readMore); return 0; }
uint8_t REDFLY::socketClosed(uint8_t socket) { if(available()) //check for new data, if socket closed? { uint8_t sock=INVALID_SOCKET; uint16_t len=0; socketRead(&sock, &len, 0, 0, 0, 0); } if(socket != INVALID_SOCKET) { for(uint8_t i=0; i<MAX_SOCKETS; i++) { if(socket_state[i].handle == socket) //socket found { return 0; } } } return 1; }
ApcUpsMon::ApcUpsMon(QString host, quint16 port, int updint, QObject *parent) : QObject(parent) { bytesLeft = 0; lastResponseTimestamp = 0; connect(&socket, SIGNAL(readyRead()), this, SLOT(socketRead())); connect(&socket, SIGNAL(connected()), this, SLOT(timeout())); connect(&socket, SIGNAL(connected()), &timer, SLOT(start())); connect(&socket, SIGNAL(disconnected()), this, SLOT(timeout())); connect(&socket, SIGNAL(disconnected()), &timer, SLOT(stop())); connect(&socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); connect(&timer, SIGNAL(timeout()), this, SLOT(timeout())); connectToHost(host, port); setInterval(updint); // Launch D-BUS new ApcUpsMonAdaptor(this); QDBusConnection dbus = QDBusConnection::sessionBus(); dbus.registerObject("/", this); dbus.registerService("eu.navlost.apcupsmon"); }
Connection::Connection(QObject *p, QSslSocket *qtsSock) : QObject(p) { qtsSocket = qtsSock; qtsSocket->setParent(this); iPacketLength = -1; bDisconnectedEmitted = false; static bool bDeclared = false; if (! bDeclared) { bDeclared = true; qRegisterMetaType<QAbstractSocket::SocketError>("QAbstractSocket::SocketError"); } connect(qtsSocket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError))); connect(qtsSocket, SIGNAL(encrypted()), this, SIGNAL(encrypted())); connect(qtsSocket, SIGNAL(readyRead()), this, SLOT(socketRead())); connect(qtsSocket, SIGNAL(disconnected()), this, SLOT(socketDisconnected())); connect(qtsSocket, SIGNAL(sslErrors(const QList<QSslError> &)), this, SLOT(socketSslErrors(const QList<QSslError> &))); qtLastPacket.restart(); #ifdef Q_OS_WIN dwFlow = 0; #endif }
int sendRequest(ParseClientInternal *parseClient, const char *host, const char *httpVerb, const char *httpRequestBody, int addInstallationHeader) { short socketHandle = -1; short status = socketSslConnect(parseServer, sshPort); if (status >= 0) { socketHandle = status; #ifdef REQUEST_DEBUG DEBUG_PRINT("\r\n"); DEBUG_PRINT("[Parse] ---------\r\n"); DEBUG_PRINT("[Parse] Request :\r\n"); DEBUG_PRINT("[Parse] --------- Start -\r\n"); #endif /* REQUEST_DEBUG */ status = buildRequestHeaders(parseClient, host, httpVerb, httpRequestBody, addInstallationHeader); #ifdef REQUEST_DEBUG if (status >= 0) { DEBUG_PRINT("%s\r\n", dataBuffer); } else { DEBUG_PRINT("[Parse] Build request error: %d\r\n", status); } DEBUG_PRINT("[Parse] --------- End -\r\n"); DEBUG_PRINT("\r\n"); #endif /* REQUEST_DEBUG */ } if (status >= 0) { status = socketWrite(socketHandle, dataBuffer, status); } if (status >= 0) { #ifdef REQUEST_DEBUG DEBUG_PRINT("[Parse] ---------\r\n"); DEBUG_PRINT("[Parse] Response:\r\n"); DEBUG_PRINT("[Parse] --------- Start -\r\n"); #endif /* REQUEST_DEBUG */ memset(dataBuffer, 0, sizeof(dataBuffer)); status = socketRead(socketHandle, dataBuffer, sizeof(dataBuffer), 5000); #ifdef REQUEST_DEBUG if (status >= 0) { DEBUG_PRINT("%s\r\n", dataBuffer); } else { DEBUG_PRINT("[Parse] Response read error: %d\r\n", status); } DEBUG_PRINT("[Parse] --------- End -\r\n"); DEBUG_PRINT("\r\n"); #endif /* REQUEST_DEBUG */ socketClose(socketHandle); #ifdef REQUEST_DEBUG } else { DEBUG_PRINT("[Parse] Request write error: %d\r\n", status); #endif /* REQUEST_DEBUG */ } return status; }
Q3Membuf* Q3Process::membufStderr() { if( d->pipeStderr[0] != 0 ) socketRead( 2 ); return &d->bufStderr; }
uint8_t REDFLY::cmd(uint8_t *dst, uint8_t dst_size, PGM_P p1, char *v1, PGM_P p2, uint8_t *v2, uint16_t v2_size) { uint8_t c, i; uint32_t timeout; uint8_t buf[8]; //ERRORx if(read_state == 2) //currently receiving data? { return 0xFF; } else if(available()) //check for new data { uint8_t sock=INVALID_SOCKET; uint16_t len=0; socketRead(&sock, &len, 0, 0, 0, 0); if(len != 0) //rx data found { return 0xFF; } } //send p1 command c = pgm_read_byte(p1++); while(c != 0) { write(c); c = pgm_read_byte(p1++); } //send v1 parameter 1 if(v1) { while(*v1) { write(*v1++); } } //send p2 parameter 2 if(p2) { c = pgm_read_byte(p2++); while(c != 0) { if(c == 0xDB) //0xDB -> 0xDB 0xDD { write(0xDB); write(0xDD); c = pgm_read_byte(p2++); } else if((c == 0x0D) && (pgm_read_byte(p2) == 0x0A)) //\r\n -> 0xDB 0xDC { write(0xDB); write(0xDC); p2++; c = pgm_read_byte(p2++); } else { write(c); c = pgm_read_byte(p2++); } } } //send v2 parameter 3 if(v2_size) { while(v2_size) { if(v2[0] == 0xDB) //0xDB -> 0xDB 0xDD { write(0xDB); write(0xDD); v2++; v2_size--; } else if((v2[0] == 0x0D) && (v2[1] == 0x0A) && (v2_size >= 2)) //\r\n -> 0xDB 0xDC { write(0xDB); write(0xDC); v2+=2; v2_size-=2; } else { write(*v2++); v2_size--; } } } //flush rx and tx buffer flush_nowait(); //send end characters of command write('\r'); write('\n'); //read response timeout = F_CPU/4UL; //about 10s if(dst_size == 0) //dont save response { buf[0] = 0; buf[5] = 0; for(i=0; timeout!=0; timeout--) { if(available()) { c = read(); if(i < 8) { buf[i++] = c; if((buf[0] != 'O') && (buf[0] != 'E')) //OK or ERROR { i = 0; } } timeout = F_CPU/16384UL; //about 2ms } } } else //save response to dst { dst[0] = 0; dst[5] = 0; for(i=0; timeout!=0; timeout--) { if(available()) { c = read(); if(i < dst_size) { dst[i++] = c; if((dst[0] != 'O') && (dst[0] != 'E')) //OK or ERROR { i = 0; } } timeout = F_CPU/16384UL; //about 2ms } } buf[0] = dst[0]; buf[1] = dst[1]; buf[5] = dst[5]; } //check response if((buf[0] == 'O') && (buf[1] == 'K')) { return 0; //OK } else if((buf[0] == 'E') && (buf[1] == 'R') && (buf[5] != 0) && (buf[5] != '\r')) { return buf[5]; //ERROR code } return 0xFF; }
uint16_t REDFLY::socketRead(uint8_t *socket, uint16_t *len, uint8_t *dst, uint16_t dst_size) //TCP connection { return socketRead(socket, len, 0, 0, dst, dst_size); }
int main(int argc, char* argv[]) { /* Setup signal handling before anything else */ signal(SIGHUP, handle_signal); signal(SIGTERM, handle_signal); signal(SIGINT, handle_signal); signal(SIGQUIT, handle_signal); /* Initializing configuration */ init_config(argc, argv); /* set runmode depending on leftover arguments */ if (optind >= argc) { bb_status.runmode = BB_RUN_STATUS; } else { bb_status.runmode = BB_RUN_APP; } bb_init_log(); bb_log(LOG_DEBUG, "%s version %s starting...\n", bb_status.program_name, GITVERSION); /* Connect to listening daemon */ bb_status.bb_socket = socketConnect(bb_config.socket_path, SOCK_NOBLOCK); if (bb_status.bb_socket < 0) { bb_log(LOG_ERR, "Could not connect to bumblebee daemon - is it running?\n"); bb_closelog(); return EXIT_FAILURE; } char buffer[BUFFER_SIZE]; int r; /* Request status */ if (bb_status.runmode == BB_RUN_STATUS) { r = snprintf(buffer, BUFFER_SIZE, "Status?"); socketWrite(&bb_status.bb_socket, buffer, r); while (bb_status.bb_socket != -1) { r = socketRead(&bb_status.bb_socket, buffer, BUFFER_SIZE); if (r > 0) { printf("Bumblebee status: %*s\n", r, buffer); socketClose(&bb_status.bb_socket); } } } /* Run given application */ if (bb_status.runmode == BB_RUN_APP) { int ranapp = 0; r = snprintf(buffer, BUFFER_SIZE, "Checking availability..."); socketWrite(&bb_status.bb_socket, buffer, r); while (bb_status.bb_socket != -1) { r = socketRead(&bb_status.bb_socket, buffer, BUFFER_SIZE); if (r > 0) { bb_log(LOG_INFO, "Response: %*s\n", r, buffer); switch (buffer[0]) { case 'N': //No, run normally. socketClose(&bb_status.bb_socket); if (!bb_config.fallback_start){ bb_log(LOG_ERR, "Cannot access secondary GPU. Aborting.\n"); } break; case 'Y': //Yes, run through vglrun bb_log(LOG_INFO, "Running application through vglrun.\n"); ranapp = 1; //run vglclient if any method other than proxy is used if (strncmp(bb_config.vgl_compress, "proxy", BUFFER_SIZE) != 0) { char * vglclient_args[] = { "vglclient", "-detach", 0 }; bb_run_fork(vglclient_args); } char ** vglrun_args = malloc(sizeof (char *) * (9 + argc - optind)); vglrun_args[0] = "vglrun"; vglrun_args[1] = "-c"; vglrun_args[2] = bb_config.vgl_compress; vglrun_args[3] = "-d"; vglrun_args[4] = bb_config.x_display; vglrun_args[5] = "-ld"; vglrun_args[6] = bb_config.ld_path; vglrun_args[7] = "--"; for (r = 0; r < argc - optind; r++) { vglrun_args[8 + r] = argv[optind + r]; } vglrun_args[8 + r] = 0; bb_run_fork_wait(vglrun_args); socketClose(&bb_status.bb_socket); break; default: //Something went wrong - output and exit. bb_log(LOG_ERR, "Problem: %*s\n", r, buffer); socketClose(&bb_status.bb_socket); break; } } } if (!ranapp && bb_config.fallback_start) { bb_log(LOG_WARNING, "Running application normally.\n"); bb_run_exec(argv + optind); } } bb_closelog(); bb_stop_all(); //stop any started processes that are left return (EXIT_SUCCESS); }
/** * Starts a program with Bumblebee if possible * * @param argc The number of arguments * @param argv The values of arguments * @return The exitcode of the program on success, EXIT_FAILURE if the program * could not be started */ static int run_app(int argc, char *argv[]) { int exitcode = EXIT_FAILURE; char buffer[BUFFER_SIZE]; int r; int ranapp = 0; r = snprintf(buffer, BUFFER_SIZE, "Checking availability..."); socketWrite(&bb_status.bb_socket, buffer, r + 1); while (bb_status.bb_socket != -1) { r = socketRead(&bb_status.bb_socket, buffer, BUFFER_SIZE); if (r > 0) { bb_log(LOG_INFO, "Response: %s\n", buffer); switch (buffer[0]) { case 'N': //No, run normally. bb_log(LOG_ERR, "Cannot access secondary GPU%s\n", buffer+2); socketClose(&bb_status.bb_socket); if (!bb_config.fallback_start) { bb_log(LOG_ERR, "Aborting because fallback start is disabled.\n"); } break; case 'Y': //Yes, run through vglrun bb_log(LOG_INFO, "Running application through vglrun.\n"); ranapp = 1; //run vglclient if any method other than proxy is used if (strncmp(bb_config.vgl_compress, "proxy", BUFFER_SIZE) != 0) { char * vglclient_args[] = { "vglclient", "-detach", 0 }; bb_run_fork(vglclient_args, 1); } /* number of options passed to --vgl-options */ unsigned int vglrun_opts_count = 0; char *next_arg = bb_config.vglrun_options; /* read vglrun options only if there is an arguments list */ if (next_arg && next_arg[0]) { do { ++vglrun_opts_count; } while ((next_arg = strchr(next_arg + 1, ' '))); } /* position of next option */ unsigned int optno = 0; /* 7 for the first options, 1 for the -- and 1 for the trailing 0 */ char ** vglrun_args = malloc(sizeof (char *) * (9 + vglrun_opts_count + argc - optind)); vglrun_args[0] = "vglrun"; vglrun_args[1] = "-c"; vglrun_args[2] = bb_config.vgl_compress; vglrun_args[3] = "-d"; vglrun_args[4] = bb_config.x_display; vglrun_args[5] = "-ld"; vglrun_args[6] = bb_config.ld_path; optno = 7; next_arg = bb_config.vglrun_options; if (next_arg && next_arg[0]) { char *current_arg; do { current_arg = next_arg; next_arg = strchr(current_arg, ' '); /* cut the string if a space is found */ if (next_arg) { *next_arg = 0; /* the next argument starts at the position after the space */ next_arg++; } vglrun_args[optno++] = current_arg; } while (next_arg); } vglrun_args[optno++] = "--"; for (r = 0; r < argc - optind; r++) { vglrun_args[r + optno] = argv[optind + r]; } vglrun_args[optno+=r] = 0; exitcode = bb_run_fork(vglrun_args, 0); free(vglrun_args); socketClose(&bb_status.bb_socket); break; default: //Something went wrong - output and exit. bb_log(LOG_ERR, "Problem: %*s\n", r, buffer); socketClose(&bb_status.bb_socket); break; } } } if (!ranapp) { exitcode = run_fallback(argv + optind); } return exitcode; }
int read(char *buf, int len, int to) { if(isConnected()) return socketRead(sock, buf, len, to); return -1; }