How to open file for writing in shared mode in Perl - perl

I would like to open file in shared mode for editing (other processes must have access to that file for writing as well) under Windows OS. Is it possible in Perl?
For example, in WinApi there is a possibility to specify flag FILE_SHARE_WRITE in CreateFile() function.
Thank you!

Multiple processes writing to the same file is a bad situation. An example would be a database scenario where a table must be locked by a processes in order to changes to be written to the table reliably. You could write something that does nothing else but listen to the other processes to write to the file.
perlmonks suggest using flock
Here's the link. Hope this helps!

Related

How to check if a file is already being used (open) using perl. If so,forcefully close it using perl

I am in a situation where I need to check if a file, say Test.xls is already opened. If the file is opened, I want my perl to forcefully close it with/without saving changes.
If not opened, my perl will create a new file and carry on with its execution.
Any inputs to it ?
You can be creative!
For the functionally you can realize on two ways.
The popular first: a flat textfile, where the state of opened file(s) is notified.
Second is the same, but just as array in RAM. It's faster, while direct acessable state improves your realtime experience. If system reboots no file is opened and will not fail from popular way. There will left the flatfile after reboot, which is on last state.
Maybe you're looking for a combinition both ways, its your choice!
So you're autonom from operating system.

Force overwrite or delete file in use (executable that currently runs)

I'm looking for solution to delete or (preferably directly) overwrite source of an exe file while it is running.
To explain further before you get it all wrong, I'll give an example:
I have an exe file on drive D:\ which I run (with previously posted question's answer, giving params to "Start in" folder on C:\Program Files\MyProgram\" so it finds its dlls.
Now after the file is running, I'd like to rewrite the file's byte stream (just like opening it in hex editor...), or at least delete it so I can copy over new exe file directly using same name.
So far the solution I'm using is that I trigger format D: command for the whole drive D:\ (which, in my case is ramdisk and thumb-drive, as I only have this exe on it, I copy it there as necessary), since that removes the file and let's me copy new file there.
Trying to use del myProgram.exe even with -force flag triggers error that access to the file is denied. Same goes if I try to overwrite the contents of the file.
Is there any alternative to do that without using the format command, as that requires to have partition drive only for the purpose?
Update: Note: MoveFileEx and similar techniques that require termination of the process or system restart/reboot are not qualified as a solution. This should be done while the process is running without further actions that can compromise the process's run state.
On a side note, when formatting the drive using the Powershell's format command, the file is gone, although if viewing the partition using Hex viewer tool, there is full binary (hex) content of the exe visible there and an be restored using just as simple as copy-paste technique. This is one of the points as to where overwriting the file contents would be preferable than deleting the file directly.
Please note: This is a knowledge and skills based question, and would therefore appreciate sparing the moral and security-concerning comments about such actions and behaviour.
For deleting/replacing/overwriting a file at least two conditions must be met:
The user performing the operation must have the required permissions to do so. This can be verified for instance via Get-Acl or icacls.
Windows must not have an open handle to the file. This can be checked for instance with tools like Process Explorer or handle. These tools can also be used to forcibly close open handles, although that's not recommended as it may cause data loss and/or damage to the files in question. I'm not sure, though, if it's actually possible to close handles to an executable without terminating the process.
Note that antivirus software is likely to interfere with this kind of operation.
The basic problem here is that Windows loads from the .EXE upon demand, it's not all read in at once.
If you destroy the original file what happens when it tries to load in a page that no longer exists?
If I had to write something of this sort I would copy the .exe to a temporary location (beware that running code from the temp directory may be prohibited), run the new .exe, terminate the old one and then do what I want to it.

use matlab to open a file with an outside program and execute 'save as'

Alright, here's what I'm dealing with (you can skip to TLDR if all you need to see is what I want to run):
I'm having an issue with file formatting for a nasty conglomeration of several ancient programs I've strung together. I have some data in .CSV format, and I need to put it into .SPC format. I've tried a set of proprietary MATLAB programs called 'GS tools' for fast and easy conversion, but fast and easy doesn't look like its gonna happen here since there are discrepancies in how .spc files are organized now and how they were organized back when my ancient programs were written.
If I could find the source code for the old programs I could probably alter the GS tools code to write my .spc files appropriately, but all I can find are broken links circa 2002 and earlier. Seeing as I don't know what my programs are looking for, I have no choice but to try resaving my data with other programs until one of them produces something workable.
I found my Cinderella program: if I open the data I have in a program called Spekwin and save the file with a .spc extension... viola! Everything else runs on those files. The problem is that I have hundreds of these files and I'd like to automate the conversion process.
I either need to extract the writing rubric Spekwin uses for .spc files (I believe that info is stored in a dll file within the program, but I'm not sure if that actually makes sense) and use it as a rule to write a file from my input data, or I need a piece of code that will open a file with Spekwin, tell Spekwin to save that file under the .spc extension, and terminate Spekwin.
TLDR: Need a command that tells the computer to open a file with a certain program, save that file under a different extension through that program (essentially open*.csv>save as>*.spc), then terminate the program.
OR--I need a way to tell MATLAB to write a file according to rules specified by a .dll, but I'm not sure I fully understand what that entails.
Of course I'm open to suggestions on other ways to handle this.

Write lock on a yaml file?

This post explains how to put file write lock on regular files.
But is it possible to put a lock on a yaml file, so only one script at a time can write to it?
I am using YAML::Syck, if that makes a difference.
You can lock a file using flock. You'll need to open the file first as flock operates on filehandles.
Alternatively you can use LockFile::Simple from CPAN.
As others have said, use flock. Also, see perlfaq5 under "How can I lock a file".
It's important to note that it's advisory locking anyway, so there is no need to actually lock the .yaml file. You can just lock a lock file (maybe yourfile.yaml.lock) and unlock it when done.
This also gives you the capability to say "this block of operations requires exclusive access", rather than just limit your exclusivity to a single file.

What's the best way to do a cross-platform, atomic file replacement in Perl?

I have a very common situation. I have a file, and I need to entirely overwrite that file with new contents. However, the original file is accessed on every page load (this is a web app), so it can't be missing for very long. A few ms is OK (though not ideal), a second is not OK.
Right now I do this by writing a temp file to the same directory and then renaming that temp file to the name of the new file. I'm just using the normal File::Temp and "rename" to do this, in Perl. I was wondering--is there some other recommended/better way to do this? Preferably one that doesn't require a CPAN module, as this is the only place in my system that I need to do this, and I don't want a whole new dependency just for this.
Oh, and all of this has to work on Windows, Linux, BSD, OS X, Solaris, and most other common platforms.
Here is the code in question, for those interested.
Your method seems just fine. It's quick, it's atomic, it uses core modules only, and File::Temp is a safe way to deal with temporary files. What more do you need?
I'd do it the same way you're doing it. At least on Unix-type OSes, a file rename is guaranteed to be atomic so you won't have any instants where either the original or the new files isn't there.
Rename is sufficient. However:
Is your temporary file at risk for race conditions? The filename should be randomized so nobody can cause problems by inserting their own file. Use an interface to mkstemp() if possible.