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/FileSystem.h> 105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/Directory.h> 115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <mcld/Support/Path.h> 125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <llvm/Support/ErrorHandling.h> 135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <cerrno> 155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <dirent.h> 165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <stdio.h> 175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <sys/stat.h> 185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <sys/types.h> 195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <string> 205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <stack> 215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao#include <unistd.h> 225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace mcld{ 245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace sys{ 255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace fs{ 265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaonamespace detail{ 275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst char separator = '/'; 295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaoconst char preferred_separator = '/'; 305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// return the last charactor being handled. 325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaosize_t canonicalize(std::string& pathname) 335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // Variable Index // 355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // SepTable - stack of result separators 365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // LR(1) Algorithm // 375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // traverse pPathName 385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if we meet '//', '///', '////', ... 395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> ignore it 405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> push current into stack 415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> jump to the next not '/' 425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if we meet '/./' 435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> ignore 445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> jump to the next not '/' 455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if we meet '/../' 465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> pop previous position of '/' P 475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> erase P+1 to now 485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if we meet other else 495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // -> go go go 505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // if we meet '/.../', '/..../', ... -> illegal 515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pathname.empty()) 525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t handler = 0; 555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao std::stack<size_t> slash_stack; 565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao slash_stack.push(-1); 575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao while (handler < pathname.size()) { 585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (separator == pathname[handler]) { // handler = 1st '/' 595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao size_t next = handler + 1; 605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (next >= pathname.size()) 615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return handler; 625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(pathname[next]) { // next = handler + 1; 635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case separator: { // '//' 645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao while (next < pathname.size() && separator == pathname[next]) 655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++next; 665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // next is the last not '/' 675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pathname.erase(handler, next - handler - 1); 685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // handler is the first '/' 695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao slash_stack.push(handler); 705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case '.': { // '/.' 735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++next; // next = handler + 2 745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (next >= pathname.size()) // '/.' 755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return handler; 765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (pathname[next]) { 775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case separator: { // '/./' 785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pathname.erase(handler, 2); 795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case '.': { // '/..' 825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao ++next; // next = handler + 3; 835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (next >= pathname.size()) // '/..?' 845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return handler; 855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch(pathname[next]) { 865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case separator: { // '/../' 875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao handler = slash_stack.top(); 885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao slash_stack.pop(); 895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pathname.erase(handler+1, next-handler); 905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (static_cast<size_t>(-1) == handler) { 915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao slash_stack.push(-1); 925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao handler = pathname.find_first_of(separator, handler); 935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case '.': { // '/...', illegal 975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return handler; 985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default : { // '/..a' 1015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao slash_stack.push(handler); 1025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao handler = pathname.find_first_of(separator, handler+3); 1035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default : { // '/.a' 1095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao slash_stack.push(handler); 1105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao handler = pathname.find_first_of(separator, handler+2); 1115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default : { // '/a 1175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao slash_stack.push(handler); 1185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao handler = pathname.find_first_of(separator, handler+1); 1195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 1205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else { 1245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao handler = pathname.find_first_of(separator, handler); 1255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return handler; 1285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaobool not_found_error(int perrno) 1315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return perrno == ENOENT || perrno == ENOTDIR; 1335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid status(const Path& p, FileStatus& pFileStatus) 1365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao struct stat path_stat; 1385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(stat(p.c_str(), &path_stat)!= 0) 1395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao { 1405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(not_found_error(errno)) 1415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao { 1425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(FileNotFound); 1435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 1455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(StatusError); 1465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if(S_ISDIR(path_stat.st_mode)) 1485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(DirectoryFile); 1495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if(S_ISREG(path_stat.st_mode)) 1505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(RegularFile); 1515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if(S_ISBLK(path_stat.st_mode)) 1525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(BlockFile); 1535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if(S_ISCHR(path_stat.st_mode)) 1545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(CharacterFile); 1555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if(S_ISFIFO(path_stat.st_mode)) 1565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(FifoFile); 1575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else if(S_ISSOCK(path_stat.st_mode)) 1585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(SocketFile); 1595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 1605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(TypeUnknown); 1615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid symlink_status(const Path& p, FileStatus& pFileStatus) 1645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao struct stat path_stat; 1665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(lstat(p.c_str(), &path_stat)!= 0) 1675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao { 1685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(errno == ENOENT || errno == ENOTDIR) // these are not errors 1695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao { 1705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(FileNotFound); 1715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 1735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(StatusError); 1745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 1755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(S_ISREG(path_stat.st_mode)) 1765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(RegularFile); 1775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(S_ISDIR(path_stat.st_mode)) 1785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(DirectoryFile); 1795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(S_ISLNK(path_stat.st_mode)) 1805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(SymlinkFile); 1815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(S_ISBLK(path_stat.st_mode)) 1825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(BlockFile); 1835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(S_ISCHR(path_stat.st_mode)) 1845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(CharacterFile); 1855460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(S_ISFIFO(path_stat.st_mode)) 1865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(FifoFile); 1875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if(S_ISSOCK(path_stat.st_mode)) 1885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(SocketFile); 1895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao else 1905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pFileStatus.setType(TypeUnknown); 1915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 1925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 1935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// read_dir - return true if we read one entry 1945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// @return value -1: read error 1955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 0: read the end 1965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 1: success 1975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaostatic int read_dir(intptr_t& pDir, std::string& pOutFilename) 1985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 1995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao errno = 0; 2005460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao dirent *cur_dir = ::readdir(reinterpret_cast<DIR*>(pDir)); 2015460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (0 == cur_dir && 0 != errno) 2025460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return -1; 2035460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2045460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // idx does not stay at the end, but all elements had beed put into cache. 2055460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (NULL == cur_dir) { 2065460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 0; 2075460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2085460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2095460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::StringRef name(cur_dir->d_name, strlen(cur_dir->d_name)); 2105460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if ((name.size() == 1 && name[0] == '.') || 2115460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao (name.size() == 2 && name[0] == '.' && name[1] == '.')) 2125460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return read_dir(pDir, pOutFilename); 2135460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2145460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // find a new directory 2155460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pOutFilename.append(name.data(), name.size()); 2165460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return 1; 2175460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2185460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2195460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao/// directory_iterator_increment - increment function implementation 2205460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 2215460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// iterator will call this function in two situations: 2225460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 1. All elements have been put into cache, and iterator stays at the end 2235460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// of cache. (a real end) 2245460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// 2. Some but not all elements had beed put into cache, and we stoped. 2255460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao// An iterator now is staying at the end of cache. (a temporal end) 2265460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaomcld::sys::fs::PathCache::entry_type* bring_one_into_cache(DirIterator& pIter) 2275460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2285460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::sys::fs::PathCache::entry_type* entry = 0; 2295460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao std::string path(pIter.m_pParent->m_Path.native()); 2305460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (read_dir(pIter.m_pParent->m_Handler, path)) { 2315460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case 1: { 2325460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // read one 2335460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool exist = false; 2345460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry = pIter.m_pParent->m_Cache.insert(path, exist); 2355460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!exist) 2365460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry->setValue(new Path(path)); 2375460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 2385460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2395460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case 0:// meet real end 2405460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pIter.m_pParent->m_CacheFull = true; 2415460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 2425460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 2435460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case -1: 2445460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(std::string("Can't read directory: ")+ 2455460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pIter.m_pParent->path().native()); 2465460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao break; 2475460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2485460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return entry; 2495460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2505460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2515460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid open_dir(Directory& pDir) 2525460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2535460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pDir.m_Handler = reinterpret_cast<intptr_t>(opendir(pDir.path().c_str())); 2545460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pDir.m_Handler == 0) { 2555460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao errno = 0; // opendir() will set errno if it failed to open directory. 2565460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pDir.m_CacheFull = true; 2575460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 2585460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2595460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // read one entry for advance the end element of the cache. 2605460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao std::string path(pDir.path().native()); 2615460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao switch (read_dir(pDir.m_Handler, path)) { 2625460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case 1: { 2635460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // find a new directory 2645460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao bool exist = false; 2655460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao mcld::sys::fs::PathCache::entry_type* entry = pDir.m_Cache.insert(path, exist); 2665460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (!exist) 2675460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao entry->setValue(new Path(path)); 2685460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 2695460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2705460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case 0: 2715460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao // FIXME: a warning function 2725460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pDir.m_CacheFull = true; 2735460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao return; 2745460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao default: 2755460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao case -1: 2765460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao llvm::report_fatal_error(std::string("Can't read directory: ")+ 2775460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pDir.path().native()); 2785460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao } 2795460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2805460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2815460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid close_dir(Directory& pDir) 2825460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2835460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao if (pDir.m_Handler) 2845460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao closedir(reinterpret_cast<DIR *>(pDir.m_Handler)); 285affc150dc44fab1911775a49636d0ce85333b634Zonr Chang pDir.m_Handler = 0; 2865460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2875460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2885460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liaovoid get_pwd(std::string& pPWD) 2895460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao{ 2905460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao char* pwd = (char*)malloc(PATH_MAX); 2915460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao pPWD.assign(getcwd(pwd, PATH_MAX)); 2925460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao free(pwd); 2935460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} 2945460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 2955460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of detail 2965460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of fs 2975460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of sys 2985460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao} // namespace of mcld 2995460a1f25d9ddecb5c70667267d66d51af177a99Shih-wei Liao 300