Symbolic Links

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
pgimeno
Party member
Posts: 3581
Joined: Sun Oct 18, 2015 2:58 pm

Symbolic Links

Post by pgimeno »

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:

Code: Select all

mkdir clean_test
cd clean_test
mkdir lib
> lib/init.lua
echo 'require "Lib"' > main.lua
ln -s lib Lib
Running 'love .' fails:

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'
Note that the line I've marked with *** is false. The file exists. Running strace gives us a hint of what's going on:

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...]
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:

Code: Select all

echo 'require "Lib.init"' > main.lua
$ ~/apps/love/versions/love-0.9.2 .
[ normal black window - no error ]
$ 
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:

Code: Select all

lovelink.sh:
#!/bin/sh
if [ -f "$1"/init.lua" ] ; then ln -s "$1"/init.lua "$2".lua
ln -s "$1" "$2"
to make two symlinks, e.g. in the above example lib/init.lua as Lib.lua and lib as Lib
Last edited by pgimeno on Wed Dec 02, 2015 10:37 pm, edited 1 time in total.
User avatar
slime
Solid Snayke
Posts: 3142
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Symbolic Links

Post by slime »

LÖVE [wiki]0.9.2[/wiki] supports symlinks, but you have to explicitly enable them via [wiki]love.filesystem.setSymlinksEnabled[/wiki]. They will be enabled by default in [wiki]0.10.0[/wiki].
User avatar
pgimeno
Party member
Posts: 3581
Joined: Sun Oct 18, 2015 2:58 pm

Re: Symbolic Links

Post by pgimeno »

Thanks. Since it's an option controlled by the programmer, I take it that it's a safety, rather than a security, measure (as in protecting programmers against themselves, rather than protecting users against potentially malicious software). The use of 'security' in the wording of that report confused me.
User avatar
slime
Solid Snayke
Posts: 3142
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: Symbolic Links

Post by slime »

Opinions also change during a 5 year period. ;)
bobbyjones
Party member
Posts: 730
Joined: Sat Apr 26, 2014 7:46 pm

Re: Symbolic Links

Post by bobbyjones »

Yeah if you look through all the old forum posts or issues they mention security a lot. Even to the point of them desiring to remove the standard io library and some users actually made a fork that has even more sandboxing and security. But I think the security thing died out.
Post Reply

Who is online

Users browsing this forum: No registered users and 6 guests