From 741957914073eb9f4a1fa0cd5ae90cc17078a623 Mon Sep 17 00:00:00 2001 From: Tycho Date: Thu, 23 Jan 2014 10:25:56 -0800 Subject: Switched cEvent to use strerror_r for error messages --- src/OSSupport/Event.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/Event.cpp b/src/OSSupport/Event.cpp index cbacbba17..fe1128dc9 100644 --- a/src/OSSupport/Event.cpp +++ b/src/OSSupport/Event.cpp @@ -7,7 +7,9 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Event.h" - +#if not defined(_WIN32) +#include +#endif @@ -35,14 +37,18 @@ cEvent::cEvent(void) m_Event = sem_open(EventName.c_str(), O_CREAT, 777, 0 ); if (m_Event == SEM_FAILED) { - LOGERROR("cEvent: Cannot create event, errno = %i. Aborting server.", errno); + char buffer[1024]; + strerror_r(errno,buffer,1024); + LOGERROR("cEvent: Cannot create event, err = %s. Aborting server.", buffer); abort(); } // Unlink the semaphore immediately - it will continue to function but will not pollute the namespace // We don't store the name, so can't call this in the destructor if (sem_unlink(EventName.c_str()) != 0) { - LOGWARN("ERROR: Could not unlink cEvent. (%i)", errno); + char buffer[1024]; + strerror_r(errno,buffer,1024); + LOGWARN("ERROR: Could not unlink cEvent. (%s)", buffer); } } #endif // *nix @@ -61,7 +67,9 @@ cEvent::~cEvent() { if (sem_close(m_Event) != 0) { - LOGERROR("ERROR: Could not close cEvent. (%i)", errno); + char buffer[1024]; + strerror_r(errno,buffer,1024); + LOGERROR("ERROR: Could not close cEvent. (%s)", buffer); } } else @@ -88,7 +96,9 @@ void cEvent::Wait(void) int res = sem_wait(m_Event); if (res != 0 ) { - LOGWARN("cEvent: waiting for the event failed: %i, errno = %i. Continuing, but server may be unstable.", res, errno); + char buffer[1024]; + strerror_r(errno,buffer,1024); + LOGWARN("cEvent: waiting for the event failed: %i, err = %s. Continuing, but server may be unstable.", res, buffer); } #endif } @@ -108,7 +118,9 @@ void cEvent::Set(void) int res = sem_post(m_Event); if (res != 0) { - LOGWARN("cEvent: Could not set cEvent: %i, errno = %d", res, errno); + char buffer[1024]; + strerror_r(errno,buffer,1024); + LOGWARN("cEvent: Could not set cEvent: %i, err = %s", res, buffer); } #endif } -- cgit v1.2.3 From 59b8205f02eb7bf2954acba56fd63f485a30ece5 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 25 Jan 2014 05:51:03 -0800 Subject: Extracted cSocket::GetErrorString into GetOSErrorString --- src/OSSupport/BlockingTCPLink.cpp | 4 +-- src/OSSupport/Errors.cpp | 52 +++++++++++++++++++++++++++++++++++++++ src/OSSupport/Errors.h | 3 +++ src/OSSupport/Socket.cpp | 52 --------------------------------------- src/OSSupport/Socket.h | 7 +++--- src/OSSupport/SocketThreads.cpp | 3 ++- 6 files changed, 62 insertions(+), 59 deletions(-) create mode 100644 src/OSSupport/Errors.cpp create mode 100644 src/OSSupport/Errors.h (limited to 'src/OSSupport') diff --git a/src/OSSupport/BlockingTCPLink.cpp b/src/OSSupport/BlockingTCPLink.cpp index 08aec0c65..af50eda5d 100644 --- a/src/OSSupport/BlockingTCPLink.cpp +++ b/src/OSSupport/BlockingTCPLink.cpp @@ -2,7 +2,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "BlockingTCPLink.h" - +#include "Errors.h" @@ -75,7 +75,7 @@ bool cBlockingTCPLink::Connect(const char * iAddress, unsigned int iPort) server.sin_port = htons( (unsigned short)iPort); if (connect(m_Socket, (struct sockaddr *)&server, sizeof(server))) { - LOGWARN("cTCPLink: Connection to \"%s:%d\" failed (%s)", iAddress, iPort, cSocket::GetErrorString( cSocket::GetLastError() ).c_str() ); + LOGWARN("cTCPLink: Connection to \"%s:%d\" failed (%s)", iAddress, iPort,GetOSErrorString( cSocket::GetLastError() ).c_str() ); CloseSocket(); return false; } diff --git a/src/OSSupport/Errors.cpp b/src/OSSupport/Errors.cpp new file mode 100644 index 000000000..b2e8880bb --- /dev/null +++ b/src/OSSupport/Errors.cpp @@ -0,0 +1,52 @@ + +#include "Globals.h" + +#include "Errors.h" + +AString GetOSErrorString( int a_ErrNo ) +{ + char buffer[ 1024 ]; + AString Out; + + #ifdef _WIN32 + + FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, a_ErrNo, 0, buffer, ARRAYCOUNT(buffer), NULL); + Printf(Out, "%d: %s", a_ErrNo, buffer); + if (!Out.empty() && (Out[Out.length() - 1] == '\n')) + { + Out.erase(Out.length() - 2); + } + return Out; + + #else // _WIN32 + + // According to http://linux.die.net/man/3/strerror_r there are two versions of strerror_r(): + + #if ( _GNU_SOURCE ) && !defined(ANDROID_NDK) // GNU version of strerror_r() + + char * res = strerror_r( errno, buffer, ARRAYCOUNT(buffer) ); + if( res != NULL ) + { + Printf(Out, "%d: %s", a_ErrNo, res); + return Out; + } + + #else // XSI version of strerror_r(): + + int res = strerror_r( errno, buffer, ARRAYCOUNT(buffer) ); + if( res == 0 ) + { + Printf(Out, "%d: %s", a_ErrNo, buffer); + return Out; + } + + #endif // strerror_r() version + + else + { + Printf(Out, "Error %d while getting error string for error #%d!", errno, a_ErrNo); + return Out; + } + + #endif // else _WIN32 +} diff --git a/src/OSSupport/Errors.h b/src/OSSupport/Errors.h new file mode 100644 index 000000000..72ba98862 --- /dev/null +++ b/src/OSSupport/Errors.h @@ -0,0 +1,3 @@ + +AString GetOSErrorString(int a_ErrNo); + diff --git a/src/OSSupport/Socket.cpp b/src/OSSupport/Socket.cpp index d80c9bb3d..4226a7535 100644 --- a/src/OSSupport/Socket.cpp +++ b/src/OSSupport/Socket.cpp @@ -105,58 +105,6 @@ void cSocket::ShutdownReadWrite(void) - -AString cSocket::GetErrorString( int a_ErrNo ) -{ - char buffer[ 1024 ]; - AString Out; - - #ifdef _WIN32 - - FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, NULL, a_ErrNo, 0, buffer, ARRAYCOUNT(buffer), NULL); - Printf(Out, "%d: %s", a_ErrNo, buffer); - if (!Out.empty() && (Out[Out.length() - 1] == '\n')) - { - Out.erase(Out.length() - 2); - } - return Out; - - #else // _WIN32 - - // According to http://linux.die.net/man/3/strerror_r there are two versions of strerror_r(): - - #if ( _GNU_SOURCE ) && !defined(ANDROID_NDK) // GNU version of strerror_r() - - char * res = strerror_r( errno, buffer, ARRAYCOUNT(buffer) ); - if( res != NULL ) - { - Printf(Out, "%d: %s", a_ErrNo, res); - return Out; - } - - #else // XSI version of strerror_r(): - - int res = strerror_r( errno, buffer, ARRAYCOUNT(buffer) ); - if( res == 0 ) - { - Printf(Out, "%d: %s", a_ErrNo, buffer); - return Out; - } - - #endif // strerror_r() version - - else - { - Printf(Out, "Error %d while getting error string for error #%d!", errno, a_ErrNo); - return Out; - } - - #endif // else _WIN32 -} - - - - int cSocket::GetLastError() { #ifdef _WIN32 diff --git a/src/OSSupport/Socket.h b/src/OSSupport/Socket.h index 91c9ca5fd..4ca3d61f4 100644 --- a/src/OSSupport/Socket.h +++ b/src/OSSupport/Socket.h @@ -14,7 +14,7 @@ #endif - +#include "Errors.h" class cSocket @@ -57,11 +57,10 @@ public: /// Initializes the network stack. Returns 0 on success, or another number as an error code. static int WSAStartup(void); - static AString GetErrorString(int a_ErrNo); static int GetLastError(); static AString GetLastErrorString(void) { - return GetErrorString(GetLastError()); + return GetOSErrorString(GetLastError()); } /// Creates a new socket of the specified address family @@ -115,4 +114,4 @@ public: private: xSocket m_Socket; AString m_IPString; -}; \ No newline at end of file +}; diff --git a/src/OSSupport/SocketThreads.cpp b/src/OSSupport/SocketThreads.cpp index b8069cf00..74932daf8 100644 --- a/src/OSSupport/SocketThreads.cpp +++ b/src/OSSupport/SocketThreads.cpp @@ -7,6 +7,7 @@ #include "Globals.h" #include "SocketThreads.h" +#include "Errors.h" @@ -556,7 +557,7 @@ void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write) if (Sent < 0) { int Err = cSocket::GetLastError(); - LOGWARNING("Error %d while writing to client \"%s\", disconnecting. \"%s\"", Err, m_Slots[i].m_Socket.GetIPString().c_str(), cSocket::GetErrorString(Err).c_str()); + LOGWARNING("Error %d while writing to client \"%s\", disconnecting. \"%s\"", Err, m_Slots[i].m_Socket.GetIPString().c_str(), GetOSErrorString(Err).c_str()); m_Slots[i].m_Socket.CloseSocket(); if (m_Slots[i].m_Client != NULL) { -- cgit v1.2.3 From 977e277094750a22284b4a738269db295af3cad3 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sat, 25 Jan 2014 06:02:20 -0800 Subject: Switched cEvent to GetOSErrorString --- src/OSSupport/Errors.cpp | 1 + src/OSSupport/Errors.h | 2 ++ src/OSSupport/Event.cpp | 29 +++++++++++------------------ 3 files changed, 14 insertions(+), 18 deletions(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/Errors.cpp b/src/OSSupport/Errors.cpp index b2e8880bb..2e05f1df1 100644 --- a/src/OSSupport/Errors.cpp +++ b/src/OSSupport/Errors.cpp @@ -50,3 +50,4 @@ AString GetOSErrorString( int a_ErrNo ) #endif // else _WIN32 } + diff --git a/src/OSSupport/Errors.h b/src/OSSupport/Errors.h index 72ba98862..8ce9deb10 100644 --- a/src/OSSupport/Errors.h +++ b/src/OSSupport/Errors.h @@ -1,3 +1,5 @@ +#pragma once + AString GetOSErrorString(int a_ErrNo); diff --git a/src/OSSupport/Event.cpp b/src/OSSupport/Event.cpp index fe1128dc9..649a0a3cf 100644 --- a/src/OSSupport/Event.cpp +++ b/src/OSSupport/Event.cpp @@ -7,9 +7,7 @@ #include "Globals.h" // NOTE: MSVC stupidness requires this to be the same across all modules #include "Event.h" -#if not defined(_WIN32) -#include -#endif +#include "Errors.h" @@ -37,18 +35,16 @@ cEvent::cEvent(void) m_Event = sem_open(EventName.c_str(), O_CREAT, 777, 0 ); if (m_Event == SEM_FAILED) { - char buffer[1024]; - strerror_r(errno,buffer,1024); - LOGERROR("cEvent: Cannot create event, err = %s. Aborting server.", buffer); + AString error = GetOSErrorString(errno); + LOGERROR("cEvent: Cannot create event, err = %s. Aborting server.", error.c_str()); abort(); } // Unlink the semaphore immediately - it will continue to function but will not pollute the namespace // We don't store the name, so can't call this in the destructor if (sem_unlink(EventName.c_str()) != 0) { - char buffer[1024]; - strerror_r(errno,buffer,1024); - LOGWARN("ERROR: Could not unlink cEvent. (%s)", buffer); + AString error = GetOSErrorString(errno); + LOGWARN("ERROR: Could not unlink cEvent. (%s)", error.c_str()); } } #endif // *nix @@ -67,9 +63,8 @@ cEvent::~cEvent() { if (sem_close(m_Event) != 0) { - char buffer[1024]; - strerror_r(errno,buffer,1024); - LOGERROR("ERROR: Could not close cEvent. (%s)", buffer); + AString error = GetOSErrorString(errno); + LOGERROR("ERROR: Could not close cEvent. (%s)", error.c_str()); } } else @@ -96,9 +91,8 @@ void cEvent::Wait(void) int res = sem_wait(m_Event); if (res != 0 ) { - char buffer[1024]; - strerror_r(errno,buffer,1024); - LOGWARN("cEvent: waiting for the event failed: %i, err = %s. Continuing, but server may be unstable.", res, buffer); + AString error = GetOSErrorString(errno); + LOGWARN("cEvent: waiting for the event failed: %i, err = %s. Continuing, but server may be unstable.", res, error.c_str()); } #endif } @@ -118,9 +112,8 @@ void cEvent::Set(void) int res = sem_post(m_Event); if (res != 0) { - char buffer[1024]; - strerror_r(errno,buffer,1024); - LOGWARN("cEvent: Could not set cEvent: %i, err = %s", res, buffer); + AString error = GetOSErrorString(errno); + LOGWARN("cEvent: Could not set cEvent: %i, err = %s", res, error.c_str()); } #endif } -- cgit v1.2.3 From 5aa3fc4c564252359613eb0d91225247f65e0d45 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Sat, 25 Jan 2014 15:27:34 +0100 Subject: Added cFile::Flush(). This is useful when using cFile as a log file and we know the server may crash after a specific write, so we flush the file before continuing. --- src/OSSupport/File.cpp | 9 +++++++++ src/OSSupport/File.h | 45 +++++++++++++++++++++++++-------------------- 2 files changed, 34 insertions(+), 20 deletions(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index 9f7c0d439..0ebd04915 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -450,3 +450,12 @@ int cFile::Printf(const char * a_Fmt, ...) + +void cFile::Flush(void) +{ + fflush(m_File); +} + + + + diff --git a/src/OSSupport/File.h b/src/OSSupport/File.h index 01663a229..07fce6661 100644 --- a/src/OSSupport/File.h +++ b/src/OSSupport/File.h @@ -18,6 +18,8 @@ Usage: 2, Check if the file was opened using IsOpen() 3, Read / write 4, Destroy the instance + +For reading entire files into memory, just use the static cFile::ReadWholeFile() */ @@ -55,7 +57,7 @@ public: static const char PathSeparator = '/'; #endif - /// The mode in which to open the file + /** The mode in which to open the file */ enum eMode { fmRead, // Read-only. If the file doesn't exist, object will not be valid @@ -63,13 +65,13 @@ public: fmReadWrite // Read/write. If the file already exists, it will be left intact; writing will overwrite the data from the beginning } ; - /// Simple constructor - creates an unopened file object, use Open() to open / create a real file + /** Simple constructor - creates an unopened file object, use Open() to open / create a real file */ cFile(void); - /// Constructs and opens / creates the file specified, use IsOpen() to check for success + /** Constructs and opens / creates the file specified, use IsOpen() to check for success */ cFile(const AString & iFileName, eMode iMode); - /// Auto-closes the file, if open + /** Auto-closes the file, if open */ ~cFile(); bool Open(const AString & iFileName, eMode iMode); @@ -77,60 +79,63 @@ public: bool IsOpen(void) const; bool IsEOF(void) const; - /// Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open + /** Reads up to iNumBytes bytes into iBuffer, returns the number of bytes actually read, or -1 on failure; asserts if not open */ int Read (void * iBuffer, int iNumBytes); - /// Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open + /** Writes up to iNumBytes bytes from iBuffer, returns the number of bytes actually written, or -1 on failure; asserts if not open */ int Write(const void * iBuffer, int iNumBytes); - /// Seeks to iPosition bytes from file start, returns old position or -1 for failure; asserts if not open + /** Seeks to iPosition bytes from file start, returns old position or -1 for failure; asserts if not open */ int Seek (int iPosition); - /// Returns the current position (bytes from file start) or -1 for failure; asserts if not open + /** Returns the current position (bytes from file start) or -1 for failure; asserts if not open */ int Tell (void) const; - /// Returns the size of file, in bytes, or -1 for failure; asserts if not open + /** Returns the size of file, in bytes, or -1 for failure; asserts if not open */ int GetSize(void) const; - /// Reads the file from current position till EOF into an AString; returns the number of bytes read or -1 for error + /** Reads the file from current position till EOF into an AString; returns the number of bytes read or -1 for error */ int ReadRestOfFile(AString & a_Contents); // tolua_begin - /// Returns true if the file specified exists + /** Returns true if the file specified exists */ static bool Exists(const AString & a_FileName); - /// Deletes a file, returns true if successful + /** Deletes a file, returns true if successful */ static bool Delete(const AString & a_FileName); - /// Renames a file or folder, returns true if successful. May fail if dest already exists (libc-dependant)! + /** Renames a file or folder, returns true if successful. May fail if dest already exists (libc-dependant)! */ static bool Rename(const AString & a_OrigPath, const AString & a_NewPath); - /// Copies a file, returns true if successful. + /** Copies a file, returns true if successful. */ static bool Copy(const AString & a_SrcFileName, const AString & a_DstFileName); - /// Returns true if the specified path is a folder + /** Returns true if the specified path is a folder */ static bool IsFolder(const AString & a_Path); - /// Returns true if the specified path is a regular file + /** Returns true if the specified path is a regular file */ static bool IsFile(const AString & a_Path); - /// Returns the size of the file, or a negative number on error + /** Returns the size of the file, or a negative number on error */ static int GetSize(const AString & a_FileName); - /// Creates a new folder with the specified name. Returns true if successful. Path may be relative or absolute + /** Creates a new folder with the specified name. Returns true if successful. Path may be relative or absolute */ static bool CreateFolder(const AString & a_FolderPath); - /// Returns the entire contents of the specified file as a string. Returns empty string on error. + /** Returns the entire contents of the specified file as a string. Returns empty string on error. */ static AString ReadWholeFile(const AString & a_FileName); // tolua_end - /// Returns the list of all items in the specified folder (files, folders, nix pipes, whatever's there). + /** Returns the list of all items in the specified folder (files, folders, nix pipes, whatever's there). */ static AStringVector GetFolderContents(const AString & a_Folder); // Exported in ManualBindings.cpp int Printf(const char * a_Fmt, ...); + /** Flushes all the bufferef output into the file (only when writing) */ + void Flush(void); + private: #ifdef USE_STDIO_FILE FILE * m_File; -- cgit v1.2.3 From cc1284a753874aa7d351a6ea41aaec4662ca6e57 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 27 Jan 2014 21:27:13 +0100 Subject: Rewritten networking to use non-blocking sockets. This fixes #592. --- src/OSSupport/Socket.cpp | 31 +++++++- src/OSSupport/Socket.h | 9 +++ src/OSSupport/SocketThreads.cpp | 172 +++++++++++++++++++++++++++------------- src/OSSupport/SocketThreads.h | 26 ++++-- 4 files changed, 176 insertions(+), 62 deletions(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/Socket.cpp b/src/OSSupport/Socket.cpp index 4226a7535..3248eed88 100644 --- a/src/OSSupport/Socket.cpp +++ b/src/OSSupport/Socket.cpp @@ -320,7 +320,7 @@ bool cSocket::ConnectIPv4(const AString & a_HostNameOrAddr, unsigned short a_Por -int cSocket::Receive(char* a_Buffer, unsigned int a_Length, unsigned int a_Flags) +int cSocket::Receive(char * a_Buffer, unsigned int a_Length, unsigned int a_Flags) { return recv(m_Socket, a_Buffer, a_Length, a_Flags); } @@ -354,3 +354,32 @@ unsigned short cSocket::GetPort(void) const + +void cSocket::SetNonBlocking(void) +{ + #ifdef _WIN32 + u_long NonBlocking = 1; + int res = ioctlsocket(m_Socket, FIONBIO, &NonBlocking); + if (res != 0) + { + LOGERROR("Cannot set socket to non-blocking. This would make the server deadlock later on, aborting.\nErr: %d, %d, %s", + res, GetLastError(), GetLastErrorString().c_str() + ); + abort(); + } + #else + int NonBlocking = 1; + int res = ioctl(m_Socket, FIONBIO, (char *)&NonBlocking); + if (res != 0) + { + LOGERROR("Cannot set socket to non-blocking. This would make the server deadlock later on, aborting.\nErr: %d, %d, %s", + res, GetLastError(), GetLastErrorString().c_str() + ); + abort(); + } + #endif +} + + + + diff --git a/src/OSSupport/Socket.h b/src/OSSupport/Socket.h index 4ca3d61f4..bdc2babf5 100644 --- a/src/OSSupport/Socket.h +++ b/src/OSSupport/Socket.h @@ -24,6 +24,12 @@ public: { IPv4 = AF_INET, IPv6 = AF_INET6, + + #ifdef _WIN32 + ErrWouldBlock = WSAEWOULDBLOCK, + #else + ErrWouldBlock = EWOULDBLOCK, + #endif } ; #ifdef _WIN32 @@ -110,6 +116,9 @@ public: unsigned short GetPort(void) const; // Returns 0 on failure const AString & GetIPString(void) const { return m_IPString; } + + /** Sets the socket into non-blocking mode */ + void SetNonBlocking(void); private: xSocket m_Socket; diff --git a/src/OSSupport/SocketThreads.cpp b/src/OSSupport/SocketThreads.cpp index 74932daf8..3e2631733 100644 --- a/src/OSSupport/SocketThreads.cpp +++ b/src/OSSupport/SocketThreads.cpp @@ -175,6 +175,7 @@ void cSocketThreads::cSocketThread::AddClient(const cSocket & a_Socket, cCallbac m_Slots[m_NumSlots].m_Client = a_Client; m_Slots[m_NumSlots].m_Socket = a_Socket; + m_Slots[m_NumSlots].m_Socket.SetNonBlocking(); m_Slots[m_NumSlots].m_Outgoing.clear(); m_Slots[m_NumSlots].m_State = sSlot::ssNormal; m_NumSlots++; @@ -213,7 +214,9 @@ bool cSocketThreads::cSocketThread::RemoveClient(const cCallback * a_Client) else { // Query and queue the last batch of outgoing data: - m_Slots[i].m_Client->GetOutgoingData(m_Slots[i].m_Outgoing); + AString Data; + m_Slots[i].m_Client->GetOutgoingData(Data); + m_Slots[i].m_Outgoing.append(Data); if (m_Slots[i].m_Outgoing.empty()) { // No more outgoing data, shut the socket down immediately: @@ -386,38 +389,28 @@ void cSocketThreads::cSocketThread::Execute(void) // The main thread loop: while (!m_ShouldTerminate) { - // Put all sockets into the Read set: + // Read outgoing data from the clients: + QueueOutgoingData(); + + // Put sockets into the sets fd_set fdRead; + fd_set fdWrite; cSocket::xSocket Highest = m_ControlSocket1.GetSocket(); - - PrepareSet(&fdRead, Highest, false); + PrepareSets(&fdRead, &fdWrite, Highest); // Wait for the sockets: timeval Timeout; Timeout.tv_sec = 5; Timeout.tv_usec = 0; - if (select(Highest + 1, &fdRead, NULL, NULL, &Timeout) == -1) + if (select(Highest + 1, &fdRead, &fdWrite, NULL, &Timeout) == -1) { - LOG("select(R) call failed in cSocketThread: \"%s\"", cSocket::GetLastErrorString().c_str()); + LOG("select() call failed in cSocketThread: \"%s\"", cSocket::GetLastErrorString().c_str()); continue; } + // Perform the IO: ReadFromSockets(&fdRead); - - // Test sockets for writing: - fd_set fdWrite; - Highest = m_ControlSocket1.GetSocket(); - PrepareSet(&fdWrite, Highest, true); - Timeout.tv_sec = 0; - Timeout.tv_usec = 0; - if (select(Highest + 1, NULL, &fdWrite, NULL, &Timeout) == -1) - { - LOG("select(W) call failed in cSocketThread: \"%s\"", cSocket::GetLastErrorString().c_str()); - continue; - } - WriteToSockets(&fdWrite); - CleanUpShutSockets(); } // while (!mShouldTerminate) } @@ -426,10 +419,11 @@ void cSocketThreads::cSocketThread::Execute(void) -void cSocketThreads::cSocketThread::PrepareSet(fd_set * a_Set, cSocket::xSocket & a_Highest, bool a_IsForWriting) +void cSocketThreads::cSocketThread::PrepareSets(fd_set * a_Read, fd_set * a_Write, cSocket::xSocket & a_Highest) { - FD_ZERO(a_Set); - FD_SET(m_ControlSocket1.GetSocket(), a_Set); + FD_ZERO(a_Read); + FD_ZERO(a_Write); + FD_SET(m_ControlSocket1.GetSocket(), a_Read); cCSLock Lock(m_Parent->m_CS); for (int i = m_NumSlots - 1; i >= 0; --i) @@ -444,11 +438,16 @@ void cSocketThreads::cSocketThread::PrepareSet(fd_set * a_Set, cSocket::xSocket continue; } cSocket::xSocket s = m_Slots[i].m_Socket.GetSocket(); - FD_SET(s, a_Set); + FD_SET(s, a_Read); if (s > a_Highest) { a_Highest = s; } + if (!m_Slots[i].m_Outgoing.empty()) + { + // There's outgoing data for the socket, put it in the Write set + FD_SET(s, a_Write); + } } // for i - m_Slots[] } @@ -480,34 +479,37 @@ void cSocketThreads::cSocketThread::ReadFromSockets(fd_set * a_Read) int Received = m_Slots[i].m_Socket.Receive(Buffer, ARRAYCOUNT(Buffer), 0); if (Received <= 0) { - // The socket has been closed by the remote party - switch (m_Slots[i].m_State) + if (cSocket::GetLastError() != cSocket::ErrWouldBlock) { - case sSlot::ssNormal: - { - // Notify the callback that the remote has closed the socket; keep the slot - m_Slots[i].m_Client->SocketClosed(); - m_Slots[i].m_State = sSlot::ssRemoteClosed; - break; - } - case sSlot::ssWritingRestOut: - case sSlot::ssShuttingDown: - case sSlot::ssShuttingDown2: - { - // Force-close the socket and remove the slot: - m_Slots[i].m_Socket.CloseSocket(); - m_Slots[i] = m_Slots[--m_NumSlots]; - break; - } - default: + // The socket has been closed by the remote party + switch (m_Slots[i].m_State) { - LOG("%s: Unexpected socket state: %d (%s)", - __FUNCTION__, m_Slots[i].m_Socket.GetSocket(), m_Slots[i].m_Socket.GetIPString().c_str() - ); - ASSERT(!"Unexpected socket state"); - break; - } - } // switch (m_Slots[i].m_State) + case sSlot::ssNormal: + { + // Notify the callback that the remote has closed the socket; keep the slot + m_Slots[i].m_Client->SocketClosed(); + m_Slots[i].m_State = sSlot::ssRemoteClosed; + break; + } + case sSlot::ssWritingRestOut: + case sSlot::ssShuttingDown: + case sSlot::ssShuttingDown2: + { + // Force-close the socket and remove the slot: + m_Slots[i].m_Socket.CloseSocket(); + m_Slots[i] = m_Slots[--m_NumSlots]; + break; + } + default: + { + LOG("%s: Unexpected socket state: %d (%s)", + __FUNCTION__, m_Slots[i].m_Socket.GetSocket(), m_Slots[i].m_Socket.GetIPString().c_str() + ); + ASSERT(!"Unexpected socket state"); + break; + } + } // switch (m_Slots[i].m_State) + } } else { @@ -539,7 +541,9 @@ void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write) // Request another chunk of outgoing data: if (m_Slots[i].m_Client != NULL) { - m_Slots[i].m_Client->GetOutgoingData(m_Slots[i].m_Outgoing); + AString Data; + m_Slots[i].m_Client->GetOutgoingData(Data); + m_Slots[i].m_Outgoing.append(Data); } if (m_Slots[i].m_Outgoing.empty()) { @@ -553,8 +557,7 @@ void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write) } } // if (outgoing data is empty) - int Sent = m_Slots[i].m_Socket.Send(m_Slots[i].m_Outgoing.data(), m_Slots[i].m_Outgoing.size()); - if (Sent < 0) + if (!SendDataThroughSocket(m_Slots[i].m_Socket, m_Slots[i].m_Outgoing)) { int Err = cSocket::GetLastError(); LOGWARNING("Error %d while writing to client \"%s\", disconnecting. \"%s\"", Err, m_Slots[i].m_Socket.GetIPString().c_str(), GetOSErrorString(Err).c_str()); @@ -565,7 +568,6 @@ void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write) } return; } - m_Slots[i].m_Outgoing.erase(0, Sent); if (m_Slots[i].m_Outgoing.empty() && (m_Slots[i].m_State == sSlot::ssWritingRestOut)) { @@ -590,8 +592,41 @@ void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write) +bool cSocketThreads::cSocketThread::SendDataThroughSocket(cSocket & a_Socket, AString & a_Data) +{ + // Send data in smaller chunks, so that the OS send buffers aren't overflown easily + while (!a_Data.empty()) + { + size_t NumToSend = std::min(a_Data.size(), (size_t)1024); + int Sent = a_Socket.Send(a_Data.data(), NumToSend); + if (Sent < 0) + { + int Err = cSocket::GetLastError(); + if (Err == cSocket::ErrWouldBlock) + { + // The OS send buffer is full, leave the outgoing data for the next time + return true; + } + // An error has occured + return false; + } + if (Sent == 0) + { + a_Socket.CloseSocket(); + return true; + } + a_Data.erase(0, Sent); + } + return true; +} + + + + + void cSocketThreads::cSocketThread::CleanUpShutSockets(void) { + cCSLock Lock(m_Parent->m_CS); for (int i = m_NumSlots - 1; i >= 0; i--) { switch (m_Slots[i].m_State) @@ -617,3 +652,32 @@ void cSocketThreads::cSocketThread::CleanUpShutSockets(void) +void cSocketThreads::cSocketThread::QueueOutgoingData(void) +{ + cCSLock Lock(m_Parent->m_CS); + for (int i = 0; i < m_NumSlots; i++) + { + if (m_Slots[i].m_Client != NULL) + { + AString Data; + m_Slots[i].m_Client->GetOutgoingData(Data); + m_Slots[i].m_Outgoing.append(Data); + } + if (m_Slots[i].m_Outgoing.empty()) + { + // No outgoing data is ready + if (m_Slots[i].m_State == sSlot::ssWritingRestOut) + { + // The socket doesn't want to be kept alive anymore, and doesn't have any remaining data to send. + // Shut it down and then close it after a timeout, or when the other side agrees + m_Slots[i].m_State = sSlot::ssShuttingDown; + m_Slots[i].m_Socket.ShutdownReadWrite(); + } + continue; + } + } +} + + + + diff --git a/src/OSSupport/SocketThreads.h b/src/OSSupport/SocketThreads.h index 9e1947ab6..fcd2ce11f 100644 --- a/src/OSSupport/SocketThreads.h +++ b/src/OSSupport/SocketThreads.h @@ -66,7 +66,8 @@ public: /** Called when data is received from the remote party */ virtual void DataReceived(const char * a_Data, int a_Size) = 0; - /** Called when data can be sent to remote party; the function is supposed to *append* outgoing data to a_Data */ + /** Called when data can be sent to remote party + The function is supposed to *set* outgoing data to a_Data (overwrite) */ virtual void GetOutgoingData(AString & a_Data) = 0; /** Called when the socket has been closed for any reason */ @@ -156,16 +157,27 @@ private: virtual void Execute(void) override; - /** Puts all sockets into the set, along with m_ControlSocket1. - Only sockets that are able to send and receive data are put in the Set. - Is a_IsForWriting is true, the ssWritingRestOut sockets are added as well. */ - void PrepareSet(fd_set * a_Set, cSocket::xSocket & a_Highest, bool a_IsForWriting); + /** Prepares the Read and Write socket sets for select() + Puts all sockets into the read set, along with m_ControlSocket1. + Only sockets that have outgoing data queued on them are put in the write set.*/ + void PrepareSets(fd_set * a_ReadSet, fd_set * a_WriteSet, cSocket::xSocket & a_Highest); - void ReadFromSockets(fd_set * a_Read); // Reads from sockets indicated in a_Read - void WriteToSockets (fd_set * a_Write); // Writes to sockets indicated in a_Write + /** Reads from sockets indicated in a_Read */ + void ReadFromSockets(fd_set * a_Read); + /** Writes to sockets indicated in a_Write */ + void WriteToSockets (fd_set * a_Write); + + /** Sends data through the specified socket, trying to fill the OS send buffer in chunks. + Returns true if there was no error while sending, false if an error has occured. + Modifies a_Data to contain only the unsent data. */ + bool SendDataThroughSocket(cSocket & a_Socket, AString & a_Data); + /** Removes those slots in ssShuttingDown2 state, sets those with ssShuttingDown state to ssShuttingDown2 */ void CleanUpShutSockets(void); + + /** Calls each client's callback to retrieve outgoing data for that client. */ + void QueueOutgoingData(void); } ; typedef std::list cSocketThreadList; -- cgit v1.2.3 From 4169af1ce1a022d364edfa3313aa5a21d594f198 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 27 Jan 2014 21:33:06 +0100 Subject: Fixed Linux compilation. --- src/OSSupport/Socket.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/Socket.cpp b/src/OSSupport/Socket.cpp index 3248eed88..064abbab5 100644 --- a/src/OSSupport/Socket.cpp +++ b/src/OSSupport/Socket.cpp @@ -6,7 +6,8 @@ #ifndef _WIN32 #include #include - #include //inet_ntoa() + #include // inet_ntoa() + #include // ioctl() #else #define socklen_t int #endif -- cgit v1.2.3 From a359275064ecbaf3608995e82875532419a8ed80 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 27 Jan 2014 21:34:54 +0100 Subject: Squashed common code. --- src/OSSupport/Socket.cpp | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/Socket.cpp b/src/OSSupport/Socket.cpp index 064abbab5..6afaceedf 100644 --- a/src/OSSupport/Socket.cpp +++ b/src/OSSupport/Socket.cpp @@ -361,24 +361,17 @@ void cSocket::SetNonBlocking(void) #ifdef _WIN32 u_long NonBlocking = 1; int res = ioctlsocket(m_Socket, FIONBIO, &NonBlocking); - if (res != 0) - { - LOGERROR("Cannot set socket to non-blocking. This would make the server deadlock later on, aborting.\nErr: %d, %d, %s", - res, GetLastError(), GetLastErrorString().c_str() - ); - abort(); - } #else int NonBlocking = 1; int res = ioctl(m_Socket, FIONBIO, (char *)&NonBlocking); - if (res != 0) - { - LOGERROR("Cannot set socket to non-blocking. This would make the server deadlock later on, aborting.\nErr: %d, %d, %s", - res, GetLastError(), GetLastErrorString().c_str() - ); - abort(); - } #endif + if (res != 0) + { + LOGERROR("Cannot set socket to non-blocking. This would make the server deadlock later on, aborting.\nErr: %d, %d, %s", + res, GetLastError(), GetLastErrorString().c_str() + ); + abort(); + } } -- cgit v1.2.3 From 76457d367338b603808b7821036cf9edc6f95afb Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 28 Jan 2014 16:28:55 +0100 Subject: Fixed timing on *nix. --- src/OSSupport/Timer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/Timer.cpp b/src/OSSupport/Timer.cpp index ed16f9e3a..fd838dd0d 100644 --- a/src/OSSupport/Timer.cpp +++ b/src/OSSupport/Timer.cpp @@ -28,7 +28,7 @@ long long cTimer::GetNowTime(void) #else struct timeval now; gettimeofday(&now, NULL); - return (long long)(now.tv_sec * 1000 + now.tv_usec / 1000); + return (long long)now.tv_sec * 1000 + (long long)now.tv_usec / 1000; #endif } -- cgit v1.2.3 From 0b384198e535470ac4aaa7d8f38b3da62b12ea34 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 3 Feb 2014 10:38:25 +0100 Subject: SocketThreads: Fixed sending to closed socket. --- src/OSSupport/SocketThreads.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/SocketThreads.cpp b/src/OSSupport/SocketThreads.cpp index 3e2631733..269f1d452 100644 --- a/src/OSSupport/SocketThreads.cpp +++ b/src/OSSupport/SocketThreads.cpp @@ -557,6 +557,11 @@ void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write) } } // if (outgoing data is empty) + if (m_Slots[i].m_State == sSlot::ssRemoteClosed) + { + continue; + } + if (!SendDataThroughSocket(m_Slots[i].m_Socket, m_Slots[i].m_Outgoing)) { int Err = cSocket::GetLastError(); @@ -566,7 +571,7 @@ void cSocketThreads::cSocketThread::WriteToSockets(fd_set * a_Write) { m_Slots[i].m_Client->SocketClosed(); } - return; + continue; } if (m_Slots[i].m_Outgoing.empty() && (m_Slots[i].m_State == sSlot::ssWritingRestOut)) -- cgit v1.2.3 From c9916cd8c2332b6d6992ab38c0339ced6c91bc92 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Mon, 3 Feb 2014 17:07:46 +0100 Subject: Fixed socket leaking. --- src/OSSupport/SocketThreads.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/OSSupport') diff --git a/src/OSSupport/SocketThreads.cpp b/src/OSSupport/SocketThreads.cpp index 269f1d452..a02661d2c 100644 --- a/src/OSSupport/SocketThreads.cpp +++ b/src/OSSupport/SocketThreads.cpp @@ -209,6 +209,10 @@ bool cSocketThreads::cSocketThread::RemoveClient(const cCallback * a_Client) if (m_Slots[i].m_State == sSlot::ssRemoteClosed) { // The remote has already closed the socket, remove the slot altogether: + if (m_Slots[i].m_Socket.IsValid()) + { + m_Slots[i].m_Socket.CloseSocket(); + } m_Slots[i] = m_Slots[--m_NumSlots]; } else @@ -489,6 +493,7 @@ void cSocketThreads::cSocketThread::ReadFromSockets(fd_set * a_Read) // Notify the callback that the remote has closed the socket; keep the slot m_Slots[i].m_Client->SocketClosed(); m_Slots[i].m_State = sSlot::ssRemoteClosed; + m_Slots[i].m_Socket.CloseSocket(); break; } case sSlot::ssWritingRestOut: -- cgit v1.2.3 From fad90081d2c039a2c34badf16ba48e0ae80bc014 Mon Sep 17 00:00:00 2001 From: Tiger Wang Date: Mon, 3 Feb 2014 22:25:16 +0000 Subject: Fixed #491 --- src/OSSupport/File.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index 0ebd04915..17070030f 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -73,14 +73,26 @@ bool cFile::Open(const AString & iFileName, eMode iMode) return false; } } - m_File = fopen( (FILE_IO_PREFIX + iFileName).c_str(), Mode); + +#ifdef _WIN32 + fopen_s(&m_File, (FILE_IO_PREFIX + iFileName).c_str(), Mode); +#else + m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), Mode); +#endif // _WIN32 + if ((m_File == NULL) && (iMode == fmReadWrite)) { // Fix for MS not following C spec, opening "a" mode files for writing at the end only // The file open operation has been tried with "read update", fails if file not found // So now we know either the file doesn't exist or we don't have rights, no need to worry about file contents. // Simply re-open for read-writing, erasing existing contents: - m_File = fopen( (FILE_IO_PREFIX + iFileName).c_str(), "wb+"); + +#ifdef _WIN32 + fopen_s(&m_File, (FILE_IO_PREFIX + iFileName).c_str(), "wb+"); +#else + m_File = fopen((FILE_IO_PREFIX + iFileName).c_str(), "wb+"); +#endif // _WIN32 + } return (m_File != NULL); } -- cgit v1.2.3 From 462e0bcf46ce8e7c29e9f00ace58c2fcebffb8d1 Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 23 Feb 2014 12:23:35 -0800 Subject: fixed globals.h warnings --- src/OSSupport/Queue.h | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/Queue.h b/src/OSSupport/Queue.h index 6c3d58295..beb6a63f1 100644 --- a/src/OSSupport/Queue.h +++ b/src/OSSupport/Queue.h @@ -29,7 +29,11 @@ public: static void Delete(T) {}; /// Called when an Item is inserted with EnqueueItemIfNotPresent and there is another equal value already inserted - static void Combine(T & a_existing, const T & a_new) {}; + static void Combine(T & a_existing, const T & a_new) + { + UNUSED(a_existing); + UNUSED(a_new); + }; }; -- cgit v1.2.3 From 182646188448f9fd8df0b4c0391a2db04575c49d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Feb 2014 16:26:23 +0100 Subject: Fixed multiple gcc warnings about unused params. --- src/OSSupport/BlockingTCPLink.cpp | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/OSSupport') diff --git a/src/OSSupport/BlockingTCPLink.cpp b/src/OSSupport/BlockingTCPLink.cpp index af50eda5d..e9c00d6d4 100644 --- a/src/OSSupport/BlockingTCPLink.cpp +++ b/src/OSSupport/BlockingTCPLink.cpp @@ -89,6 +89,8 @@ bool cBlockingTCPLink::Connect(const char * iAddress, unsigned int iPort) int cBlockingTCPLink::Send(char * a_Data, unsigned int a_Size, int a_Flags /* = 0 */ ) { + UNUSED(a_Flags); + ASSERT(m_Socket.IsValid()); if (!m_Socket.IsValid()) { @@ -104,6 +106,8 @@ int cBlockingTCPLink::Send(char * a_Data, unsigned int a_Size, int a_Flags /* = int cBlockingTCPLink::SendMessage( const char* a_Message, int a_Flags /* = 0 */ ) { + UNUSED(a_Flags); + ASSERT(m_Socket.IsValid()); if (!m_Socket.IsValid()) { -- cgit v1.2.3 From b480148116ea7099c9a6afda83f74a3d45815a83 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 7 Mar 2014 10:26:07 -0800 Subject: Fixed warnings --- src/OSSupport/SocketThreads.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/SocketThreads.h b/src/OSSupport/SocketThreads.h index fcd2ce11f..b2eb5950f 100644 --- a/src/OSSupport/SocketThreads.h +++ b/src/OSSupport/SocketThreads.h @@ -103,7 +103,7 @@ private: public: cSocketThread(cSocketThreads * a_Parent); - ~cSocketThread(); + virtual ~cSocketThread(); // All these methods assume parent's m_CS is locked bool HasEmptySlot(void) const {return m_NumSlots < MAX_SLOTS; } -- cgit v1.2.3 From e5fc3c63f2ab4bcc8d225f746afd07d01ad9d08c Mon Sep 17 00:00:00 2001 From: Tycho Date: Sun, 9 Mar 2014 10:52:12 -0700 Subject: Fix IsThread destructor --- src/OSSupport/IsThread.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/IsThread.h b/src/OSSupport/IsThread.h index b8784ea33..42b8bfdda 100644 --- a/src/OSSupport/IsThread.h +++ b/src/OSSupport/IsThread.h @@ -34,7 +34,7 @@ protected: public: cIsThread(const AString & iThreadName); - ~cIsThread(); + virtual ~cIsThread(); /// Starts the thread; returns without waiting for the actual start bool Start(void); -- cgit v1.2.3 From 8665233522da3454a77c4c40ace03d3a61150023 Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 10:32:51 -0700 Subject: Fixed cast between types of different alignment in cSocket --- src/OSSupport/Socket.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/Socket.cpp b/src/OSSupport/Socket.cpp index 6afaceedf..c29e495c3 100644 --- a/src/OSSupport/Socket.cpp +++ b/src/OSSupport/Socket.cpp @@ -307,7 +307,8 @@ bool cSocket::ConnectIPv4(const AString & a_HostNameOrAddr, unsigned short a_Por CloseSocket(); return false; } - addr = *((unsigned long*)hp->h_addr); + // Should be optimised to a single word copy + memcpy(&addr, hp->h_addr, hp->h_length); } sockaddr_in server; -- cgit v1.2.3 From e2e7f2184f09562753be1a474c2d7e8273b1e83b Mon Sep 17 00:00:00 2001 From: Tycho Date: Mon, 10 Mar 2014 10:38:21 -0700 Subject: Fixed cast to type with different alignment in BlockingTCPLink --- src/OSSupport/BlockingTCPLink.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/BlockingTCPLink.cpp b/src/OSSupport/BlockingTCPLink.cpp index e9c00d6d4..07f48b955 100644 --- a/src/OSSupport/BlockingTCPLink.cpp +++ b/src/OSSupport/BlockingTCPLink.cpp @@ -70,7 +70,7 @@ bool cBlockingTCPLink::Connect(const char * iAddress, unsigned int iPort) } } - server.sin_addr.s_addr = *((unsigned long *)hp->h_addr); + memcpy(&server.sin_addr.s_addr,hp->h_addr, hp->h_length); server.sin_family = AF_INET; server.sin_port = htons( (unsigned short)iPort); if (connect(m_Socket, (struct sockaddr *)&server, sizeof(server))) -- cgit v1.2.3 From 53faac10c50ba88ce540e0464123f388bd7db069 Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 11 Mar 2014 13:41:15 -0700 Subject: Added macros to follow format string checking through wrappers --- src/OSSupport/File.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/File.h b/src/OSSupport/File.h index 07fce6661..e229035b7 100644 --- a/src/OSSupport/File.h +++ b/src/OSSupport/File.h @@ -131,7 +131,7 @@ public: /** Returns the list of all items in the specified folder (files, folders, nix pipes, whatever's there). */ static AStringVector GetFolderContents(const AString & a_Folder); // Exported in ManualBindings.cpp - int Printf(const char * a_Fmt, ...); + int Printf(const char * a_Fmt, ...) FORMATSTRING(2,3); /** Flushes all the bufferef output into the file (only when writing) */ void Flush(void); -- cgit v1.2.3 From 16b27c4b7ae2ccb03355148fa7fc7116190cc5fb Mon Sep 17 00:00:00 2001 From: Tycho Date: Tue, 11 Mar 2014 14:16:08 -0700 Subject: Fixed a load of format string errors --- src/OSSupport/SocketThreads.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/SocketThreads.cpp b/src/OSSupport/SocketThreads.cpp index a02661d2c..f37b00202 100644 --- a/src/OSSupport/SocketThreads.cpp +++ b/src/OSSupport/SocketThreads.cpp @@ -54,7 +54,7 @@ bool cSocketThreads::AddClient(const cSocket & a_Socket, cCallback * a_Client) } // No thread has free space, create a new one: - LOGD("Creating a new cSocketThread (currently have %d)", m_Threads.size()); + LOGD("Creating a new cSocketThread (currently have %zu)", m_Threads.size()); cSocketThread * Thread = new cSocketThread(this); if (!Thread->Start()) { -- cgit v1.2.3 From 862e2194433b5d47aaf88261091b35a1ee663482 Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 12 Mar 2014 10:34:50 -0700 Subject: Added additional macros to support the MSVC size_t format and changed all formats to use the macros --- src/OSSupport/SocketThreads.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/SocketThreads.cpp b/src/OSSupport/SocketThreads.cpp index f37b00202..0bc1d6b55 100644 --- a/src/OSSupport/SocketThreads.cpp +++ b/src/OSSupport/SocketThreads.cpp @@ -54,7 +54,7 @@ bool cSocketThreads::AddClient(const cSocket & a_Socket, cCallback * a_Client) } // No thread has free space, create a new one: - LOGD("Creating a new cSocketThread (currently have %zu)", m_Threads.size()); + LOGD("Creating a new cSocketThread (currently have " SIZE_T_FMT ")", m_Threads.size()); cSocketThread * Thread = new cSocketThread(this); if (!Thread->Start()) { -- cgit v1.2.3 From cd6ab5617cd7b26b13cfe26a950ca17fecefd550 Mon Sep 17 00:00:00 2001 From: Tycho Date: Fri, 14 Mar 2014 06:11:49 -0700 Subject: Fixed xofts issues --- src/OSSupport/File.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/File.h b/src/OSSupport/File.h index e229035b7..b394c5cb9 100644 --- a/src/OSSupport/File.h +++ b/src/OSSupport/File.h @@ -131,7 +131,7 @@ public: /** Returns the list of all items in the specified folder (files, folders, nix pipes, whatever's there). */ static AStringVector GetFolderContents(const AString & a_Folder); // Exported in ManualBindings.cpp - int Printf(const char * a_Fmt, ...) FORMATSTRING(2,3); + int Printf(const char * a_Fmt, ...) FORMATSTRING(2, 3); /** Flushes all the bufferef output into the file (only when writing) */ void Flush(void); -- cgit v1.2.3 From 4dc5650023c234a9e82c97c795d8c39016063c51 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 18 Mar 2014 13:54:17 +0100 Subject: Fixed cGZipFile::ReadRestOfFile returning incorrect value. --- src/OSSupport/GZipFile.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/GZipFile.cpp b/src/OSSupport/GZipFile.cpp index cbf6be6c4..b13e519e0 100644 --- a/src/OSSupport/GZipFile.cpp +++ b/src/OSSupport/GZipFile.cpp @@ -73,12 +73,15 @@ int cGZipFile::ReadRestOfFile(AString & a_Contents) // Since the gzip format doesn't really support getting the uncompressed length, we need to read incrementally. Yuck! int NumBytesRead = 0; + int TotalBytes = 0; char Buffer[64 KiB]; while ((NumBytesRead = gzread(m_File, Buffer, sizeof(Buffer))) > 0) { + TotalBytes += NumBytesRead; a_Contents.append(Buffer, NumBytesRead); } - return NumBytesRead; + // NumBytesRead is < 0 on error + return (NumBytesRead >= 0) ? TotalBytes : NumBytesRead; } -- cgit v1.2.3 From d77a6417f62990f5c986e03a7e226c03b5a74fb8 Mon Sep 17 00:00:00 2001 From: Samuel Barney Date: Tue, 25 Mar 2014 10:33:52 -0600 Subject: Added newlines. Without them, the files would not compile. --- src/OSSupport/Sleep.h | 2 +- src/OSSupport/Thread.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/Sleep.h b/src/OSSupport/Sleep.h index 5298c15da..0ec0adf9d 100644 --- a/src/OSSupport/Sleep.h +++ b/src/OSSupport/Sleep.h @@ -4,4 +4,4 @@ class cSleep { public: static void MilliSleep( unsigned int a_MilliSeconds ); -}; \ No newline at end of file +}; diff --git a/src/OSSupport/Thread.h b/src/OSSupport/Thread.h index 3c9316424..4153b2427 100644 --- a/src/OSSupport/Thread.h +++ b/src/OSSupport/Thread.h @@ -23,4 +23,4 @@ private: cEvent* m_StopEvent; AString m_ThreadName; -}; \ No newline at end of file +}; -- cgit v1.2.3 From eb3cc729d4e367c54a47369f712831908f8da22c Mon Sep 17 00:00:00 2001 From: Samuel Barney Date: Tue, 25 Mar 2014 11:15:05 -0600 Subject: More fixes to get it to compile for me on Mac 10.9. Mostly just newline additions, but some of the unused variables were causing errors, so I wrapped them in #ifndef __APPLE__ calls, since I didn't know if they were going to be used in the future. Also had to undefine TOLUA_TEMPLATE_BIND a couple of times. --- src/OSSupport/Errors.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/Errors.cpp b/src/OSSupport/Errors.cpp index 2e05f1df1..6072b6ac6 100644 --- a/src/OSSupport/Errors.cpp +++ b/src/OSSupport/Errors.cpp @@ -22,7 +22,7 @@ AString GetOSErrorString( int a_ErrNo ) // According to http://linux.die.net/man/3/strerror_r there are two versions of strerror_r(): - #if ( _GNU_SOURCE ) && !defined(ANDROID_NDK) // GNU version of strerror_r() + #if !defined(__APPLE__) && ( _GNU_SOURCE ) && !defined(ANDROID_NDK) // GNU version of strerror_r() char * res = strerror_r( errno, buffer, ARRAYCOUNT(buffer) ); if( res != NULL ) -- cgit v1.2.3 From 773ce7fde692e86531e1e92f42776e316b793d83 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Fri, 28 Mar 2014 21:35:45 +0100 Subject: Fixed non-virtual destructors warnings. --- src/OSSupport/ListenThread.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/ListenThread.h b/src/OSSupport/ListenThread.h index 4e337d814..b2d806c82 100644 --- a/src/OSSupport/ListenThread.h +++ b/src/OSSupport/ListenThread.h @@ -29,43 +29,45 @@ class cListenThread : typedef cIsThread super; public: - /// Used as the callback for connection events + /** Used as the callback for connection events */ class cCallback { public: - /// This callback is called whenever a socket connection is accepted + virtual ~cCallback() {} + + /** This callback is called whenever a socket connection is accepted */ virtual void OnConnectionAccepted(cSocket & a_Socket) = 0; } ; cListenThread(cCallback & a_Callback, cSocket::eFamily a_Family, const AString & a_ServiceName = ""); ~cListenThread(); - /// Creates all the sockets, returns trus if successful, false if not. + /** Creates all the sockets, returns trus if successful, false if not. */ bool Initialize(const AString & a_PortsString); bool Start(void); void Stop(void); - /// Call before Initialize() to set the "reuse" flag on the sockets + /** Call before Initialize() to set the "reuse" flag on the sockets */ void SetReuseAddr(bool a_Reuse = true); protected: typedef std::vector cSockets; - /// The callback which to notify of incoming connections + /** The callback which to notify of incoming connections */ cCallback & m_Callback; - /// Socket address family to use + /** Socket address family to use */ cSocket::eFamily m_Family; - /// Sockets that are being monitored + /** Sockets that are being monitored */ cSockets m_Sockets; - /// If set to true, the SO_REUSEADDR socket option is set to true + /** If set to true, the SO_REUSEADDR socket option is set to true */ bool m_ShouldReuseAddr; - /// Name of the service that's listening on the ports; for logging purposes only + /** Name of the service that's listening on the ports; for logging purposes only */ AString m_ServiceName; -- cgit v1.2.3 From 45150e97541aa8dfda7f0fdba75acf2ec616654d Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 14:58:05 +0200 Subject: Fixed clang warnings in cFile. We only support 32-bit filesizes (files < 2 GiB). --- src/OSSupport/File.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index 17070030f..75ea198a8 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -152,7 +152,7 @@ int cFile::Read (void * iBuffer, int iNumBytes) return -1; } - return fread(iBuffer, 1, iNumBytes, m_File); // fread() returns the portion of Count parameter actually read, so we need to send iNumBytes as Count + return (int)fread(iBuffer, 1, (size_t)iNumBytes, m_File); // fread() returns the portion of Count parameter actually read, so we need to send iNumBytes as Count } @@ -168,7 +168,7 @@ int cFile::Write(const void * iBuffer, int iNumBytes) return -1; } - int res = fwrite(iBuffer, 1, iNumBytes, m_File); // fwrite() returns the portion of Count parameter actually written, so we need to send iNumBytes as Count + int res = (int)fwrite(iBuffer, 1, (size_t)iNumBytes, m_File); // fwrite() returns the portion of Count parameter actually written, so we need to send iNumBytes as Count return res; } @@ -189,7 +189,7 @@ int cFile::Seek (int iPosition) { return -1; } - return ftell(m_File); + return (int)ftell(m_File); } @@ -206,7 +206,7 @@ int cFile::Tell (void) const return -1; } - return ftell(m_File); + return (int)ftell(m_File); } @@ -222,7 +222,7 @@ int cFile::GetSize(void) const return -1; } - int CurPos = ftell(m_File); + int CurPos = Tell(); if (CurPos < 0) { return -1; @@ -231,8 +231,8 @@ int cFile::GetSize(void) const { return -1; } - int res = ftell(m_File); - if (fseek(m_File, CurPos, SEEK_SET) != 0) + int res = Tell(); + if (fseek(m_File, (size_t)CurPos, SEEK_SET) != 0) { return -1; } @@ -255,7 +255,7 @@ int cFile::ReadRestOfFile(AString & a_Contents) int DataSize = GetSize() - Tell(); // HACK: This depends on the internal knowledge that AString's data() function returns the internal buffer directly - a_Contents.assign(DataSize, '\0'); + a_Contents.assign((size_t)DataSize, '\0'); return Read((void *)a_Contents.data(), DataSize); } @@ -350,7 +350,7 @@ int cFile::GetSize(const AString & a_FileName) struct stat st; if (stat(a_FileName.c_str(), &st) == 0) { - return st.st_size; + return (int)st.st_size; } return -1; } @@ -456,7 +456,7 @@ int cFile::Printf(const char * a_Fmt, ...) va_start(args, a_Fmt); AppendVPrintf(buf, a_Fmt, args); va_end(args); - return Write(buf.c_str(), buf.length()); + return Write(buf.c_str(), (int)buf.length()); } -- cgit v1.2.3 From b9a090d835c9434570166b7cddcb8b6d7e2628e4 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 15:00:30 +0200 Subject: Fixed clang warnings in cGZipFile. --- src/OSSupport/GZipFile.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/GZipFile.cpp b/src/OSSupport/GZipFile.cpp index b13e519e0..7a8433f4f 100644 --- a/src/OSSupport/GZipFile.cpp +++ b/src/OSSupport/GZipFile.cpp @@ -78,7 +78,7 @@ int cGZipFile::ReadRestOfFile(AString & a_Contents) while ((NumBytesRead = gzread(m_File, Buffer, sizeof(Buffer))) > 0) { TotalBytes += NumBytesRead; - a_Contents.append(Buffer, NumBytesRead); + a_Contents.append(Buffer, (size_t)NumBytesRead); } // NumBytesRead is < 0 on error return (NumBytesRead >= 0) ? TotalBytes : NumBytesRead; @@ -102,7 +102,7 @@ bool cGZipFile::Write(const char * a_Contents, int a_Size) return false; } - return (gzwrite(m_File, a_Contents, a_Size) != 0); + return (gzwrite(m_File, a_Contents, (unsigned int)a_Size) != 0); } -- cgit v1.2.3 From 2672b14c036f74548f970349aa08b6cb02600688 Mon Sep 17 00:00:00 2001 From: madmaxoft Date: Tue, 1 Apr 2014 16:00:20 +0200 Subject: More cFile warning fixes. --- src/OSSupport/File.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/File.cpp b/src/OSSupport/File.cpp index 75ea198a8..7f0f0ad2f 100644 --- a/src/OSSupport/File.cpp +++ b/src/OSSupport/File.cpp @@ -232,7 +232,7 @@ int cFile::GetSize(void) const return -1; } int res = Tell(); - if (fseek(m_File, (size_t)CurPos, SEEK_SET) != 0) + if (fseek(m_File, (long)CurPos, SEEK_SET) != 0) { return -1; } -- cgit v1.2.3 From 1f5a4a39f2cd9f63a7e5695689042d3c43b2e83b Mon Sep 17 00:00:00 2001 From: Tycho Date: Wed, 2 Apr 2014 06:36:25 -0700 Subject: Fixed All signedness warnings in HTTPServer.cpp --- src/OSSupport/SocketThreads.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/OSSupport') diff --git a/src/OSSupport/SocketThreads.h b/src/OSSupport/SocketThreads.h index b2eb5950f..679e374e1 100644 --- a/src/OSSupport/SocketThreads.h +++ b/src/OSSupport/SocketThreads.h @@ -64,7 +64,7 @@ public: virtual ~cCallback() {} /** Called when data is received from the remote party */ - virtual void DataReceived(const char * a_Data, int a_Size) = 0; + virtual void DataReceived(const char * a_Data, size_t a_Size) = 0; /** Called when data can be sent to remote party The function is supposed to *set* outgoing data to a_Data (overwrite) */ -- cgit v1.2.3