Saving failes when relative pathnames used on command line

• Dec 12, 2016 - 12:24
Reported version
S4 - Minor

Starting MuseScore like 'musescore path/to/file.mscx' makes it fail to save; an strace shows it tries to access 'path/to/path/to/file.mscx' intermittently. Starting it with the full path ('musescore /home/foo/path/to/file') succeeds.

lasconic suggested in IRC to resolve pathnames from the command line to their absolute paths early. (Just take care to not break symlinks.)


Status (old) needs info active
Status needs info active

This still happens with 2.1 on GNU (Debian GNU/Linux sid/x32):

tglase@tglase:~ $ strace -e file -o foo musescore mbsd/mirsol/music/free/Abendlied.mscx
QStandardPaths: XDG_RUNTIME_DIR not set, defaulting to '/tmp/runtime-tglase'
Qt: XKEYBOARD extension not present on the X server.
130|tglase@tglase:~ $ fgrep Abendlied foo
execve("/usr/bin/musescore", ["musescore", "mbsd/mirsol/music/free/Abendlied"...], [/* 45 vars */]) = 0
stat("/home/tglase/mbsd/mirsol/music/free/Abendlied.mscx", {st_mode=S_IFREG|0644, st_size=223839, ...}) = 0
open("mbsd/mirsol/music/free/Abendlied.mscx", O_RDONLY|O_CLOEXEC) = 19
stat("mbsd/mirsol/music/free/Abendlied.mscx", {st_mode=S_IFREG|0644, st_size=223839, ...}) = 0
access("mbsd/mirsol/music/free/Abendlied.mscx", W_OK) = 0
open("mbsd/mirsol/music/free/Abendlied.mscx.temp", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 19
stat("mbsd/mirsol/music/free/.Abendlied.mscx,", 0xffd4f3f0) = -1 ENOENT (No such file or directory)
stat("mbsd/mirsol/music/free/mbsd/mirsol/music/free/Abendlied.mscx", 0xffd4f3f0) = -1 ENOENT (No such file or directory)
lstat("mbsd/mirsol/music/free/Abendlied.mscx.temp", {st_mode=S_IFREG|0644, st_size=223839, ...}) = 0
stat("mbsd/mirsol/music/free/Abendlied.mscx", {st_mode=S_IFREG|0644, st_size=223839, ...}) = 0

See the path doubling in the stat call. Screenshot also attached, of the situation where I pressed ^C.

Attachment Size
bla.png 160.83 KB

Could be this in libmscore/scorefile.cpp:

416                       if (!dir.rename(name, backupName)) {

“name” is the complete relative path, and if the renaming is attempted relative to “dir”, which could be inside the directory, it would match the strace output. Unfortunately, strace in Debian is not compiled with libunwind, and gdb is not very helpful either:

(gdb) print dir->dirName()
Cannot resolve method QDir::dirName to any overloaded instance

My C++-fu is not strong enough for this.

I would guess that {targetdirectory}.rename({absolutepath}, {basename}) works because it’s an absolute path in the first argument, which doesn’t get the path of targetdirectory prepended, while a relative one does.