Symbolic Links
Posted: Wed Dec 02, 2015 9:50 pm
I'm trying to use symbolic links under Linux to avoid duplicating entire trees with libraries, or to make quick workarounds for case sensitivity problems in some love programs.
But they are behaving weird.
Say we have an empty init.lua in directory 'lib', and a main.lua that requires 'Lib', and then we symlink lib to Lib:
Running 'love .' fails:
Note that the line I've marked with *** is false. The file exists. Running strace gives us a hint of what's going on:
The lines I've marked again as *** seem to find that it's not a directory but a symbolic link, and then init.lua is not searched there for some reason.
However, this works:
I was going to report the failure of the first example in Bitbucket, but then I found this: https://bitbucket.org/rude/love/issues/ ... olic-links
It is closed as wontfix, on security grounds. I would understand if symbolic links inside .love files were not being followed (if they are possible at all), but not in the actual filesystem, since that hinders development. I would cite Benjamin Franklin on freedom and safety, but the fact that the second case is working suggests that this is not intentional, and now I am confused.
Which is it?
EDIT: For the record, this solves my immediate problem, though it's an ugly workaround:
to make two symlinks, e.g. in the above example lib/init.lua as Lib.lua and lib as Lib
But they are behaving weird.
Say we have an empty init.lua in directory 'lib', and a main.lua that requires 'Lib', and then we symlink lib to Lib:
Code: Select all
mkdir clean_test
cd clean_test
mkdir lib
> lib/init.lua
echo 'require "Lib"' > main.lua
ln -s lib Lib
Code: Select all
$ ~/apps/love/versions/love-0.9.2 .
Error: main.lua:1: module 'Lib' not found:
no field package.preload['Lib']
no file 'Lib.lua' in LOVE game directories.
*** no file 'Lib/init.lua' in LOVE game directories.
no file 'Lib.so' in LOVE paths.
no file './Lib.lua'
no file '/usr/share/luajit-2.0.3/Lib.lua'
no file '/usr/local/share/lua/5.1/Lib.lua'
no file '/usr/local/share/lua/5.1/Lib/init.lua'
no file '/usr/share/lua/5.1/Lib.lua'
no file '/usr/share/lua/5.1/Lib/init.lua'
no file './Lib.so'
no file '/usr/local/lib/lua/5.1/Lib.so'
no file '/usr/lib/i386-linux-gnu/lua/5.1/Lib.so'
no file '/usr/local/lib/lua/5.1/loadall.so'
stack traceback:
[C]: in function 'require'
main.lua:1: in main chunk
[C]: in function 'require'
[string "boot.lua"]:374: in function <[string "boot.lua"]:244>
[C]: in function 'xpcall'
Code: Select all
[...snipped...]
lstat64("/clean_test/main.lua", {st_mode=S_IFREG|0664, st_size=14, ...}) = 0
lstat64("/clean_test/main.lua", {st_mode=S_IFREG|0664, st_size=14, ...}) = 0
lstat64("/clean_test/main.lua", {st_mode=S_IFREG|0664, st_size=14, ...}) = 0
open("/clean_test/main.lua", O_RDONLY) = 16
fstat64(16, {st_mode=S_IFREG|0664, st_size=14, ...}) = 0
lseek(16, 0, SEEK_CUR) = 0
fstat64(16, {st_mode=S_IFREG|0664, st_size=14, ...}) = 0
read(16, "require \"Lib\"\n", 14) = 14
fsync(16) = 0
close(16) = 0
lstat64("/clean_test/Lib.lua", 0xbfd35e48) = -1 ENOENT (No such file or directory)
lstat64("/clean_test/Lib.lua", 0xbfd35e98) = -1 ENOENT (No such file or directory)
*** lstat64("/clean_test/Lib", {st_mode=S_IFLNK|0777, st_size=3, ...}) = 0
*** lstat64("/clean_test/Lib", {st_mode=S_IFLNK|0777, st_size=3, ...}) = 0
open("/home/pgimeno/.local/share//love/Lib.so", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory)
open("./Lib.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/share/luajit-2.0.3/Lib.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/local/share/lua/5.1/Lib.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/local/share/lua/5.1/Lib/init.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
open("/usr/share/lua/5.1/Lib.lua", O_RDONLY|O_LARGEFILE) = -1 ENOENT (No such file or directory)
[...snipped...]
However, this works:
Code: Select all
echo 'require "Lib.init"' > main.lua
$ ~/apps/love/versions/love-0.9.2 .
[ normal black window - no error ]
$
It is closed as wontfix, on security grounds. I would understand if symbolic links inside .love files were not being followed (if they are possible at all), but not in the actual filesystem, since that hinders development. I would cite Benjamin Franklin on freedom and safety, but the fact that the second case is working suggests that this is not intentional, and now I am confused.
Which is it?
EDIT: For the record, this solves my immediate problem, though it's an ugly workaround:
Code: Select all
lovelink.sh:
#!/bin/sh
if [ -f "$1"/init.lua" ] ; then ln -s "$1"/init.lua "$2".lua
ln -s "$1" "$2"