@ -23,6 +23,7 @@
# include <sys/socket.h>
# include <sys/stat.h>
# include <sys/types.h>
# include <sys/un.h>
# include <unistd.h>
# include <cstdlib>
# include <cstring>
@ -30,45 +31,66 @@
# include <errno.h>
# include <sstream>
SocketManager : : SocketManager ( )
{
const char * runtimeDir = getenv ( " XDG_RUNTIME_DIR " ) ;
if ( ! runtimeDir | | ! * runtimeDir )
runtimeDir = " /tmp/ " ;
m_socketRootPath = runtimeDir ;
m_socketRootPath + = " /mapplauncherd " ;
if ( mkdir ( m_socketRootPath . c_str ( ) , S_IRUSR | S_IWUSR | S_IXUSR ) ! = 0 ) {
if ( errno ! = EEXIST ) {
Logger : : logError ( " Daemon: Cannot create socket root directory %s: %s \n " ,
m_socketRootPath . c_str ( ) , strerror ( errno ) ) ;
}
}
m_socketRootPath + = ' / ' ;
}
void SocketManager : : initSocket ( const string & socketId )
{
string socketPath = m_socketRootPath + socketId ;
// Initialize a socket at socketId if one already doesn't
// exist for that id / path.
if ( m_socketHash . find ( socketId ) = = m_socketHash . end ( ) )
{
Logger : : logDebug ( " SocketManager: Initing socket at '%s'.. " , socketId . c_str ( ) ) ;
Logger : : logDebug ( " SocketManager: Initing socket at '%s'.. " , socket Path . c_str ( ) ) ;
// Create a new local socket
int socketFd = socket ( PF_UNIX , SOCK_STREAM , 0 ) ;
if ( socketFd < 0 )
throw std : : runtime_error ( " SocketManager: Failed to open socket \n " ) ;
// TODO: Error if socketId >= maxLen. Also unlink() here may
// TODO: Error if socket Path >= maxLen. Also unlink() here may
// try to remove a different file than is passed to sun.sa_data.
// Remove the previous socket file
struct stat sb ;
stat ( socketId . c_str ( ) , & sb ) ;
stat ( socket Path . c_str ( ) , & sb ) ;
if ( S_ISSOCK ( sb . st_mode ) )
{
// coverity[toctou]
if ( unlink ( socket Id . c_str ( ) ) = = - 1 )
if ( unlink ( socket Path . c_str ( ) ) = = - 1 )
{
std : : string msg ( " SocketManager: Failed to unlink existing socket file ' " ) ;
msg + = socket Id + " ': " + strerror ( errno ) ;
msg + = socket Path + " ': " + strerror ( errno ) ;
Logger : : logWarning ( msg . c_str ( ) ) ;
}
}
// Initialize the socket struct
struct sockaddr sun ;
sun . s a _family = AF_UNIX ;
int maxLen = sizeof ( sun . s a_data ) - 1 ;
strncpy ( sun . s a_data, socketId . c_str ( ) , maxLen ) ;
sun . s a_data [ maxLen ] = ' \0 ' ;
struct sockaddr _un sun ;
sun . s un _family = AF_UNIX ;
int maxLen = sizeof ( sun . s un_path ) - 1 ;
strncpy ( sun . s un_path, socketPath . c_str ( ) , maxLen ) ;
sun . s un_path [ maxLen ] = ' \0 ' ;
// Bind the socket
if ( bind ( socketFd , & sun , sizeof ( sun ) ) < 0 )
if ( bind ( socketFd , ( struct sockaddr * ) & sun , sizeof ( sun ) ) < 0 )
{
std : : string msg ( " SocketManager: Failed to bind to socket (fd= " ) ;
std : : stringstream ss ;
@ -88,9 +110,7 @@ void SocketManager::initSocket(const string & socketId)
}
// Set permissions
chmod ( socketId . c_str ( ) , S_IRUSR | S_IWUSR | S_IXUSR |
S_IRGRP | S_IWGRP | S_IXGRP |
S_IROTH | S_IWOTH | S_IXOTH ) ;
chmod ( socketPath . c_str ( ) , S_IRUSR | S_IWUSR | S_IXUSR ) ;
// Store path <-> file descriptor mapping
m_socketHash [ socketId ] = socketFd ;
@ -142,3 +162,9 @@ void SocketManager::addMapping(const string & socketId, int fd)
{
m_socketHash [ socketId ] = fd ;
}
string SocketManager : : socketRootPath ( ) const
{
return m_socketRootPath ;
}