Notepad++ resets file permission bits for WSL files on save
-
I use npp to edit script files on Windows that I then call from within WSL (v2).
These scripts are located on Windows file system and I access them via /mnt/d/…
They also have the executable bit set (chmod +x …) to be, well, executable.
Npp is started from within Windows, not WSL.Whenever I now save a script in npp, the executable bit gets cleared. This is not the case if I use Windows’ native notepad.exe instead - but who wants to edit in notepad.exe, right?
Is there any way I can prevent npp from resetting this flag?
What is the difference in these two applications when saving files?
-
@anno73 ,
What is the difference in these two applications when saving files?
One would probably have to have the source code for MS notepad.exe to be sure… and since, unlike Notepad++, MS notepad.exe is proprietary, not open source,
Whenever I now save a script in npp, the executable bit gets cleared.
I haven’t used WSL for much of anything, but I believe you can launch Windows native commands from within WSL environment, and still have them work right. So, if you edit the same file by launching Notepad++ from WSL instead of from Windows, do the permission bits also change?
As a workaround, if you have the NppExec plugin (or are willing to install it), you could make a script for NppExec which saves the active file, then runs
chmod
on the active file, something like:cd "$(CURRENT_DIRECTORY)" NPP_SAVE chmod a+x "$(FILE_NAME)"
To make that script, run Plugins > NppExec > Execute NppExec Script… and enter those in the Commands box, then use Save… to save that script to a name – for this example,
SaveAndSetExecutableBit
. Then use Plugins > NppExec > Advanced Options, typeSave and Set Execute Bit
into the Item Name: box, and pickSaveAndSetExecutableBit
from the Associated Script dropdown, then Add/Modify to put it in the Menu Items list; while there, note whetherPlace to the Macros submenu
is checkmarked or not.After restarting Notepad++, you should be able to use Settings > Shortcut Mapper to set a keyboard shortcut for your new
SaveAndSetExecutableBit
script: if the checkmark mentioned above was checkmarked, you would use the Macros tab of the Shortcut Mapper; otherwise, the script willl be listed on the Plugin Commands tab. Either way, set your shortcut, and from now on, that shortcut will both save the file and reset its permissions. -
@anno73 said in Notepad++ resets file permission bits for WSL files on save:
Whenever I now save a script in npp, the executable bit gets cleared.
Can you confirm this?
- Start Notepad++
- From within wsl inspect the file’s permissions using
ls -l
to confirm that the x or execute bit is on. - From Notepad++ open the file - don’t make any changes. Just open it.
- From within wsl inspect the file’s permissions using
ls -l
to confirm that the x or execute bit is on. - From Notepad++ change one letter in the file. Don’t save it yet. We just want the Notepad++ tab for the file to now be red.
- From within wsl inspect the file’s permissions using
ls -l
to confirm that the x or execute bit is on. - From Notepad++ do
Ctrl+S
to save the file. Don’t close the tab yet. - From within wsl inspect the file’s permissions using
ls -l
to confirm that the x or execute bit is on. - From Notepad++ do
Ctrl+W
to close the tab. - From within wsl inspect the file’s permissions using
ls -l
to confirm that the x or execute bit is on. - From Notepad++ do
ALT+F4
to close/exit Notepad++ - From within wsl inspect the file’s permissions using
ls -l
to confirm that the x or execute bit is on.
Did the x or execute bit get turned off anywhere in those steps? If so, what step?
What is the difference in these two applications when saving files?
There should be no difference that makes a difference…
When you save a file from Microsoft Notepad the application does:
- CreateFile with Desired Access: Generic Read/Write, Disposition: OpenIf, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: N, ShareMode: Read, AllocationSize: 0, OpenResult: Opened
- WriteFile Offset: 0, Length: 349, Priority: Normal
- SetEndOfFileInformationFile EndOfFile: 349
- SetAllocationInformationFile AllocationSize: 349
- CloseFile
When you save a file from Notepad++ the application does:
- CreateFile Desired Access: Generic Read/Write, Disposition: Open, Options: Synchronous IO Non-Alert, Non-Directory File, Attributes: N, ShareMode: Read, Write, AllocationSize: n/a, OpenResult: Opened
- SetAllocationInformationFile AllocationSize: 0
- WriteFile Offset: 0, Length: 368, Priority: Normal
- FlushBuffersFile
- WriteFile Offset: 0, Length: 4,096, I/O Flags: Non-cached, Paging I/O, Synchronous Paging I/O, Priority: Normal
- CloseFile
While there are differences in those details I would be I would be surprised that the operations performed by Notepad++ cause the x or execute flag to be cleared. Maybe it’s the
SetAllocationInformationFile AllocationSize: 0
which resets the file to zero size prior to writing the data. I have always been puzzled by that 4,096 byte write Notepad++ does at the end. It ends up doing nothing.Notepad++ has always used Microsoft’s C Runtime (CRT) library for file I/O. The CRT provides an environment that looks and behaves very much like Unix which it maps into Windows API calls. Microsoft Notepad does not use the CRT and instead uses direct Windows API calls. Thus, if it turns out that something that the CRT does such as that
SetAllocationInformationFile AllocationSize: 0
then it’s something that Notepad++ has little to no control over without a rewrite of Notepad++'s file I/O code to use the Windows API rather than the CRT. -
Anyone else reading this topic not knowing what WSL means?
WSL = Windows Subsystem for Linux
I don’t know how great of a reference this is, but I found some info about it HERE.
-
I also use npp to edit shell scripts from wsl, and that doesn’t seem to happen for me.
The difference in my workflow is that I edit the scripts via the network share\\wsl$\Ubuntu...
my config
wsl --version WSL version: 2.3.24.0 Kernel version: 5.15.153.1-2 WSLg version: 1.0.65 MSRDC version: 1.2.5620 Direct3D version: 1.611.1-81528511 DXCore version: 10.0.26100.1-240331-1435.ge-release Windows version: 10.0.26100.1742
terminal from wsl
user@...:~$ pwd /home/user user@...:~$ touch test.sh user@...:~$ chmod +x test.sh user@...:~$ ls -l test.sh -rwxr-xr-x 1 user user 0 Oct 25 15:04 test.sh user@...:~$ ls -l test.sh -rwxr-xr-x 1 user user 12 Oct 25 15:04 test.sh user@...:~$ ./test.sh hello user@...:~$
-
@anno73 said in Notepad++ resets file permission bits for WSL files on save:
I use npp to edit script files on Windows that I then call from within WSL
Generally - do not change Linux files using Windows apps directly, use rather the @Ekopalypse way instead:
@Ekopalypse said in Notepad++ resets file permission bits for WSL files on save:
I edit the scripts via the network share \wsl$\Ubuntu…
Windows file metadata (timestamps, permissions, ownership…) != *nix ones!
WSL is the translation layer here…@anno73 said in Notepad++ resets file permission bits for WSL files on save:
Whenever I now save a script in npp, the executable bit gets cleared. This is not the case if I use Windows’ native notepad.exe instead
Hmm, there is a possibility that it is a N++ fault, I will try to check it later.
N++ for some complicated reason (long story short - the file-storage in heterogeneous systems/networks is a real Hell!) can use the WINAPI disposition parameter CREATE_ALWAYS under certain circumstances, which I suspect could be the culprit here, as it then effectively creates a completely new file instead of editing the original one (where you set that executable-bit before). In your case this should not happen (the TRUNCATE_EXISTING should be used instead) but who knows, this needs your STR debugging.
@mkupper said in Notepad++ resets file permission bits for WSL files on save:
Notepad++ has always used Microsoft’s C Runtime (CRT) library for file I/O.
This partially does not apply to file-writing from the v8.1.6+. N++ has been forced to start using the CreateFile WINAPI (to overcome severe Windows caching issues leading to possible data loss when Windows forcibly restarts or crashes). See e.g. here.
@Alan-Kilborn said in Notepad++ resets file permission bits for WSL files on save:
Anyone else reading this topic not knowing what WSL means?
A good start for usage and installation is described here.
-
Thanks all for thoughts and suggestions. One thing I mentioned in my question seems to have been overlooked:
- These scripts are located on Windows file system and I access them via /mnt/d/…
WSL allows to mount regular windows drives to /mnt/c, /mnt/d, … :
$ mount | grep -e "/mnt/[cd]" C:\ on /mnt/c type 9p (rw,noatime,dirsync,aname=drvfs;path=C:\;uid=1000;gid=1000;umask=22;fmask=111;metadata;case=off;symlinkroot=/mnt/,mmap,access=client,msize=65536,trans=fd,rfd=3,wfd=3) D:\ on /mnt/d type 9p (rw,noatime,dirsync,aname=drvfs;path=D:\;uid=1000;gid=1000;umask=22;fmask=111;metadata;case=off;symlinkroot=/mnt/,mmap,access=client,msize=65536,trans=fd,rfd=3,wfd=3)
So, no need for \wsl$… really to access these files. They reside somewhere blow D:… in my case here.
And I start these scripts from within wsl. (/mnt/d/…/myscript.sh)
Maybe this helps for better understanding and problem solving. Maybe the API calls npp uses to access files mangels with the attributes set from within wsl as @mkupper already mentioned.
-
@mkupper said in Notepad++ resets file permission bits for WSL files on save:
@anno73 said in Notepad++ resets file permission bits for WSL files on save:
Whenever I now save a script in npp, the executable bit gets cleared.
Can you confirm this?
- Start Notepad++
- From within wsl inspect the file’s permissions using
ls -l
to confirm that the x or execute bit is on.
$ cd /mnt/d $ echo Hello > test.sh $ ls -l test.sh -rw-r--r-- 1 u g 6 Nov 6 13:56 test.sh $ chmod +x test.sh $ ls -l test.sh -rwxr-xr-x 1 u g 6 Nov 6 13:56 test.sh*
- From Notepad++ open the file - don’t make any changes. Just open it.
- From within wsl inspect the file’s permissions using
ls -l
to confirm that the x or execute bit is on.
$ ls -l test.sh -rwxr-xr-x 1 u g 6 Nov 6 13:56 test.sh*
- From Notepad++ change one letter in the file. Don’t save it yet. We just want the Notepad++ tab for the file to now be red.
- From within wsl inspect the file’s permissions using
ls -l
to confirm that the x or execute bit is on.
$ ls -l test.sh -rwxr-xr-x 1 u g 6 Nov 6 14:05 test.sh*
- From Notepad++ do
Ctrl+S
to save the file. Don’t close the tab yet. - From within wsl inspect the file’s permissions using
ls -l
to confirm that the x or execute bit is on.
$ ls -l test.sh -rw-r--r-- 1 u g 7 Nov 6 14:10 test.sh
- From Notepad++ do
Ctrl+W
to close the tab. - From within wsl inspect the file’s permissions using
ls -l
to confirm that the x or execute bit is on.
$ ls -l test.sh -rw-r--r-- 1 u g 7 Nov 6 14:10 test.sh
- From Notepad++ do
ALT+F4
to close/exit Notepad++ - From within wsl inspect the file’s permissions using
ls -l
to confirm that the x or execute bit is on.
$ ls -l test.sh -rw-r--r-- 1 u g 7 Nov 6 14:10 test.sh
Did the x or execute bit get turned off anywhere in those steps? If so, what step?
Following directions from above, the executable bits were removed upon save.
I also tried to edit the file via opening
\\wsl$\Debian\d\test.sh
in npp, but this got prevented by a windows access denied error to mountpoint directory d.When editing
\\wsl$\Debian\home\user\test.sh
the executable bits are not reset. -
Out of curiosity, I also tried VSCode. The bits did not change upon save. The script stayed executable.
-
Thanks for the details and the
ls -l
test. Now I see where the problem is (probably - I did not have time to setup a WSL test & debug that in N++ yet).The problem is really in what I already stated (a possibility that N++ uses in this case incorrectly the
CREATE_ALWAYS
file saving disposition parameter somehow instead of theTRUNCATE
one). My mistake was in the wrong assumption, how the storage of such WSL Linux permissions is implemented on the Windows side in NTFS - I thought it would be the NTFS Alternate Data Streams (this is already covered in the N++ file saving code) but it is implemented via the Extended Attributes (ref.).So the fix should be easy - adding one more pre-check for the
FILE_ATTRIBUTE_EA
. I will see what I can do but please be patient, nowadays I have almost no free time…