lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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 ... )