15460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===- PathV3.inc ---------------------------------------------------------===// 25460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 35460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// The MCLinker Project 45460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 55460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// This file is distributed under the University of Illinois Open Source 65460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// License. See LICENSE.TXT for details. 75460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 85460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao//===----------------------------------------------------------------------===// 95460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/Path.h> 10f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines#include <mcld/Support/FileSystem.h> 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ErrorHandling.h> 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cerrno> 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <stdio.h> 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <sys/stat.h> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <sys/types.h> 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <string> 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <stack> 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <unistd.h> 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld{ 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace sys{ 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace fs{ 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 25f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 26f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// mcld::sys::fs::detail 27f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines//===----------------------------------------------------------------------===// 28f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hinesnamespace detail{ 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// return the last charactor being handled. 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t canonicalize(std::string& pathname) 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Variable Index // 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // SepTable - stack of result separators 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // LR(1) Algorithm // 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // traverse pPathName 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if we meet '//', '///', '////', ... 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> ignore it 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> push current into stack 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> jump to the next not '/' 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if we meet '/./' 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> ignore 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> jump to the next not '/' 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if we meet '/../' 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> pop previous position of '/' P 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> erase P+1 to now 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if we meet other else 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> go go go 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if we meet '/.../', '/..../', ... -> illegal 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pathname.empty()) 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t handler = 0; 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao std::stack<size_t> slash_stack; 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao slash_stack.push(-1); 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao while (handler < pathname.size()) { 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (separator == pathname[handler]) { // handler = 1st '/' 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t next = handler + 1; 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (next >= pathname.size()) 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return handler; 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(pathname[next]) { // next = handler + 1; 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case separator: { // '//' 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao while (next < pathname.size() && separator == pathname[next]) 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++next; 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // next is the last not '/' 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pathname.erase(handler, next - handler - 1); 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // handler is the first '/' 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao slash_stack.push(handler); 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case '.': { // '/.' 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++next; // next = handler + 2 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (next >= pathname.size()) // '/.' 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return handler; 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pathname[next]) { 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case separator: { // '/./' 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pathname.erase(handler, 2); 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case '.': { // '/..' 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++next; // next = handler + 3; 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (next >= pathname.size()) // '/..?' 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return handler; 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(pathname[next]) { 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case separator: { // '/../' 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao handler = slash_stack.top(); 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao slash_stack.pop(); 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pathname.erase(handler+1, next-handler); 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (static_cast<size_t>(-1) == handler) { 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao slash_stack.push(-1); 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao handler = pathname.find_first_of(separator, handler); 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case '.': { // '/...', illegal 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return handler; 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default : { // '/..a' 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao slash_stack.push(handler); 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao handler = pathname.find_first_of(separator, handler+3); 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default : { // '/.a' 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao slash_stack.push(handler); 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao handler = pathname.find_first_of(separator, handler+2); 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default : { // '/a 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao slash_stack.push(handler); 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao handler = pathname.find_first_of(separator, handler+1); 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao handler = pathname.find_first_of(separator, handler); 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return handler; 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool not_found_error(int perrno) 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return perrno == ENOENT || perrno == ENOTDIR; 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid status(const Path& p, FileStatus& pFileStatus) 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao struct stat path_stat; 1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(stat(p.c_str(), &path_stat)!= 0) 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao { 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(not_found_error(errno)) 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao { 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(FileNotFound); 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(StatusError); 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if(S_ISDIR(path_stat.st_mode)) 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(DirectoryFile); 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if(S_ISREG(path_stat.st_mode)) 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(RegularFile); 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if(S_ISBLK(path_stat.st_mode)) 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(BlockFile); 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if(S_ISCHR(path_stat.st_mode)) 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(CharacterFile); 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if(S_ISFIFO(path_stat.st_mode)) 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(FifoFile); 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if(S_ISSOCK(path_stat.st_mode)) 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(SocketFile); 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(TypeUnknown); 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid symlink_status(const Path& p, FileStatus& pFileStatus) 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao struct stat path_stat; 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(lstat(p.c_str(), &path_stat)!= 0) 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao { 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(errno == ENOENT || errno == ENOTDIR) // these are not errors 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao { 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(FileNotFound); 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(StatusError); 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(S_ISREG(path_stat.st_mode)) 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(RegularFile); 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(S_ISDIR(path_stat.st_mode)) 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(DirectoryFile); 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(S_ISLNK(path_stat.st_mode)) 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(SymlinkFile); 1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(S_ISBLK(path_stat.st_mode)) 1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(BlockFile); 1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(S_ISCHR(path_stat.st_mode)) 1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(CharacterFile); 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(S_ISFIFO(path_stat.st_mode)) 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(FifoFile); 1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(S_ISSOCK(path_stat.st_mode)) 1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(SocketFile); 1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(TypeUnknown); 1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// directory_iterator_increment - increment function implementation 1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// iterator will call this function in two situations: 1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 1. All elements have been put into cache, and iterator stays at the end 1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// of cache. (a real end) 197f7ac0f19a1c8d0ad14bcf6456ce368b830fea886Stephen Hines// 2. Some but not all elements had been put into cache, and we stoped. 1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// An iterator now is staying at the end of cache. (a temporal end) 1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaomcld::sys::fs::PathCache::entry_type* bring_one_into_cache(DirIterator& pIter) 2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::sys::fs::PathCache::entry_type* entry = 0; 2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao std::string path(pIter.m_pParent->m_Path.native()); 2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (read_dir(pIter.m_pParent->m_Handler, path)) { 2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case 1: { 2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // read one 2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool exist = false; 2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry = pIter.m_pParent->m_Cache.insert(path, exist); 2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!exist) 2096f75755c9204b1d8817ae5a65a2f7e5af0ec3f70Stephen Hines entry->setValue(path); 2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case 0:// meet real end 2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pIter.m_pParent->m_CacheFull = true; 2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case -1: 2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(std::string("Can't read directory: ")+ 2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pIter.m_pParent->path().native()); 2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return entry; 2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of detail 2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of fs 2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of sys 2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 229