diff options
Diffstat (limited to 'plugins/coro-fs')
-rw-r--r-- | plugins/coro-fs/LICENSE | 22 | ||||
-rw-r--r-- | plugins/coro-fs/README.md | 2 | ||||
-rw-r--r-- | plugins/coro-fs/init.lua | 222 |
3 files changed, 246 insertions, 0 deletions
diff --git a/plugins/coro-fs/LICENSE b/plugins/coro-fs/LICENSE new file mode 100644 index 00000000000..5789b767285 --- /dev/null +++ b/plugins/coro-fs/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 Tim Caswell + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/plugins/coro-fs/README.md b/plugins/coro-fs/README.md new file mode 100644 index 00000000000..79ef57330a0 --- /dev/null +++ b/plugins/coro-fs/README.md @@ -0,0 +1,2 @@ +# luv-coro-fs +A luv port of lit's coro-fs module diff --git a/plugins/coro-fs/init.lua b/plugins/coro-fs/init.lua new file mode 100644 index 00000000000..f4be5bff832 --- /dev/null +++ b/plugins/coro-fs/init.lua @@ -0,0 +1,222 @@ +local exports = {} +exports.name = "creationix/coro-fs" +exports.version = "1.3.0" +exports.homepage = "https://github.com/luvit/lit/blob/master/deps/coro-fs.lua" +exports.description = "A coro style interface to the filesystem." +exports.tags = {"coro", "fs"} +exports.license = "MIT" +exports.author = { name = "Tim Caswell" } + +local uv = require('luv') +local fs = exports +local pathJoin = require('path').join + +local function noop() end + +local function makeCallback() + local thread = coroutine.running() + return function (err, value, ...) + if err then + assert(coroutine.resume(thread, nil, err)) + else + assert(coroutine.resume(thread, value == nil and true or value, ...)) + end + end +end + +function fs.mkdir(path, mode) + uv.fs_mkdir(path, mode or 511, makeCallback()) + return coroutine.yield() +end +function fs.open(path, flags, mode) + uv.fs_open(path, flags or "r", mode or 438, makeCallback()) + return coroutine.yield() +end +function fs.unlink(path) + uv.fs_unlink(path, makeCallback()) + return coroutine.yield() +end +function fs.stat(path) + uv.fs_stat(path, makeCallback()) + return coroutine.yield() +end +function fs.lstat(path) + uv.fs_lstat(path, makeCallback()) + return coroutine.yield() +end +function fs.symlink(target, path) + uv.fs_symlink(target, path, makeCallback()) + return coroutine.yield() +end +function fs.readlink(path) + uv.fs_readlink(path, makeCallback()) + return coroutine.yield() +end +function fs.fstat(fd) + uv.fs_fstat(fd, makeCallback()) + return coroutine.yield() +end +function fs.chmod(fd, path) + uv.fs_chmod(fd, path, makeCallback()) + return coroutine.yield() +end +function fs.fchmod(fd, mode) + uv.fs_fchmod(fd, mode, makeCallback()) + return coroutine.yield() +end +function fs.read(fd, length, offset) + uv.fs_read(fd, length or 1024*48, offset or -1, makeCallback()) + return coroutine.yield() +end +function fs.write(fd, data, offset) + uv.fs_write(fd, data, offset or -1, makeCallback()) + return coroutine.yield() +end +function fs.close(fd) + uv.fs_close(fd, makeCallback()) + return coroutine.yield() +end +function fs.access(path, flags) + uv.fs_access(path, flags or "", makeCallback()) + return coroutine.yield() +end +function fs.rename(path, newPath) + uv.fs_rename(path, newPath, makeCallback()) + return coroutine.yield() +end +function fs.rmdir(path) + uv.fs_rmdir(path, makeCallback()) + return coroutine.yield() +end +function fs.rmrf(path) + local success, err + success, err = fs.rmdir(path) + if success then return success end + if err:match("^ENOTDIR:") then return fs.unlink(path) end + if not err:match("^ENOTEMPTY:") then return success, err end + for entry in assert(fs.scandir(path)) do + local subPath = pathJoin(path, entry.name) + if entry.type == "directory" then + success, err = fs.rmrf(pathJoin(path, entry.name)) + else + success, err = fs.unlink(subPath) + end + if not success then return success, err end + end + return fs.rmdir(path) +end +function fs.scandir(path) + uv.fs_scandir(path, makeCallback()) + local req, err = coroutine.yield() + if not req then return nil, err end + return function () + return uv.fs_scandir_next(req) + end +end + +function fs.readFile(path) + local fd, stat, data, err + fd, err = fs.open(path) + if err then return nil, err end + stat, err = fs.fstat(fd) + if stat then + data, err = fs.read(fd, stat.size) + end + uv.fs_close(fd, noop) + return data, err +end + +function fs.writeFile(path, data, mkdir) + local fd, success, err + fd, err = fs.open(path, "w") + if err then + if mkdir and string.match(err, "^ENOENT:") then + success, err = fs.mkdirp(pathJoin(path, "..")) + if success then return fs.writeFile(path, data) end + end + return nil, err + end + success, err = fs.write(fd, data) + uv.fs_close(fd, noop) + return success, err +end + +function fs.mkdirp(path, mode) + local success, err = fs.mkdir(path, mode) + if success or string.match(err, "^EEXIST") then + return true + end + if string.match(err, "^ENOENT:") then + success, err = fs.mkdirp(pathJoin(path, ".."), mode) + if not success then return nil, err end + return fs.mkdir(path, mode) + end + return nil, err +end + +function fs.chroot(base) + local chroot = { + base = base, + fstat = fs.fstat, + fchmod = fs.fchmod, + read = fs.read, + write = fs.write, + close = fs.close, + } + local function resolve(path) + assert(path, "path missing") + return pathJoin(base, pathJoin(path)) + end + function chroot.mkdir(path, mode) + return fs.mkdir(resolve(path), mode) + end + function chroot.mkdirp(path, mode) + return fs.mkdirp(resolve(path), mode) + end + function chroot.open(path, flags, mode) + return fs.open(resolve(path), flags, mode) + end + function chroot.unlink(path) + return fs.unlink(resolve(path)) + end + function chroot.stat(path) + return fs.stat(resolve(path)) + end + function chroot.lstat(path) + return fs.lstat(resolve(path)) + end + function chroot.symlink(target, path) + -- TODO: should we resolve absolute target paths or treat it as opaque data? + return fs.symlink(target, resolve(path)) + end + function chroot.readlink(path) + return fs.readlink(resolve(path)) + end + function chroot.chmod(path, mode) + return fs.chmod(resolve(path), mode) + end + function chroot.access(path, flags) + return fs.access(resolve(path), flags) + end + function chroot.rename(path, newPath) + return fs.rename(resolve(path), resolve(newPath)) + end + function chroot.rmdir(path) + return fs.rmdir(resolve(path)) + end + function chroot.rmrf(path) + return fs.rmrf(resolve(path)) + end + function chroot.scandir(path, iter) + return fs.scandir(resolve(path), iter) + end + function chroot.readFile(path) + return fs.readFile(resolve(path)) + end + function chroot.writeFile(path, data, mkdir) + return fs.writeFile(resolve(path), data, mkdir) + end + return chroot +end + +return exports |