Skip to content

Instantly share code, notes, and snippets.

@frangio
Last active October 8, 2015 20:53
Show Gist options
  • Save frangio/9b8945b7dc509f33ecea to your computer and use it in GitHub Desktop.
Save frangio/9b8945b7dc509f33ecea to your computer and use it in GitHub Desktop.
LTN12 wrappers for POSIX read and write.

Because they use the Lua io interface, the built in ltn12.source.file and ltn12.sink.file inherit C's stdio.h semantics.

This may not be desirable, for example, if the source is stdin connected to an interactive stream where we want to process chunks as soon as possible, and we wish to avoid buffering (stdin:setvbuf('no')). In this case ltn12.source.file(stdin) will block until exactly ltn12.BLOCKSIZE bytes (usually 2048) are read from the stream. ltn12_posix.source(0) will instead return a chunk as soon as one is available for reading, however many bytes it may be, as per POSIX read semantics.

local ltn12 = require('ltn12')
local ltn12_posix = require('ltn12-posix')
local fcntl = require('posix.fcntl')

-- copy a file
ltn12.pump.all(
  ltn12_posix.source(fcntl.open('original.png', 'r')),
  ltn12_posix.sink(fcntl.open('copy.png', 'w'))
)
local unistd = require('posix.unistd')
local ltn12 = require('ltn12')
local _M = {}
-- creates a source from a file descriptor
function _M.source(fd, err)
if fd then
return function ()
local chunk = unistd.read(fd, ltn12.BLOCKSIZE) -- [TODO] stat(fd).st_blksize?
if not chunk or chunk == '' then
err = select(2, unistd.close(fd))
end
return chunk, err
end
else
return ltn12.source.error(err or 'unable to open file')
end
end
-- creates a sink from a file descriptor
function _M.sink(fd, err)
if fd then
return function (chunk, err)
if not chunk then
return unistd.close(fd)
else
return unistd.write(fd, chunk)
end
end
else
return ltn12.sink.error(err or 'unable to open file')
end
end
return _M
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment