diff --git a/File/File.cpp b/File/File.cpp index 11e8604..ee9b81d 100644 --- a/File/File.cpp +++ b/File/File.cpp @@ -31,6 +31,12 @@ File::File(const char *name, int flags, const std::nothrow_t&) _fd = ::open(name, flags); } + +File::File(const char *name, int flags, mode_t mode, const std::nothrow_t&) +{ + _fd = ::open(name, flags, mode); +} + File::File(const char *name, bool readOnly, const std::nothrow_t&) { _fd = ::open(name, readOnly ? O_RDONLY : O_RDWR); @@ -46,6 +52,16 @@ File::File(const char *name, int flags) throw POSIXException( __METHOD__ ": open", errno); } +File::File(const char *name, int flags, mode_t mode) +{ +#undef __METHOD__ +#define __METHOD__ "File::File" + + _fd = ::open(name, flags, mode); + if (_fd < 0) + throw POSIXException( __METHOD__ ": open", errno); +} + File::File(const char *name, bool readOnly) { diff --git a/File/File.h b/File/File.h index 2d83591..1bc5e5d 100644 --- a/File/File.h +++ b/File/File.h @@ -16,9 +16,11 @@ class File { File(int fd); File(const char *name, int flags); + File(const char *name, int flags, mode_t mode); File(const char *name, bool readOnly); File(const char *name, int flags, const std::nothrow_t &); + File(const char *name, int flags, mode_t mode, const std::nothrow_t &); File(const char *name, bool readOnly, const std::nothrow_t &); ~File(); diff --git a/PROFuseX.xcodeproj/kelvin.pbxuser b/PROFuseX.xcodeproj/kelvin.pbxuser index 7038c28..81ced93 100644 --- a/PROFuseX.xcodeproj/kelvin.pbxuser +++ b/PROFuseX.xcodeproj/kelvin.pbxuser @@ -2,14 +2,14 @@ { 08FB7793FE84155DC02AAC07 /* Project object */ = { activeBuildConfigurationName = Debug; - activeExecutable = B656AF0411AA105500AB578A /* NibbleTest */; - activeTarget = B656AF0211AA105500AB578A /* NibbleTest */; + activeExecutable = B63EFCCF11A36C7300C90DCE /* apfm */; + activeTarget = B63EFCCD11A36C7300C90DCE /* apfm */; addToTargets = ( ); breakpoints = ( - B63EFD8911A4455A00C90DCE /* apfm.cpp:346 */, + B63EFD8911A4455A00C90DCE /* apfm.cpp:487 */, B63EFE0E11A451C600C90DCE /* VolumeEntry.cpp:105 */, - B63EFE3B11A4799800C90DCE /* apfm.cpp:184 */, + B63EFE3B11A4799800C90DCE /* apfm.cpp:183 */, B6F3642F11AA1E150045E114 /* NibbleTest.cpp:74 */, ); codeSenseManager = B63EFA6811A093C200C90DCE /* Code sense */; @@ -144,6 +144,34 @@ B6F3647011AB35F00045E114 /* PBXTextBookmark */ = B6F3647011AB35F00045E114 /* PBXTextBookmark */; B6F3647111AB35FE0045E114 /* PBXTextBookmark */ = B6F3647111AB35FE0045E114 /* PBXTextBookmark */; B6F3647211AB35FE0045E114 /* PBXTextBookmark */ = B6F3647211AB35FE0045E114 /* PBXTextBookmark */; + B6F3649411AB58E80045E114 /* PBXTextBookmark */ = B6F3649411AB58E80045E114 /* PBXTextBookmark */; + B6F3649511AB58E80045E114 /* PBXTextBookmark */ = B6F3649511AB58E80045E114 /* PBXTextBookmark */; + B6F3649611AB58E80045E114 /* PBXTextBookmark */ = B6F3649611AB58E80045E114 /* PBXTextBookmark */; + B6F3649711AB58E80045E114 /* XCBuildMessageTextBookmark */ = B6F3649711AB58E80045E114 /* XCBuildMessageTextBookmark */; + B6F3649811AB58E80045E114 /* PBXTextBookmark */ = B6F3649811AB58E80045E114 /* PBXTextBookmark */; + B6F3649E11AB59190045E114 /* PBXTextBookmark */ = B6F3649E11AB59190045E114 /* PBXTextBookmark */; + B6F3649F11AB59190045E114 /* XCBuildMessageTextBookmark */ = B6F3649F11AB59190045E114 /* XCBuildMessageTextBookmark */; + B6F364A011AB59190045E114 /* PBXTextBookmark */ = B6F364A011AB59190045E114 /* PBXTextBookmark */; + B6F364A511AB593E0045E114 /* PBXTextBookmark */ = B6F364A511AB593E0045E114 /* PBXTextBookmark */; + B6F364A911AB5EBD0045E114 /* PBXTextBookmark */ = B6F364A911AB5EBD0045E114 /* PBXTextBookmark */; + B6F364B111AB74F40045E114 /* XCBuildMessageTextBookmark */ = B6F364B111AB74F40045E114 /* XCBuildMessageTextBookmark */; + B6F364B211AB74F40045E114 /* PBXTextBookmark */ = B6F364B211AB74F40045E114 /* PBXTextBookmark */; + B6F364B611AB84840045E114 /* PBXTextBookmark */ = B6F364B611AB84840045E114 /* PBXTextBookmark */; + B6F364B711AB84840045E114 /* PBXTextBookmark */ = B6F364B711AB84840045E114 /* PBXTextBookmark */; + B6F364B811AB84840045E114 /* PBXTextBookmark */ = B6F364B811AB84840045E114 /* PBXTextBookmark */; + B6F364B911AB84840045E114 /* PBXTextBookmark */ = B6F364B911AB84840045E114 /* PBXTextBookmark */; + B6F364BE11AC92730045E114 /* PBXTextBookmark */ = B6F364BE11AC92730045E114 /* PBXTextBookmark */; + B6F364BF11AC92730045E114 /* XCBuildMessageTextBookmark */ = B6F364BF11AC92730045E114 /* XCBuildMessageTextBookmark */; + B6F364C011AC92730045E114 /* PBXTextBookmark */ = B6F364C011AC92730045E114 /* PBXTextBookmark */; + B6F364C811ACAB370045E114 /* PBXTextBookmark */ = B6F364C811ACAB370045E114 /* PBXTextBookmark */; + B6F364C911ACAB370045E114 /* PBXTextBookmark */ = B6F364C911ACAB370045E114 /* PBXTextBookmark */; + B6F364CA11ACAB370045E114 /* PBXTextBookmark */ = B6F364CA11ACAB370045E114 /* PBXTextBookmark */; + B6F364E811ACB5790045E114 /* PBXTextBookmark */ = B6F364E811ACB5790045E114 /* PBXTextBookmark */; + B6F364E911ACB5790045E114 /* XCBuildMessageTextBookmark */ = B6F364E911ACB5790045E114 /* XCBuildMessageTextBookmark */; + B6F364EB11ACB5790045E114 /* PBXTextBookmark */ = B6F364EB11ACB5790045E114 /* PBXTextBookmark */; + B6F364EC11ACB5790045E114 /* XCBuildMessageTextBookmark */ = B6F364EC11ACB5790045E114 /* XCBuildMessageTextBookmark */; + B6F364ED11ACB5790045E114 /* PBXTextBookmark */ = B6F364ED11ACB5790045E114 /* PBXTextBookmark */; + B6F364F511ACB5B60045E114 /* PBXTextBookmark */ = B6F364F511ACB5B60045E114 /* PBXTextBookmark */; }; sourceControlManager = B63EFA6711A093C200C90DCE /* Source Control */; userBuildSettings = { @@ -319,16 +347,16 @@ }; B63EFAC911A09DAA00C90DCE /* File.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1264, 1209}}"; - sepNavSelRange = "{1210, 0}"; - sepNavVisRange = "{0, 1046}"; + sepNavIntBoundsRect = "{{0, 0}, {838, 1534}}"; + sepNavSelRange = "{384, 0}"; + sepNavVisRange = "{0, 571}"; }; }; B63EFACA11A09DAA00C90DCE /* File.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1264, 932}}"; - sepNavSelRange = "{457, 0}"; - sepNavVisRange = "{0, 611}"; + sepNavIntBoundsRect = "{{0, 0}, {701, 948}}"; + sepNavSelRange = "{423, 0}"; + sepNavVisRange = "{0, 888}"; }; }; B63EFACB11A09DAA00C90DCE /* MappedFile.cpp */ = { @@ -361,9 +389,9 @@ }; B63EFAD211A09DB500C90DCE /* Exception.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {838, 1898}}"; - sepNavSelRange = "{734, 12}"; - sepNavVisRange = "{434, 1049}"; + sepNavIntBoundsRect = "{{0, 0}, {838, 1885}}"; + sepNavSelRange = "{783, 10}"; + sepNavVisRange = "{434, 1003}"; }; }; B63EFAD311A09DB500C90DCE /* Lock.cpp */ = { @@ -417,16 +445,16 @@ }; B63EFBEB11A244EE00C90DCE /* File.h */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {1264, 2964}}"; - sepNavSelRange = "{2767, 0}"; - sepNavVisRange = "{1820, 1622}"; + sepNavIntBoundsRect = "{{0, 0}, {838, 3029}}"; + sepNavSelRange = "{2795, 35}"; + sepNavVisRange = "{2292, 855}"; }; }; B63EFBEC11A244EE00C90DCE /* FileEntry.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {838, 5330}}"; - sepNavSelRange = "{7404, 0}"; - sepNavVisRange = "{6413, 938}"; + sepNavIntBoundsRect = "{{0, 0}, {838, 7683}}"; + sepNavSelRange = "{1582, 0}"; + sepNavVisRange = "{1039, 851}"; }; }; B63EFBF111A244EE00C90DCE /* VolumeEntry.cpp */ = { @@ -475,9 +503,9 @@ }; B63EFC9911A35F7200C90DCE /* fuse_pascal.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {701, 4004}}"; - sepNavSelRange = "{7036, 0}"; - sepNavVisRange = "{5446, 1697}"; + sepNavIntBoundsRect = "{{0, 0}, {838, 4121}}"; + sepNavSelRange = "{4176, 0}"; + sepNavVisRange = "{3759, 970}"; }; }; B63EFC9B11A35F7B00C90DCE /* newfs_pascal.cpp */ = { @@ -496,9 +524,9 @@ }; B63EFC9F11A35F8F00C90DCE /* apfm.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {838, 5187}}"; - sepNavSelRange = "{1814, 0}"; - sepNavVisRange = "{2880, 875}"; + sepNavIntBoundsRect = "{{0, 0}, {701, 7228}}"; + sepNavSelRange = "{916, 0}"; + sepNavVisRange = "{800, 1552}"; }; }; B63EFCB211A3639400C90DCE /* PBXTextBookmark */ = { @@ -573,12 +601,12 @@ fRef = B63EFAC911A09DAA00C90DCE /* File.cpp */; name = "File.cpp: 34"; rLen = 0; - rLoc = 385; + rLoc = 504; rType = 0; vrLen = 225; vrLoc = 284; }; - B63EFD8911A4455A00C90DCE /* apfm.cpp:346 */ = { + B63EFD8911A4455A00C90DCE /* apfm.cpp:487 */ = { isa = PBXFileBreakpoint; actions = ( ); @@ -590,7 +618,7 @@ functionName = "main(/* int argc, char **argv */)"; hitCount = 0; ignoreCount = 0; - lineNumber = 346; + lineNumber = 487; modificationTime = 296363159.802434; originalNumberOfMultipleMatches = 1; state = 0; @@ -806,7 +834,7 @@ originalNumberOfMultipleMatches = 1; state = 1; }; - B63EFE3B11A4799800C90DCE /* apfm.cpp:184 */ = { + B63EFE3B11A4799800C90DCE /* apfm.cpp:183 */ = { isa = PBXFileBreakpoint; actions = ( ); @@ -818,7 +846,7 @@ functionName = "action_cat(unsigned argc, char **argv, Pascal::VolumeEntry *volume)"; hitCount = 0; ignoreCount = 0; - lineNumber = 184; + lineNumber = 183; modificationTime = 296363159.805745; originalNumberOfMultipleMatches = 1; state = 0; @@ -902,6 +930,11 @@ name = VolumeEntry.cpp; path = ./Pascal/VolumeEntry.cpp; sourceTree = ""; + uiCtxt = { + sepNavIntBoundsRect = "{{0, 0}, {838, 7085}}"; + sepNavSelRange = "{3256, 0}"; + sepNavVisRange = "{2568, 1113}"; + }; }; B63EFEA711A488C200C90DCE /* PBXTextBookmark */ = { isa = PBXTextBookmark; @@ -1048,9 +1081,9 @@ }; B656AEFE11AA0F8C00AB578A /* NibbleTest.cpp */ = { uiCtxt = { - sepNavIntBoundsRect = "{{0, 0}, {838, 1079}}"; + sepNavIntBoundsRect = "{{0, 0}, {701, 1079}}"; sepNavSelRange = "{1570, 0}"; - sepNavVisRange = "{917, 940}"; + sepNavVisRange = "{173, 1684}"; }; }; B656AF0211AA105500AB578A /* NibbleTest */ = { @@ -1102,7 +1135,7 @@ fRef = B63EFBEC11A244EE00C90DCE /* FileEntry.cpp */; name = "FileEntry.cpp: 372"; rLen = 0; - rLoc = 7404; + rLoc = 11357; rType = 0; vrLen = 938; vrLoc = 6413; @@ -1112,7 +1145,7 @@ fRef = B63EFC9F11A35F8F00C90DCE /* apfm.cpp */; name = "apfm.cpp: 107"; rLen = 0; - rLoc = 1814; + rLoc = 1824; rType = 0; vrLen = 875; vrLoc = 2880; @@ -1172,7 +1205,7 @@ fRef = B63EFEA511A488C200C90DCE /* VolumeEntry.cpp */; name = "VolumeEntry.cpp: 460"; rLen = 0; - rLoc = 9665; + rLoc = 10173; rType = 0; vrLen = 797; vrLoc = 8547; @@ -1319,4 +1352,284 @@ sourceDirectories = ( ); }; + B6F3649411AB58E80045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B656AEFE11AA0F8C00AB578A /* NibbleTest.cpp */; + name = "NibbleTest.cpp: 70"; + rLen = 0; + rLoc = 1570; + rType = 0; + vrLen = 940; + vrLoc = 917; + }; + B6F3649511AB58E80045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B6F3647B11AB361D0045E114 /* xattr.cpp */; + name = "xattr.cpp: 1"; + rLen = 0; + rLoc = 0; + rType = 0; + vrLen = 985; + vrLoc = 0; + }; + B6F3649611AB58E80045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFC9911A35F7200C90DCE /* fuse_pascal.cpp */; + name = "fuse_pascal.cpp: 187"; + rLen = 0; + rLoc = 4176; + rType = 0; + vrLen = 970; + vrLoc = 3759; + }; + B6F3649711AB58E80045E114 /* XCBuildMessageTextBookmark */ = { + isa = PBXTextBookmark; + comments = "Prototype for 'File::File(const char*, int, mode_t, const std::nothrow_t&)' does not match any in class 'File'"; + fRef = B63EFAC911A09DAA00C90DCE /* File.cpp */; + fallbackIsa = XCBuildMessageTextBookmark; + rLen = 1; + rLoc = 34; + rType = 1; + }; + B6F3649811AB58E80045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFAC911A09DAA00C90DCE /* File.cpp */; + name = "File.cpp: 35"; + rLen = 0; + rLoc = 384; + rType = 0; + vrLen = 571; + vrLoc = 0; + }; + B6F3649E11AB59190045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFAC911A09DAA00C90DCE /* File.cpp */; + name = "File.cpp: 35"; + rLen = 0; + rLoc = 384; + rType = 0; + vrLen = 571; + vrLoc = 0; + }; + B6F3649F11AB59190045E114 /* XCBuildMessageTextBookmark */ = { + isa = PBXTextBookmark; + comments = "'File' has not been declared"; + fRef = B63EFC9F11A35F8F00C90DCE /* apfm.cpp */; + fallbackIsa = XCBuildMessageTextBookmark; + rLen = 1; + rLoc = 279; + rType = 1; + }; + B6F364A011AB59190045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFC9F11A35F8F00C90DCE /* apfm.cpp */; + name = "apfm.cpp: 281"; + rLen = 66; + rLoc = 5764; + rType = 0; + vrLen = 849; + vrLoc = 5157; + }; + B6F364A511AB593E0045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFC9F11A35F8F00C90DCE /* apfm.cpp */; + name = "apfm.cpp: 281"; + rLen = 66; + rLoc = 5764; + rType = 0; + vrLen = 855; + vrLoc = 5157; + }; + B6F364A911AB5EBD0045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFC9F11A35F8F00C90DCE /* apfm.cpp */; + name = "apfm.cpp: 281"; + rLen = 66; + rLoc = 5764; + rType = 0; + vrLen = 855; + vrLoc = 5157; + }; + B6F364B111AB74F40045E114 /* XCBuildMessageTextBookmark */ = { + isa = PBXTextBookmark; + comments = "'kTextFile' was not declared in this scope"; + fRef = B63EFC9F11A35F8F00C90DCE /* apfm.cpp */; + fallbackIsa = XCBuildMessageTextBookmark; + rLen = 1; + rLoc = 382; + rType = 1; + }; + B6F364B211AB74F40045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFC9F11A35F8F00C90DCE /* apfm.cpp */; + name = "apfm.cpp: 385"; + rLen = 0; + rLoc = 8425; + rType = 0; + vrLen = 715; + vrLoc = 8003; + }; + B6F364B611AB84840045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFC9F11A35F8F00C90DCE /* apfm.cpp */; + name = "apfm.cpp: 385"; + rLen = 0; + rLoc = 8425; + rType = 0; + vrLen = 715; + vrLoc = 8003; + }; + B6F364B711AB84840045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFAD211A09DB500C90DCE /* Exception.h */; + name = "Exception.h: 39"; + rLen = 10; + rLoc = 783; + rType = 0; + vrLen = 1003; + vrLoc = 434; + }; + B6F364B811AB84840045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFEA511A488C200C90DCE /* VolumeEntry.cpp */; + name = "VolumeEntry.cpp: 464"; + rLen = 0; + rLoc = 10173; + rType = 0; + vrLen = 563; + vrLoc = 8511; + }; + B6F364B911AB84840045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFEA511A488C200C90DCE /* VolumeEntry.cpp */; + name = "VolumeEntry.cpp: 473"; + rLen = 0; + rLoc = 10173; + rType = 0; + vrLen = 546; + vrLoc = 8717; + }; + B6F364BE11AC92730045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFEA511A488C200C90DCE /* VolumeEntry.cpp */; + name = "VolumeEntry.cpp: 473"; + rLen = 0; + rLoc = 10173; + rType = 0; + vrLen = 546; + vrLoc = 8717; + }; + B6F364BF11AC92730045E114 /* XCBuildMessageTextBookmark */ = { + isa = PBXTextBookmark; + comments = "'volume' is not a class or namespace"; + fRef = B63EFC9F11A35F8F00C90DCE /* apfm.cpp */; + fallbackIsa = XCBuildMessageTextBookmark; + rLen = 1; + rLoc = 378; + rType = 1; + }; + B6F364C011AC92730045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFC9F11A35F8F00C90DCE /* apfm.cpp */; + name = "apfm.cpp: 381"; + rLen = 0; + rLoc = 8337; + rType = 0; + vrLen = 667; + vrLoc = 7907; + }; + B6F364C811ACAB370045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFC9F11A35F8F00C90DCE /* apfm.cpp */; + name = "apfm.cpp: 381"; + rLen = 0; + rLoc = 8337; + rType = 0; + vrLen = 667; + vrLoc = 7907; + }; + B6F364C911ACAB370045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFEA511A488C200C90DCE /* VolumeEntry.cpp */; + name = "VolumeEntry.cpp: 473"; + rLen = 0; + rLoc = 10173; + rType = 0; + vrLen = 546; + vrLoc = 8717; + }; + B6F364CA11ACAB370045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFEA511A488C200C90DCE /* VolumeEntry.cpp */; + name = "VolumeEntry.cpp: 475"; + rLen = 0; + rLoc = 10173; + rType = 0; + vrLen = 490; + vrLoc = 8968; + }; + B6F364E811ACB5790045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFBEC11A244EE00C90DCE /* FileEntry.cpp */; + name = "FileEntry.cpp: 86"; + rLen = 0; + rLoc = 1582; + rType = 0; + vrLen = 851; + vrLoc = 1039; + }; + B6F364E911ACB5790045E114 /* XCBuildMessageTextBookmark */ = { + isa = PBXTextBookmark; + comments = "'void Pascal::VolumeEntry::writeEntry(Pascal::FileEntry*)' is private"; + fRef = B6F364EA11ACB5790045E114 /* File.h */; + fallbackIsa = XCBuildMessageTextBookmark; + rLen = 1; + rLoc = 137; + rType = 1; + }; + B6F364EA11ACB5790045E114 /* File.h */ = { + isa = PBXFileReference; + name = File.h; + path = ./Pascal/File.h; + sourceTree = ""; + }; + B6F364EB11ACB5790045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFBEB11A244EE00C90DCE /* File.h */; + name = "File.h: 141"; + rLen = 35; + rLoc = 2795; + rType = 0; + vrLen = 855; + vrLoc = 2292; + }; + B6F364EC11ACB5790045E114 /* XCBuildMessageTextBookmark */ = { + isa = PBXTextBookmark; + comments = "'_file' was not declared in this scope"; + fRef = B63EFEA511A488C200C90DCE /* VolumeEntry.cpp */; + fallbackIsa = XCBuildMessageTextBookmark; + rLen = 1; + rLoc = 154; + rType = 1; + }; + B6F364ED11ACB5790045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFEA511A488C200C90DCE /* VolumeEntry.cpp */; + name = "VolumeEntry.cpp: 154"; + rLen = 0; + rLoc = 3256; + rType = 0; + vrLen = 1019; + vrLoc = 2603; + }; + B6F364F511ACB5B60045E114 /* PBXTextBookmark */ = { + isa = PBXTextBookmark; + fRef = B63EFEA511A488C200C90DCE /* VolumeEntry.cpp */; + name = "VolumeEntry.cpp: 155"; + rLen = 0; + rLoc = 3256; + rType = 0; + vrLen = 1113; + vrLoc = 2568; + }; } diff --git a/PROFuseX.xcodeproj/kelvin.perspectivev3 b/PROFuseX.xcodeproj/kelvin.perspectivev3 index 7a90b8e..35372d2 100644 --- a/PROFuseX.xcodeproj/kelvin.perspectivev3 +++ b/PROFuseX.xcodeproj/kelvin.perspectivev3 @@ -231,8 +231,6 @@ Layout - BecomeActive - ContentConfiguration PBXBottomSmartGroupGIDs @@ -269,13 +267,17 @@ PBXSmartGroupTreeModuleOutlineStateExpansionKey 08FB7794FE84155DC02AAC07 + B63EFBE711A244EE00C90DCE + B63EFACF11A09DB500C90DCE + B63EFAC811A09DAA00C90DCE B656ADED11A84D3200AB578A 1C37FBAC04509CD000000102 PBXSmartGroupTreeModuleOutlineStateSelectionKey - 2 + 10 + 7 0 @@ -297,7 +299,7 @@ 318 RubberWindowFrame - 394 69 1239 1000 0 0 1920 1178 + 489 -24 1239 1000 0 0 1920 1178 Module PBXSmartGroupTreeModule @@ -308,12 +310,14 @@ Dock + BecomeActive + ContentConfiguration PBXProjectModuleGUID B63EFA6111A093C200C90DCE PBXProjectModuleLabel - NibbleTest.cpp + VolumeEntry.cpp PBXSplitModuleInNavigatorKey Split0 @@ -321,11 +325,11 @@ PBXProjectModuleGUID B63EFA6211A093C200C90DCE PBXProjectModuleLabel - NibbleTest.cpp + VolumeEntry.cpp _historyCapacity 0 bookmark - B6F3647211AB35FE0045E114 + B6F364F511ACB5B60045E114 history B63EFC2611A2D5A400C90DCE @@ -333,7 +337,6 @@ B63EFC3211A2D5A400C90DCE B63EFCB211A3639400C90DCE B63EFCB611A3639400C90DCE - B63EFD7F11A4436B00C90DCE B63EFDA011A4488200C90DCE B63EFDA511A4488200C90DCE B63EFDA711A4488200C90DCE @@ -351,7 +354,6 @@ B63EFEA111A488C200C90DCE B63EFEA211A488C200C90DCE B63EFEA311A488C200C90DCE - B63EFEA711A488C200C90DCE B63EFEA811A488C200C90DCE B63EFEA911A488C200C90DCE B63EFEEC11A4A70400C90DCE @@ -359,21 +361,25 @@ B6E5F0F211A73144000AD141 B6E5F11211A73340000AD141 B6E5F13A11A74F2B000AD141 - B6E5F18111A76B74000AD141 B6E5F18211A76B74000AD141 - B656AE2311A84FA400AB578A B656AE2411A84FA400AB578A B656AE2611A84FA400AB578A B656AE2711A84FA400AB578A - B656AE6511A8591F00AB578A B656AEA711A9C91600AB578A B656AEA811A9C91600AB578A - B656AF2711AA10C900AB578A - B656AF2811AA10C900AB578A B656AF2A11AA10C900AB578A B6F3642D11AA1E070045E114 B6F3647111AB35FE0045E114 - B6F3647011AB35F00045E114 + B6F3649411AB58E80045E114 + B6F3649511AB58E80045E114 + B6F3649611AB58E80045E114 + B6F3649E11AB59190045E114 + B6F364B711AB84840045E114 + B6F364C811ACAB370045E114 + B6F364E811ACB5790045E114 + B6F364E911ACB5790045E114 + B6F364EB11ACB5790045E114 + B6F364EC11ACB5790045E114 SplitCount @@ -389,7 +395,7 @@ Frame {{0, 0}, {899, 562}} RubberWindowFrame - 394 69 1239 1000 0 0 1920 1178 + 489 -24 1239 1000 0 0 1920 1178 Module PBXNavigatorGroup @@ -413,8 +419,6 @@ Frame {{10, 27}, {899, 365}} - RubberWindowFrame - 394 69 1239 1000 0 0 1920 1178 Module XCDetailModule @@ -468,7 +472,9 @@ GeometryConfiguration Frame - {{10, 27}, {899, 349}} + {{10, 27}, {899, 365}} + RubberWindowFrame + 489 -24 1239 1000 0 0 1920 1178 Module PBXBuildResultsModule @@ -690,10 +696,14 @@ 5 WindowOrderList + B6F364EE11ACB5790045E114 + B6F364C211AC92730045E114 + B6F364C111AC92730045E114 /Users/kelvin/Projects/PROFuseX/PROFuseX.xcodeproj + B6F364CC11ACAB370045E114 WindowString - 394 69 1239 1000 0 0 1920 1178 + 489 -24 1239 1000 0 0 1920 1178 WindowToolsV3 diff --git a/PROFuseX.xcodeproj/project.pbxproj b/PROFuseX.xcodeproj/project.pbxproj index f1fbefc..d87bd80 100644 --- a/PROFuseX.xcodeproj/project.pbxproj +++ b/PROFuseX.xcodeproj/project.pbxproj @@ -144,7 +144,7 @@ B656AEFE11AA0F8C00AB578A /* NibbleTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = NibbleTest.cpp; sourceTree = ""; }; B656AF0311AA105500AB578A /* NibbleTest */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = NibbleTest; sourceTree = BUILT_PRODUCTS_DIR; }; B6F3647B11AB361D0045E114 /* xattr.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = xattr.cpp; sourceTree = ""; }; - B6F3648011AB36260045E114 /* xattr */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; name = xattr; path = build/Debug/xattr; sourceTree = ""; }; + B6F3648011AB36260045E114 /* xattr */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = xattr; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ diff --git a/Pascal/File.h b/Pascal/File.h index 0e0b709..70a2476 100644 --- a/Pascal/File.h +++ b/Pascal/File.h @@ -45,7 +45,7 @@ public: unsigned lastBlock() const { return _lastBlock; } unsigned fileKind() const { return _fileKind; } - + unsigned inode() const { return _inode; } void setInode(unsigned inode) { _inode = inode; } @@ -124,6 +124,9 @@ protected: virtual void writeDirectoryEntry(LittleEndian::IOBuffer *); private: + + friend class FileEntry; + VolumeEntry(); void init(void *); @@ -174,19 +177,31 @@ class FileEntry : public Entry { int read(uint8_t *buffer, unsigned size, unsigned offset); int write(uint8_t *buffer, unsigned size, unsigned offset); + int truncate(unsigned newSize); + + const char *name() const { return _fileName; } Date modification() const { return _modification; } + void setFileKind(unsigned kind); + + + protected: virtual void writeDirectoryEntry(LittleEndian::IOBuffer *); - private: + private: + + friend class VolumeEntry; void setName(const char *name); + void extend(unsigned newSize); + + unsigned _status; @@ -196,6 +211,12 @@ class FileEntry : public Entry { unsigned _lastByte; Date _modification; + + unsigned _maxFileSize; // maximum file size. + + + + // non-text files unsigned dataFileSize(); int dataRead(uint8_t *buffer, unsigned size, unsigned offset); diff --git a/Pascal/FileEntry.cpp b/Pascal/FileEntry.cpp index 6e6f773..7b2f7ae 100644 --- a/Pascal/FileEntry.cpp +++ b/Pascal/FileEntry.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include @@ -44,6 +45,7 @@ FileEntry::FileEntry(void *vp) : _fileSize = 0; _pageSize = NULL; + _maxFileSize = 0; } FileEntry::FileEntry(const char *name, unsigned fileKind) @@ -69,6 +71,7 @@ FileEntry::FileEntry(const char *name, unsigned fileKind) _fileSize = 0; _pageSize = NULL; + _maxFileSize = 0; } FileEntry::~FileEntry() @@ -77,6 +80,13 @@ FileEntry::~FileEntry() } +void FileEntry::setFileKind(unsigned kind) +{ + _fileKind = kind; + parent()->writeEntry(this); +} + + void FileEntry::setName(const char *name) { #undef __METHOD__ @@ -93,6 +103,8 @@ void FileEntry::setName(const char *name) // not sure if this is a good idea or not. //_modification = Date::Today(); + + parent()->writeEntry(this); } unsigned FileEntry::fileSize() @@ -138,6 +150,163 @@ int FileEntry::read(uint8_t *buffer, unsigned size, unsigned offset) } +int FileEntry::truncate(unsigned newSize) +{ +#undef __METHOD__ +#define __METHOD__ "FileEntry::truncate" + + unsigned currentSize = fileSize(); + + if (currentSize == newSize) return 0; + + if (fileKind() == kTextFile) + { + if (newSize) + throw ProFUSE::Exception(__METHOD__ ": unable to truncate text file."); + + if (_pageSize) _pageSize->clear(); + } + + extend(newSize); + + _modification = Date::Today(); + parent()->writeEntry(this); + + return 0; +} + +/* + * extend -- common truncation code. + * updates _lastByte and _lastBlock but does + * not update _modification or commit to disk. + */ +void FileEntry::extend(unsigned newSize) +{ +#undef __METHOD__ +#define __METHOD__ "FileEntry::extend" + + unsigned currentSize = fileSize(); + + if (newSize == currentSize) return; + if (newSize > currentSize) + { + + if (newSize > _maxFileSize) + throw ProFUSE::POSIXException(__METHOD__ ": Unable to extend file.", ENOSPC); + + unsigned remainder = newSize - currentSize; + unsigned block = _lastBlock; + + if (_lastByte != 512) + { + // last page not full + unsigned count = std::min(512 - _lastByte, remainder); + uint8_t *address = (uint8_t *)parent()->loadBlock(block); + + std::memset(address + _lastByte, 0, count); + + parent()->unloadBlock(block, true); + + remainder -= count; + } + block++; + + while (remainder) + { + unsigned count = std::min(512u, remainder); + uint8_t *address = (uint8_t *)parent()->loadBlock(block); + + std::memset(address, 0, count); + + parent()->unloadBlock(block, true); + + remainder -= count; + block++; + } + + + } + + _lastBlock = _firstBlock + newSize / 512; + _lastByte = newSize % 512; + if (_lastByte = 0) _lastByte = 512; + +} + + +int FileEntry::write(uint8_t *buffer, unsigned size, unsigned offset) +{ +#undef __METHOD__ +#define __METHOD__ "FileEntry::write" + + if (fileKind() == kTextFile) + { + throw ProFUSE::Exception(__METHOD__ ": Text Files are too weird."); + } + + unsigned currentSize = fileSize(); + + unsigned newSize = std::max(offset + size, currentSize); + + + if (newSize > _maxFileSize) + { + throw ProFUSE::POSIXException(__METHOD__ ": Unable to extend file.", ENOSPC); + } + + if (offset > currentSize) + { + extend(offset); + } + + // now write the data... + + unsigned block = _firstBlock + offset / 512; + unsigned start = offset % 512; + unsigned remainder = size; + + if (start) + { + unsigned count = std::min(512 - start, remainder); + uint8_t *address = (uint8_t *)parent()->loadBlock(block); + + std::memcpy(address + start, buffer, count); + parent()->unloadBlock(block, true); + + remainder -= count; + buffer += count; + block++; + } + + while (remainder) + { + uint8_t *address = (uint8_t *)parent()->loadBlock(block); + + unsigned count = std::min(512u, size); + + std::memcpy(address, buffer, count); + parent()->unloadBlock(block, true); + + remainder -= count; + buffer += count; + block++; + } + + if (newSize > currentSize) + { + _lastBlock = _firstBlock + currentSize / 512; + _lastByte = currentSize % 512; + if (_lastByte == 0) _lastByte = 512; + + } + + _modification = Date::Today(); + parent()->writeEntry(this); + + return size; +} + + unsigned FileEntry::dataFileSize() { return blocks() * 512 - 512 + _lastByte; diff --git a/Pascal/VolumeEntry.cpp b/Pascal/VolumeEntry.cpp index f8c27b2..d6f12be 100644 --- a/Pascal/VolumeEntry.cpp +++ b/Pascal/VolumeEntry.cpp @@ -132,6 +132,8 @@ VolumeEntry::VolumeEntry(Device::BlockDevice *device) try { + std::vector::reverse_iterator iter; + for (unsigned i = 1; i <= _fileCount; ++i) { std::auto_ptr child; @@ -142,12 +144,26 @@ VolumeEntry::VolumeEntry(Device::BlockDevice *device) child->setInode(++_inodeGenerator); child->_parent = this; child->_address = 512 * 2 + i * 0x1a; + _files.push_back(child.release()); - } + } + + // sanity check _firstBlock, _lastBlock? + + // set up _maxBlocks; + unsigned lastBlock = _lastVolumeBlock; + for (iter = _files.rbegin(); iter != _files.rend(); ++iter) + { + FileEntry *e = *iter; + e->_maxFileSize = (lastBlock - e->_firstBlock) * 512; + lastBlock = e->_firstBlock - 1; + } + } catch (...) { std::vector::iterator iter; + for(iter = _files.begin(); iter != _files.end(); ++iter) { if (*iter) delete *iter; @@ -155,7 +171,7 @@ VolumeEntry::VolumeEntry(Device::BlockDevice *device) throw; } - + } @@ -224,6 +240,7 @@ unsigned VolumeEntry::unlink(const char *name) { unsigned index; + // TODO -- update _maxFileSize. if (_device->readOnly()) return ProFUSE::drvrWrtProt; // WRITE-PROTECTED DISK diff --git a/apfm.cpp b/apfm.cpp index 87adbd2..2d316c2 100644 --- a/apfm.cpp +++ b/apfm.cpp @@ -15,12 +15,13 @@ #include #include +#include #include #include #include - +#include const char *MonthName(unsigned m) { @@ -101,9 +102,7 @@ void printFileEntry(Pascal::FileEntry *e, bool extended) } int action_ls(int argc, char **argv, Pascal::VolumeEntry *volume) -{ - //TODO -- check for -l flag. - +{ bool extended = false; unsigned fileCount = volume->fileCount(); unsigned used = volume->blocks(); @@ -253,6 +252,148 @@ int action_krunch(int argc, char **argv, Pascal::VolumeEntry *volume) +int action_get(int argc, char **argv, Pascal::VolumeEntry *volume) +{ + // get pascal_file [native file]; + + char *infile; + char *outfile; + + Pascal::FileEntry *entry; + + switch(argc) + { + case 1: + infile = outfile = argv[0]; + break; + case 2: + infile = argv[0]; + outfile = argv[1]; + break; + default: + std::fprintf(stderr, "apfm cat: Please specify an infile (and an optional outfile)\n"); + } + + entry = volume->fileByName(infile); + + + File::File file(outfile, O_WRONLY | O_CREAT | O_TRUNC, 0666); + + if (!entry) + { + std::fprintf(stderr, "apfm get: %s: no such file.\n", infile); + return 1; + } + + unsigned fileSize = entry->fileSize(); + unsigned offset = 0; + + while (offset < fileSize) + { + uint8_t buffer[512]; + + unsigned count = std::min(512u, fileSize - offset); + entry->read(buffer, count, offset); + + ::write(file.fd(), buffer, count); + offset += count; + } + + return 0; +} + +#if 0 +int action_put(int argc, char **argv, Pascal::VolumeEntry *volume) +{ + // put [-t type] native_file [pascal_file] + + unsigned type = Pascal::kUntypedFile; + + struct stat st; + int c; + + char *infile; + char *outfile; + char *tmp; + + while ((c = getopt(argc, argv, "t:")) != -1) + { + switch (c) + { + case 't': + if (!::strcasecmp("text", optarg)) + type = Pascal::kTextFile; + else if (!::strcasecmp("txt", optarg)) + type = Pascal::kTextFile; + else if (!::strcasecmp("code", optarg)) + type = Pascal::kCodeFile; + else if (!::strcasecmp("info", optarg)) + type = Pascal::kInfoFile; + else if (!::strcasecmp("data", optarg)) + type = Pascal::kDataFile; + else if (!::strcasecmp("graf", optarg)) + type = Pascal::kGrafFile; + else if (!::strcasecmp("foto", optarg)) + type = Pascal::kFotoFile; + else type = Pascal::kUntypedFile; + + break; + } + + } + + // TODO -- if file is named .txt or .text, default to kTextFile. + + argc -= optind; + argv += optind; + + switch (argc) + { + case 1: + infile = outfile = argv[0]; + + // need to run basename on outfile. + tmp = strrchr(outfile, '/'); + if (tmp) outfile = tmp + 1; + break; + case 2: + infile = argv[0]; + outfile = argv[1]; + break; + } + + if (!Pascal::FileEntry::ValidName(outfile)) + { + std::fprintf(stderr, "apfm put: `%s' is not a valid pascal name.\n", outfile); + } + + ::stat(infile, &st); + + File::File file(infile, O_RDONLY); + + + unsigned blocks = (st.st_size + 511) / 511; + + // TODO -- if text file, .. + + Pascal::FileEntry *entry = volume.createFile(infile, blocks); + + entry->setType(type); + + if (type == Pascal::kTextFile) + { + //... + } + else + { + // ... + + } + + return 0; + +} +#endif void usage() { @@ -370,6 +511,10 @@ int main(int argc, char **argv) if (!::strcasecmp("mv", action)) return action_mv(argc - 1, argv + 1, volume.get()); if (!::strcasecmp("rm", action)) return action_rm(argc - 1, argv + 1, volume.get()); + if (!::strcasecmp("get", action)) return action_get(argc -1, argv + 1, volume.get()); + //if (!::strcasecmp("put", action)) return action_put(argc -1, argv + 1, volume.get()); + + usage(); return 3; }