[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Library bindings or os.execute?
- From: Sean Conner <sean@...>
- Date: Wed, 14 Jun 2017 02:35:38 -0400
It was thus said that the Great Dirk Laurie once stated:
> I find, increasingly often, that on my Linux system I no longer bother
> looking whether someone has written a library with Lua bindings
> for some sophisticated standard library [1]. Instead, I do it with
> os.execute.
>
> This sounds quick-and-dirty, but I wonder whether in the long run,
> it might not be more portable and require less maintenance.
>
> -- Dirk
>
> [1] For example, suppose I have ripped a CD into a disk image.
> There is a huge binary file sitting there that in principle you could
> edit, play etc. The `sox` utility seems intent on supporting the tiniest
> obscure feature. Sure, reading the manpage for `sox` is hard work,
> but reading the documentation for `libsox` is a damn sight harder.
> So I write a Lua frontend that simply assembles the command lines
> for the editing/playback calls.
Several years ago, I starting writing a program to index all the files on
my computer (a Linux system). Part of this indexing involved classifying
the type of file and for that, Linux came with a program called 'file' that
does that. It supported the option "-f" to read filenames from stdin and it
would write the file type (I used the "-i" option to print out mime types).
So my thought was: I can invoke "file", feeding it filenames in stdin,
and reading the file types on stdout. Only issue was: popen() (and by
extension, io.popen() but this was before I got into Lua) only supports
reading or writing (but not both). I was trying to avoid having to generate
a list prior (1,499,996 entries---probably more now) to generating the
types.
"Not a problem," thought I. "I wrote a Unix shell as a college project,
I know how to execute a program with redirection." And so I did a
bi-directional "popen()" function---
---which failed miserably.
Turns out the standard C library only defaults to line buffering if
stdin/stdout is an actual TTY, not a pipe. For a pipe (or a file) it does
full buffering. I solved the issue I had (not the problem---there is a
difference) using some runtime dynanamic linker tricks (LD_PRELOAD mumble
mumble) to get the line buffering and it worked.
The *real* solution was to use the magic library and avoid the hack
solution. Thus this:
local fsys = require "org.conman.fsys"
local magic = require "org.conman.fsys.magic"
magic:flags('mime')
for entry in fsys.dir() do
print(magic(entry),entry)
end
will run in reasonable time for a large directory (and not chew up CPU time
continuously spawning a program or heaven forbid attempt that horrible
hack mentioned above).
-spc (Who thinks that executables should also be shared libraries ... )