I'm using this piece of code to delete a file on demand
{
...
fs.access(path, (err)=> err || fs.unlink(path));
...
}
I got this error
Error: ENOENT: no such file or directory, unlink 'C:\ ... '
at Error (native)
Which makes no sense to me as I literally just checked for the files existence before attempting the unlink - I have a feeling something weird's going on behind the scenes like file locking.
How do I rectify this error?
Also, do I need to lock the file myself before I attempt to delete, to guarantee a robust and safe delete. I won't be there to manually delete the file and restart the server every time a user tries to delete their file.
calling fs.access before write or delete is not recommended. Please check the below link
https://nodejs.org/api/fs.html#fs_fs_access_path_mode_callback
Using fs.access() to check for the accessibility of a file before calling fs.open(), fs.readFile() or fs.writeFile() is not recommended. Doing so introduces a race condition, since other processes may change the file's state between the two calls. Instead, user code should open/read/write the file directly and handle the error raised if the file is not accessible.
Related
Is there a way to open a directory and create it if doesn't exist atomically ?
My use case is simple, I use a directory to watch every public key that are allowed to connect to my server, but if the directory doesn't exist I want to create it, unfortunately for now I only see a two step solution, create the path with create_dir_all() and then open it with read_dir() but this create a possible situation where the directory is delete between the two calls (very unlucky in my docker container... but anyway !)
I didn't find any solution in linux to do that and I'm quite surprise cause that a very common operation for file.
I found a related question Create a directory and return a dirfd with `open` but it's focus on file descriptor and so is more specific. The answer seem to say this doesn't prevent race condition, I don't really understand the context, my only concern is to avoid to create the directory and than try to open it and it's fail. It's more for convenience and robustness of code.
this is a very specific question
I'm mainly interested in the open() system calls the happen when running touch ..
So I ran strace touch . and saw that opennat() is called three times.
but I'm not really understanding whats going on; as touch . does not print anything in the console and does not create a new file named "." since "." is a pointer to the current folder and can be seen by running ls -a so nothing is created since that name is already in use.
this is my assumption:
open() is called to check if the specified file name already exits, if a file descriptor is returned this means that the name is already in use and the operation is canceled.
please correct me if I'm wrong.
GNU touch prefers to use a file descriptor when touching files, since it's possible to write touch - > foo and expect the file foo to be touched. As a result, it always tries to open the specified path as a writable file, and if that's possible, it then uses that file descriptor to update the file timestamp.
In this case, it's not possible to open . for writing, so openat returns EISDIR. touch notices that it's a directory, so its call to its internal fdutimensat function gets an invalid file descriptor and falls back to using utimensat instead of futimens.
It isn't the case that the openat call is used to check that the file exists, but instead that using a file descriptor for many operations means that you don't have to deal with path resolution multiple times or handle symlinks, since all of those are resolved when the file descriptor is opened. This is why many long-lived programs choose to open a file descriptor to their current working directory, then change directories, and then use the file descriptor with fchdir to change back. Any pchanges to permissions after the program starts are not a problem.
As I review these file system flags, I'm I correct in concluding that there is no flag you can pass to fs.promises.writeFile that will automatically create all missing directories leading up to a filename? If not, which flag does this?
I don't like solutions that check for the existence of the folders first before attempting writeFile, because after the folders are created that check happens every time you write to a file in that folder.
In my program, after the folders are created once, it should always be there, so it seems more efficient to only create the folders if there is an exception. However, I'm hoping there is a flag that avoids all this micro-management.
If a flag for auto-creating the folders doesn't exist for writeFile, then I'd like to attempt writeFile first, and then (only if there is an exception) create the folders recursively.
fs.promises.writeFile() does not automatically create the directory structure for you. That must exist first.
If you want to automatically create the path because you received an error indicative of a path problem, you can use fs.promises.mkdir() and pass the recursive flag.
And you could, of course, create your own wrapper function that calls fs.promises.writeFile() and if it gets whatever error you get when the path doesn't exist (you'd have to test to see exactly what that error is), then call fs.promises.mkdir() and then repeat the fs.promises.writeFile(). It could all be wrapped in your own utility function.
I am trying to customize cifsfs module for my own use case, one of the case I need to open a file and read its content in the cifs_unlink() call, I am using filp_open() to open it, read it then filp_close() it, then continue with the normal code path of unlink(), I could get the content just fine.
Problem is, the filp_close() call will hold off the smb request until I am out of the unlink() function, so the unlink smb request will arrive earlier than the close(), and it triggers 0xc0000043 NT_STATUS_SHARING_VIOLATION, then the unlink will fail with device busy.
tried to call cifs_close() instead of the filp_close(), same result.
Wondering how I can synchronously close() a file to avoid this failure.
I want to create a temporary file/directory in node.js. To do this, I'm attempting a simple algorithm:
Generate a file name based on pid, time, and random chars
Check if file exists
if yes: return to step 1 and repeat
if not: create the file and return it
Here's the problem: The node.js documentation for fs.exists explicitly states that fs.exists should not be used, and instead one should just use fs.open and catch a potential error:
http://nodejs.org/docs/latest/api/fs.html#fs_fs_exists_path_callback
In my case, I am not interested in opening the file if it exists, I am strictly trying to find a filename that does not yet exist. Is there a way I can go about this that does not use fs.exists? Alternatively, if I do use fs.exists, should I be worried that this method will become deprecated in the future?
Use fs.open with the 'wx' flags instead so that you'll create the file if it doesn't exist, and return an error if it already exists.
That way you eliminate the (albeit minute) possibility that the file is created between a fs.exists check and an fs.open call to create the file.