Open Temp File filename.mscz.temp Failed: Permission denied

• Feb 22, 2022 - 02:51

I've been having trouble with the "Save" on Musescore giving me a permission denied error: "Open Temp File filename.mscz.temp Failed: Permission denied"

To provide some debugging information, I opened Musescore 3.6.2-3 (Manjaro package) in strace, (filtered to only some relevant system calls) changed one note in my score, and hit "Save".

$ strace musescore Morenica.mscz 2>&1 | egrep 'Morenica|chdir'
execve("/usr/bin/musescore", ["musescore", "Morenica.mscz"], 0x7ffd5378f1f8 /* 67 vars */) = 0
access("/home/kabloom/sheetmusic/Morenica.mscz", F_OK) = 0
readlink("/home/kabloom/sheetmusic/Morenica.mscz", 0x7ffdcf856670, 1023) = -1 EINVAL (Invalid argument)
openat(AT_FDCWD, "Morenica.mscz", O_RDONLY|O_CLOEXEC) = 41
openat(AT_FDCWD, "Morenica.mscz", O_RDONLY|O_CLOEXEC) = 42
statx(AT_FDCWD, "Morenica.mscz", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0644, stx_size=19354, ...}) = 0
access("Morenica.mscz", W_OK)           = 0
chdir("/usr/bin")                       = 0
openat(AT_FDCWD, "Morenica.mscz.temp", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = -1 EACCES (Permission denied)

The chdir call is occurring as part of Musescore's startup process, so if I open Musescore this way, and close Musescore without trying to save anything, the chdir call is still a part of the trace.


Comments

In reply to by Ken Bloom

Here's what I do get from the strace --follow-forks, however the AppImage terminates before showing the application window when I do that.

$ strace  --follow-forks -D ~/Applications/MuseScore-3.6.2.548021370-x86_64_461d9f78f967c0640433c95ccb200785.AppImage Morenica.mscz 2>&1 | egrep 'Morenica|chdir'
execve("/home/kabloom/Applications/MuseScore-3.6.2.548021370-x86_64_461d9f78f967c0640433c95ccb200785.AppImage", ["/home/kabloom/Applications/MuseS"..., "Morenica.mscz"], 0x7ffec8b279d8 /* 67 vars */) = 0
[pid 46024] execve("/usr/lib/appimagelauncher/binfmt-bypass", ["/usr/lib/appimagelauncher/binfmt"..., "/home/kabloom/Applications/MuseS"..., "Morenica.mscz"], 0x55adeae43000 /* 68 vars */ 
[pid 46045] execveat(3, "", ["/home/kabloom/Applications/MuseS"..., "Morenica.mscz"], 0x55e63a7ac1e0 /* 70 vars */, AT_EMPTY_PATH) = 0
[pid 46047] chdir("/")                  = 0
[pid 46047] chdir("/tmp/.mount_MuseSc8y7A3b") = 0
[pid 46048] chdir("/")                  = 0
[pid 46048] chdir("/tmp/.mount_MuseSc8y7A3b") = 0

I think the error is caused by your sheetmusic folder being a symlink instead of a real folder.
During saving MuseScore indeed uses a temporary file, but it is supposed to be saved in the location extracted from the current file, so it can be saved right next to it.

For some reason (I suspect thus the sheetmusic or even the kabloom folders being not real folders) the retrieved file location for your opened file is empty. (Qt.FileInfo::filePath())
When then the new filehandle is being constructed it is only provided the retrieved empty path + the temp filename, which is considered a relative path to the current executable directory; hence the chdir you're seeing.

This perhaps might be fixable by using Qt.FileInfo::canonicalPath() instead, but I'm not familiar enough with the possible caveats this function then might bring as well.
Since no further updated for 3.x are planned, it would be nice if you could verify whether this is resolved in 4.0 once that Alpha has been released.

In reply to by Jojo-Schmitz

Nope.. I got thrown off scent by the readlink call in that trace; but looking at the man page reveals that the return code indicates that it indeed is not a symlink.

So there's another issue at play here as to why the temporary file is being created in the usr/bin folder rather than next to the existing file.

@OP: What is shown in File → Score Properties as the file path for your opened file?

In reply to by Ken Bloom

That "initially read from" path is what is causing the troubles.

(You can't edit the chdir out of MuseScore because it's not part of MuseScore's own code, but of the Qt libraries that do the cross-platform file handling for us).

So your workarounds seem to be:
A.) launch via commandline, use the full file path.
B.) Use "File > Open" from within MuseScore instead.

In reply to by Jojo-Schmitz

No part of the path to that file is a symlink.

I tried again, passing the absolute path to Morenica.mscz on the command-line, and the save succeded. So one fix for this issue is to resolve the filename given on the command-line into an absolute path early in the loading process, using QFileInfo::absoluteFilePath(). This has to happen before the chdir.

The other solution would be to find and eliminate the chdir("/usr/bin") call.

$ strace musescore $(pwd)/Morenica.mscz 2>&1 | egrep 'Morenica|chdir'
access("/home/kabloom/sheetmusic/Morenica.mscz", F_OK) = 0
readlink("/home/kabloom/sheetmusic/Morenica.mscz", 0x7ffdaa8a56b0, 1023) = -1 EINVAL (Invalid argument)
openat(AT_FDCWD, "/home/kabloom/sheetmusic/Morenica.mscz", O_RDONLY|O_CLOEXEC) = 40
openat(AT_FDCWD, "/home/kabloom/sheetmusic/Morenica.mscz", O_RDONLY|O_CLOEXEC) = 41
statx(AT_FDCWD, "/home/kabloom/sheetmusic/Morenica.mscz", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0644, stx_size=19353, ...}) = 0
access("/home/kabloom/sheetmusic/Morenica.mscz", W_OK) = 0
chdir("/usr/bin")                       = 0
openat(AT_FDCWD, "/home/kabloom/sheetmusic/Morenica.mscz.temp", O_WRONLY|O_CREAT|O_TRUNC|O_CLOEXEC, 0666) = 41
access("/home/kabloom/sheetmusic/.mscbackup/.Morenica.mscz,", F_OK) = 0
unlink("/home/kabloom/sheetmusic/.mscbackup/.Morenica.mscz,") = 0
access("/home/kabloom/sheetmusic/.Morenica.mscz,", F_OK) = -1 ENOENT (No such file or directory)
access("/home/kabloom/sheetmusic/Morenica.mscz", F_OK) = 0
statx(AT_FDCWD, "/home/kabloom/sheetmusic/Morenica.mscz", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0644, stx_size=19353, ...}) = 0
newfstatat(AT_FDCWD, "/home/kabloom/sheetmusic/.mscbackup/.Morenica.mscz,", 0x7ffdaa8a42b0, 0) = -1 ENOENT (No such file or directory)
renameat2(AT_FDCWD, "/home/kabloom/sheetmusic/Morenica.mscz", AT_FDCWD, "/home/kabloom/sheetmusic/.mscbackup/.Morenica.mscz,", RENAME_NOREPLACE) = 0
statx(AT_FDCWD, "/home/kabloom/sheetmusic/Morenica.mscz.temp", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW|AT_NO_AUTOMOUNT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0644, stx_size=19302, ...}) = 0
newfstatat(AT_FDCWD, "/home/kabloom/sheetmusic/Morenica.mscz", 0x7ffdaa8a42b0, 0) = -1 ENOENT (No such file or directory)
renameat2(AT_FDCWD, "/home/kabloom/sheetmusic/Morenica.mscz.temp", AT_FDCWD, "/home/kabloom/sheetmusic/Morenica.mscz", RENAME_NOREPLACE) = 0
chmod("/home/kabloom/sheetmusic/Morenica.mscz", 0644) = 0
access("/home/kabloom/sheetmusic/Morenica.mscz", F_OK) = 0

In reply to by jeetee

You mean something like this?

diff --git a/libmscore/scorefile.cpp b/libmscore/scorefile.cpp
index fd8c3f42cf..c23702b810 100644
--- a/libmscore/scorefile.cpp
+++ b/libmscore/scorefile.cpp
@@ -401,7 +401,7 @@ bool MasterScore::saveFile(bool generateBackup)
       // the original file in case of "disc full"
       //
 
-      QString tempName = info.filePath() + QString(".temp");
+      QString tempName = info.canonicalPath() + QString(".temp");
       QFile temp(tempName);
       if (!temp.open(QIODevice::WriteOnly)) {
             MScore::lastError = tr("Open Temp File\n%1\nfailed: %2").arg(tempName, strerror(errno));

Do you still have an unanswered question? Please log in first to post your question.