Created
December 7, 2011 20:16
-
-
Save dvv/1444440 to your computer and use it in GitHub Desktop.
failing fibers
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env luvit | |
| local Fiber = require('fiber') | |
| local Fs = require('fs') | |
| local Path = require('path') | |
| -- | |
| -- mimicks find | |
| -- | |
| local function find(path, match_fn, callback) | |
| path = Path.normalize(path) | |
| Fiber.new(function(resume, wait) | |
| local err, files | |
| -- match | |
| match_fn(path) | |
| -- read sub-files, if any | |
| Fs.readdir(path, resume) | |
| err, files = wait() | |
| -- read error -> bail out | |
| if err then | |
| -- ENOTDIR: current path is not directory. reset error and proceed | |
| -- ENOENT: e.g. broken symlink | |
| if err.code == 'ENOTDIR' or err.code == 'ENOENT' then | |
| err = nil | |
| end | |
| callback(err) | |
| return | |
| end | |
| -- recursively iterate thru files | |
| local i, file | |
| for i, file in ipairs(files) do | |
| -- FIXME: this is very dumb way to cope with self-pointing symlinks | |
| if #path > 255 then | |
| debug('TRIMMED', path) | |
| else | |
| find(Path.join(path, file), match_fn, resume) | |
| -- bail out on any error | |
| err = wait() | |
| if (err) then break end | |
| end | |
| end | |
| callback(err) | |
| end) | |
| end | |
| find('/home', function(path, stat) | |
| --debug('MATCH?', path) | |
| end, function(err) | |
| debug('DONE', err) | |
| end) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| local remove = require('table').remove | |
| local normalize = Path.normalize | |
| local inos = {} | |
| local function find(path, match_fn, callback) | |
| assert(type(path) == 'string') | |
| assert(type(match_fn) == 'function') | |
| assert(type(callback) == 'function') | |
| path = normalize(path) | |
| Fiber.new(function(resume, wait) | |
| local err, stat, files | |
| -- stat resolving symlinks | |
| Fs.stat(path, resume) | |
| err, stat = wait() | |
| -- stat failed -> bail out | |
| if err then | |
| callback(err) | |
| return | |
| end | |
| if stat and stat.ino and inos[stat.ino] then | |
| p('SEEN', path, inos[stat.ino]) | |
| inos[stat.ino] = inos[stat.ino] + 1 | |
| callback() | |
| return | |
| end | |
| if stat and stat.ino then | |
| inos[stat.ino] = 1 | |
| end | |
| -- match | |
| match_fn(path, stat) | |
| -- path is not directory? | |
| if not stat.is_directory then | |
| callback() | |
| return | |
| end | |
| -- path is directory. read files | |
| Fs.readdir(path, resume) | |
| err, files = wait() | |
| -- read error -> bail out | |
| if err then | |
| callback(err) | |
| return | |
| end | |
| -- recursively iterate thru files | |
| while #files do | |
| local file = remove(files) | |
| find(Path.join(path, file), match_fn, resume) | |
| -- bail out on any error | |
| err = wait() | |
| --if (err) then break end | |
| end | |
| callback(err) | |
| end) | |
| end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment