Hi,
I have two class side extensions to CfsDirectoryDescriptor, one I wrote a while ago and one I just added that I would like to share here. The first makes all the directories in a given path. The second removes all the files in a directory and sub-directories (including files in sub-directories) then removes the directory. I have used both on Windows but I don't see any reason why they wouldn't work on UNIX or Linux.
I hope they are of use to someone and if Instantiations wants to put them in the base code, that's fine with me.
Lou
makePath: aPath
"Make all the directories in the path."
"Answer the path if it already existed or we were able to create it."
"Answer a CfsError if there were any other problems (see mkdir:)."
| aPathParts pathPart result |
(aPath size < 4) ifTrue: [^(CfsError new) errno: EINVAL]. "Don't allow nil, non or very short strings."
aPathParts := aPath subStrings: self pathSeparator.
(aPathParts size < 2) ifTrue: [^(CfsError new) errno: EINVAL]. "We need at least a drive letter and folder name."
pathPart := aPathParts first, self pathSeparatorString. "Start with the drive letter."
aPathParts from: 2 to: aPathParts size do: [:folderName |
pathPart := pathPart, folderName, self pathSeparatorString. "Build the path up with each folder name."
result := self mkdir: pathPart. "Try to make the folder."
(result isCfsError and: [result errno ~= EEXIST]) ifTrue: [^result]. "It's okay if it was already there."
].
^aPath. "If we get here the folders were made or were there already."
emptyAndRemoveDir: path
"Remove all files and sub-directories (including files in sub-directories) then remove the directory."
"Answer any CfsError encountered along the way or whatever #rmdir: answers."
| dStream dEntry tempPath tempName recursiveResult |
(path isNil or: [path isEmpty]) ifTrue: [^nil].
tempPath := (path last = self pathSeparator) ifTrue: [path] ifFalse: [path, self pathSeparatorString].
dStream := CfsDirectoryDescriptor opendir: tempPath pattern: nil mode: (FREG + FDIR).
dStream isCfsError ifTrue: [^dStream].
[
dEntry := recursiveResult isCfsError ifTrue: [] ifFalse: [dStream readdir].
dEntry notNil & dEntry isCfsError not & recursiveResult isCfsError not.
] whileTrue: [
tempName := tempPath, dEntry dName.
dEntry isReg ifTrue: [CfsFileDescriptor remove: tempName].
(dEntry isDir and: [(dEntry dName ~= '.') & (dEntry dName ~= '..')]) ifTrue: [recursiveResult := self emptyAndRemoveDir: tempName].
].
dStream closedir.
dEntry isCfsError ifTrue: [^dEntry].
recursiveResult isCfsError ifTrue: [^recursiveResult].
^self rmdir: path.
P.S. I miss the way we could post code in the old forum.