📄 operations.cpp
字号:
struct stat path_stat; if ( (::stat( ph.c_str(), &path_stat )) != 0 ) return std::make_pair( error_code( errno, system_category ), false ); return std::make_pair( ok, S_ISDIR( path_stat.st_mode ) ? is_empty_directory( ph ) : path_stat.st_size == 0 ); } BOOST_FILESYSTEM_DECL query_pair equivalent_api( const std::string & ph1, const std::string & ph2 ) { struct stat s2; int e2( ::stat( ph2.c_str(), &s2 ) ); struct stat s1; int e1( ::stat( ph1.c_str(), &s1 ) ); if ( e1 != 0 || e2 != 0 ) return std::make_pair( error_code( e1 != 0 && e2 != 0 ? errno : 0, system_category ), false ); // at this point, both stats are known to be valid return std::make_pair( ok, s1.st_dev == s2.st_dev && s1.st_ino == s2.st_ino // According to the POSIX stat specs, "The st_ino and st_dev fields // taken together uniquely identify the file within the system." // Just to be sure, size and mod time are also checked. && s1.st_size == s2.st_size && s1.st_mtime == s2.st_mtime ); } BOOST_FILESYSTEM_DECL uintmax_pair file_size_api( const std::string & ph ) { struct stat path_stat; if ( ::stat( ph.c_str(), &path_stat ) != 0 ) return std::make_pair( error_code( errno, system_category ), 0 ); if ( !S_ISREG( path_stat.st_mode ) ) return std::make_pair( error_code( EPERM, system_category ), 0 ); return std::make_pair( ok, static_cast<boost::uintmax_t>(path_stat.st_size) ); } BOOST_FILESYSTEM_DECL space_pair space_api( const std::string & ph ) { struct BOOST_STATVFS vfs; space_pair result; if ( ::BOOST_STATVFS( ph.c_str(), &vfs ) != 0 ) { result.first = error_code( errno, system_category ); result.second.capacity = result.second.free = result.second.available = 0; } else { result.first = ok; result.second.capacity = static_cast<boost::uintmax_t>(vfs.f_blocks) * BOOST_STATVFS_F_FRSIZE; result.second.free = static_cast<boost::uintmax_t>(vfs.f_bfree) * BOOST_STATVFS_F_FRSIZE; result.second.available = static_cast<boost::uintmax_t>(vfs.f_bavail) * BOOST_STATVFS_F_FRSIZE; } return result; } BOOST_FILESYSTEM_DECL time_pair last_write_time_api( const std::string & ph ) { struct stat path_stat; if ( ::stat( ph.c_str(), &path_stat ) != 0 ) return std::make_pair( error_code( errno, system_category ), 0 ); return std::make_pair( ok, path_stat.st_mtime ); } BOOST_FILESYSTEM_DECL error_code last_write_time_api( const std::string & ph, std::time_t new_value ) { struct stat path_stat; if ( ::stat( ph.c_str(), &path_stat ) != 0 ) return error_code( errno, system_category ); ::utimbuf buf; buf.actime = path_stat.st_atime; // utime() updates access time too:-( buf.modtime = new_value; return error_code( ::utime( ph.c_str(), &buf ) != 0 ? errno : 0, system_category ); } BOOST_FILESYSTEM_DECL error_code get_current_path_api( std::string & ph ) { for ( long path_max = 32;; path_max *=2 ) // loop 'til buffer large enough { boost::scoped_array<char> buf( new char[static_cast<std::size_t>(path_max)] ); if ( ::getcwd( buf.get(), static_cast<std::size_t>(path_max) ) == 0 ) { if ( errno != ERANGE // bug in some versions of the Metrowerks C lib on the Mac: wrong errno set # if defined(__MSL__) && (defined(macintosh) || defined(__APPLE__) || defined(__APPLE_CC__)) && errno != 0# endif ) return error_code( errno, system_category ); } else { ph = buf.get(); break; } } return ok; } BOOST_FILESYSTEM_DECL error_code set_current_path_api( const std::string & ph ) { return error_code( ::chdir( ph.c_str() ) ? errno : 0, system_category ); } BOOST_FILESYSTEM_DECL fs::detail::query_pair create_directory_api( const std::string & ph ) { if ( ::mkdir( ph.c_str(), S_IRWXU|S_IRWXG|S_IRWXO ) == 0 ) { return std::make_pair( ok, true ); } int ec=errno; error_code dummy; if ( ec != EEXIST || !fs::is_directory( status_api( ph, dummy ) ) ) { return std::make_pair( error_code( ec, system_category ), false ); } return std::make_pair( ok, false ); } BOOST_FILESYSTEM_DECL error_code create_hard_link_api( const std::string & to_ph, const std::string & from_ph ) { return error_code( ::link( to_ph.c_str(), from_ph.c_str() ) == 0 ? 0 : errno, system_category ); } BOOST_FILESYSTEM_DECL error_code create_symlink_api( const std::string & to_ph, const std::string & from_ph ) { return error_code( ::symlink( to_ph.c_str(), from_ph.c_str() ) == 0 ? 0 : errno, system_category ); } BOOST_FILESYSTEM_DECL error_code remove_api( const std::string & ph ) { if ( posix_remove( ph.c_str() ) == 0 ) return ok; int error = errno; // POSIX says "If the directory is not an empty directory, rmdir() // shall fail and set errno to EEXIST or ENOTEMPTY." // Linux uses ENOTEMPTY, Solaris uses EEXIST. if ( error == EEXIST ) error = ENOTEMPTY; error_code ec; // ignore errors if post-condition satisfied return status_api(ph, ec).type() == file_not_found ? ok : error_code( error, system_category ) ; } BOOST_FILESYSTEM_DECL error_code rename_api( const std::string & from, const std::string & to ) { // POSIX is too permissive so must check error_code dummy; if ( fs::exists( status_api( to, dummy ) ) ) return error_code( EEXIST, system_category ); return error_code( std::rename( from.c_str(), to.c_str() ) != 0 ? errno : 0, system_category ); } BOOST_FILESYSTEM_DECL error_code copy_file_api( const std::string & from_file_ph, const std::string & to_file_ph ) { const std::size_t buf_sz = 32768; boost::scoped_array<char> buf( new char [buf_sz] ); int infile=0, outfile=0; // init quiets compiler warning struct stat from_stat; if ( ::stat( from_file_ph.c_str(), &from_stat ) != 0 || (infile = ::open( from_file_ph.c_str(), O_RDONLY )) < 0 || (outfile = ::open( to_file_ph.c_str(), O_WRONLY | O_CREAT | O_EXCL, from_stat.st_mode )) < 0 ) { if ( infile >= 0 ) ::close( infile ); return error_code( errno, system_category ); } ssize_t sz, sz_read=1, sz_write; while ( sz_read > 0 && (sz_read = ::read( infile, buf.get(), buf_sz )) > 0 ) { // Allow for partial writes - see Advanced Unix Programming (2nd Ed.), // Marc Rochkind, Addison-Wesley, 2004, page 94 sz_write = 0; do { if ( (sz = ::write( outfile, buf.get() + sz_write, sz_read - sz_write )) < 0 ) { sz_read = sz; // cause read loop termination break; // and error to be thrown after closes } sz_write += sz; } while ( sz_write < sz_read ); } if ( ::close( infile) < 0 ) sz_read = -1; if ( ::close( outfile) < 0 ) sz_read = -1; return error_code( sz_read < 0 ? errno : 0, system_category ); } // this code is based on Stevens and Rago, Advanced Programming in the // UNIX envirnment, 2nd Ed., ISBN 0-201-43307-9, page 49 error_code path_max( std::size_t & result ) {# ifdef PATH_MAX static std::size_t max = PATH_MAX;# else static std::size_t max = 0;# endif if ( max == 0 ) { errno = 0; long tmp = ::pathconf( "/", _PC_NAME_MAX ); if ( tmp < 0 ) { if ( errno == 0 ) // indeterminate max = 4096; // guess else return error_code( errno, system_category ); } else max = static_cast<std::size_t>( tmp + 1 ); // relative root } result = max; return ok; } BOOST_FILESYSTEM_DECL error_code dir_itr_first( void *& handle, void *& buffer, const std::string & dir, std::string & target, file_status &, file_status & ) { if ( (handle = ::opendir( dir.c_str() )) == 0 ) return error_code( errno, system_category ); target = std::string( "." ); // string was static but caused trouble // when iteration called from dtor, after // static had already been destroyed std::size_t path_size; error_code ec = path_max( path_size ); if ( ec ) return ec; dirent de; buffer = std::malloc( (sizeof(dirent) - sizeof(de.d_name)) + path_size + 1 ); // + 1 for "/0" return ok; } BOOST_FILESYSTEM_DECL error_code dir_itr_close( void *& handle, void*& buffer ) { std::free( buffer ); buffer = 0; if ( handle == 0 ) return ok; DIR * h( static_cast<DIR*>(handle) ); handle = 0; return error_code( ::closedir( h ) == 0 ? 0 : errno, system_category ); } // warning: the only dirent member updated is d_name inline int readdir_r_simulator( DIR * dirp, struct dirent * entry, struct dirent ** result ) // *result set to 0 on end of directory { errno = 0; # if !defined(__CYGWIN__) \ && defined(_POSIX_THREAD_SAFE_FUNCTIONS) \ && defined(_SC_THREAD_SAFE_FUNCTIONS) \ && (_POSIX_THREAD_SAFE_FUNCTIONS+0 >= 0) \ && (!defined(__hpux) || (defined(__hpux) && defined(_REENTRANT))) if ( ::sysconf( _SC_THREAD_SAFE_FUNCTIONS ) >= 0 ) { return ::readdir_r( dirp, entry, result ); } # endif struct dirent * p; *result = 0; if ( (p = ::readdir( dirp )) == 0 ) return errno; std::strcpy( entry->d_name, p->d_name ); *result = entry; return 0; } BOOST_FILESYSTEM_DECL error_code dir_itr_increment( void *& handle, void *& buffer, std::string & target, file_status & sf, file_status & symlink_sf ) { BOOST_ASSERT( buffer != 0 ); dirent * entry( static_cast<dirent *>(buffer) ); dirent * result; int return_code; if ( (return_code = readdir_r_simulator( static_cast<DIR*>(handle), entry, &result )) != 0 ) return error_code( errno, system_category ); if ( result == 0 ) return dir_itr_close( handle, buffer ); target = entry->d_name;# ifdef BOOST_FILESYSTEM_STATUS_CACHE if ( entry->d_type == DT_UNKNOWN ) // filesystem does not supply d_type value { sf = symlink_sf = fs::file_status(fs::status_unknown); } else // filesystem supplies d_type value { if ( entry->d_type == DT_DIR ) sf = symlink_sf = fs::file_status( fs::directory_file ); else if ( entry->d_type == DT_REG ) sf = symlink_sf = fs::file_status( fs::regular_file ); else if ( entry->d_type == DT_LNK ) { sf = fs::file_status( fs::status_unknown ); symlink_sf = fs::file_status( fs::symlink_file ); } else sf = symlink_sf = fs::file_status( fs::status_unknown ); }# else sf = symlink_sf = fs::file_status( fs::status_unknown );# endif return ok; }# endif } // namespace detail } // namespace filesystem} // namespace boost
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -