The Samba-Bugzilla – Attachment 3122 Details for
Bug 5232
getpwent_r, getpwuid_r, getpwnam_r and getgrgid_r not reentrant.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
Pass a path to the program and it will try to get the owner of each file from multiple threads
nssTest.cpp (text/plain), 4.47 KB, created by
Dominique Leroux (mail bounces back)
on 2008-01-29 11:55:02 UTC
(
hide
)
Description:
Pass a path to the program and it will try to get the owner of each file from multiple threads
Filename:
MIME Type:
Creator:
Dominique Leroux (mail bounces back)
Created:
2008-01-29 11:55:02 UTC
Size:
4.47 KB
patch
obsolete
>//============================================================================== >// NSS thread-safety test program >//============================================================================== > >// compile with: >// g++ -o nssTest nssTest.cpp -lpthread > >#include <vector> >#include <iostream> >#include <cerrno> > >#include <dirent.h> >#include <pthread.h> >#include <unistd.h> >#include <sys/types.h> >#include <sys/stat.h> >#include <pwd.h> > >namespace { > >//============================================================================== >// LOCAL DECLARATIONS >//============================================================================== > >/*----- variables -----*/ > >int pwSize = 0; > >typedef std::vector< std::string > StrVec; >typedef std::vector< uid_t > UidVec; >UidVec userIds; >StrVec userNames; >bool threadUnsafe; >pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; > >//============================================================================== >// LOCAL FUNCTIONS >//============================================================================== > >//------------------------------------------------------------------------------ >// >std::string getUserName( const uid_t userId ) >{ > char* pwBuf = new char[ pwSize ]; > struct passwd pwd; > struct passwd* pwdr = 0; > int ret; > > do { > if ( threadUnsafe ) { > pthread_mutex_lock( &mutex ); > } > ret = getpwuid_r( userId , &pwd, pwBuf, pwSize, &pwdr ); > if ( threadUnsafe ) { > pthread_mutex_unlock( &mutex ); > } > } while ( ret == -1 && errno == EINTR ); > if ( ret == -1 ) { > return std::string( "--->Error while retrieving<---" ); > } > if ( pwdr == 0 ) { > return std::string( "--->Error in returned value<---" ); > } > const std::string name( pwd.pw_name ); > delete [] pwBuf; > return name; >} > >//------------------------------------------------------------------------------ >// >void* accessOwners( void* param ) >{ > // Perform a few accesses to make sure there is some concurrent access to > // getpwuid_r. > for ( int i = 0; i < 50; ++i ) { > const int idx = rand() % userIds.size(); > getUserName( userIds[ i ] ); > } > > const int idx = reinterpret_cast< int >( param ); > userNames[ idx ] = getUserName( userIds[ idx ] ); > return 0; >} > >} > >//============================================================================== >// GLOBAL FUNCTIONS >//============================================================================== > >//------------------------------------------------------------------------------ >// >int main( int argc, char* argv[] ) >{ > if ( argc < 2 ) { > std::cerr << "Missing path." << std::endl; > } > > std::string dirStr( argv[ 1 ] ); > if ( argc > 2 ) { > const std::string serializeAccessArg( "-s" ); > if ( argv[ 1 ] == serializeAccessArg ) { > threadUnsafe = true; > dirStr = argv[ 2 ]; > std::cerr << "Serializing calls to getpwuid_r." << std::endl; > } > } > > pwSize = sysconf( _SC_GETPW_R_SIZE_MAX ); > if ( pwSize < 0 ) { > std::cerr << "_SC_GETPW_R_SIZE_MAX returns " << pwSize; > pwSize = 4096; > std::cerr << ". Adjusted to " << pwSize << "." << std::endl; > } > > DIR* dirStream = opendir( dirStr.c_str() ); > if ( dirStream == NULL ) { > std::cerr << dirStr << " is not a directory." << std::endl; > return -1; > } > > if ( dirStr[ dirStr.size() - 1 ] != '/' ) { > dirStr += "/"; > } > > StrVec fileNames; > while ( true ) { > struct dirent* dirEnt = readdir( dirStream ); > if ( dirEnt == NULL ) { > break; > } > const std::string fileName( dirStr + std::string( dirEnt->d_name ) ); > fileNames.push_back( fileName ); > > struct stat statStr; > stat( fileName.c_str(), &statStr ); > userIds.push_back( statStr.st_uid ); > > if ( userIds.size() > PTHREAD_THREADS_MAX ) { > // Avoid doing work for too many files: we start one thread per file > // and we don't want to go beyond the prheads limit. > break; > } > } > > std::vector< pthread_t > threadIds( fileNames.size() ); > userNames.resize( fileNames.size() ); > for ( int i = 0; i < fileNames.size(); ++i ) { > ::pthread_create( &threadIds[ i ], NULL, accessOwners, > reinterpret_cast< void* >( i ) ); > } > > for ( int i = 0; i < fileNames.size(); ++i ) { > ::pthread_join( threadIds[ i ], NULL ); > } > > for ( int i = 0; i < fileNames.size(); ++i ) { > std::cout << fileNames[ i ] << ": " << userNames[ i ] << std::endl; > } > > return 0; >}
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 5232
: 3122