reading (not writing) last_write_time gives a file creation error - c++

I'm stumped... it took me a while to track this down.. because I don't have visual C++ IDE installed on the problematic system (it is windows server 2019)... my code works fine with VS 2022 on my laptop (W11 22H2)... anyhow.. I get this exception
Cannot create a file when that file already exists
I tracked it down to this code:
const auto fileTime = fs::last_write_time(p);
apparently this function can also write to the file to modify the time.
but I'm just trying to read it... (I didn't add the arguments necessary to write)
does anyone have any idea why this error might be happening?
https://en.cppreference.com/w/cpp/filesystem/last_write_time
please note it is highly likely that sometimes the file is actually being written to when I call this code (this code is called in a loop, and so is the file that is being written by another program)

Related

Error with std::filesystem::copy copying a file to another pre-existing directory

See below for the following code, and below that, the error that follows.
std::string source = "C:\\Users\\cambarchian\\Documents\\tested";
std::string destination = "C:\\Users\\cambarchian\\Documents\\tester";
std::filesystem::path sourcepath = source;
std::filesystem::path destpath = destination;
std::filesystem::copy_options::update_existing;
std::filesystem::copy(sourcepath, destpath);
terminate called after throwing an instance of 'std::filesystem::__cxx11::filesystem_error'
what(): filesystem error: cannot copy: File exists [C:\Users\cambarchian\Documents\tested] [C:\Users\cambarchian\Documents\tester]
Tried to use filesystem::copy, along with trying different paths. No luck with anything. Not too much I can write here as the problem is listed above, could be a simple formatting issue. That being said, it worked on my home computer using visual studio 2022, however using VS Code with gcc 11.2 gives me this issue.
Using:
filesystem::copy_file(oldPath, newPath, filesystem::copy_options::overwrite_existing);
The overloads of std::filesystem::copy are documented. You're using the first overload, but want the second:
void copy(from, to) which is equivalent to [overload 2, below] using copy_options::none
void copy(from, to, options)
Writing the statement std::filesystem::copy_options::update_existing; before calling copy doesn't achieve anything at all, whereas passing the option to the correct overload like
std::filesystem::copy(sourcepath, destpath,
std::filesystem::copy_options::update_existing);
should do what you want.
... it worked on my home computer using visual studio 2022 ...
you don't say whether the destination file existed in that case, which is the first thing you should check.
I put the copy_options within the copy function but it didn't work so I started moving it around, I probably should have mentioned that.
Randomly permuting your code isn't a good way of generating clean examples for others to help with.
In the rare event that hacking away at something does fix it, I strongly recommend pausing to figure out why. When you've hacked away at something and it still doesn't work, by all means leave comments to remind yourself what you tried, but the code itself should still be in a good state.
Still doesn't work when I write std::filesystem::copy(sourcepath, destpath, std::filesystem::copy_options::recursive)
Well, that's a different option, isn't it? Were you randomly permuting which copy_options you selected as well?
Trying recursive and update_existing yields the same issue.
The documentation says
The behavior is undefined if there is more than one option in any of the copy_options option group present in options (even in the copy_file group).
so you shouldn't be setting both anyway. There's no benefit to recursively copying a single file, but there may be a benefit to updating or overwriting one. If the destination already exists. Which, according to your error, it does.
Since you do have an error explicitly saying "File exists", you should certainly look at the "options controlling copy_file() when the file already exists" section of the table here.
Visual Studio 2022 fixed the problem

Deleted file still reported as existing (Windows only)

(Note that this is not primarily a Qt question)
It seems to me that the return value of QFile::exists() is sometimes incorrect.
Consider the following two unit-test-like snippets (each of which I have executed a few thousand times in a loop)
// create file
QFile file("test.tmp");
QVERIFY(file.open(QIODevice::WriteOnly));
QVERIFY(file.write("some data") != -1);
file.close();
// delete file
QVERIFY(file.remove());
// assert file is gone
QVERIFY(!file.exists()); // <-- 5..10 % chance of failure
and
// create file
QFile file("test.tmp");
QVERIFY(file.open(QIODevice::WriteOnly));
QVERIFY(file.write("some data") != -1);
file.close();
// delete file
QVERIFY(file.remove());
// retry until file is gone (or until timeout)
for (auto i = 0; i < 10; i++)
{
if (!file.exists()) // <-- note that only the check is retried, not the actual delete
return;
QThread::yieldCurrentThread();
}
QFAIL("file is still reported as existing"); // <-- never reached in my tests
The first unit test fails about 8 out of 100 times. Always on the last line of code (indicating that the file still exists). The second unit test never fails.
This behavior was observed on a Windows 10 system using NTFS (with Qt 5.2.1). It could not be reproduced using ubuntu 16.04 LTS using ext4 on a VM (with Qt 5.8.0)
Not sure if this helps:
Process Monitor (when it succeeds)
Process Monitor (when it fails)
So my questions are:
what is happening?
what are implications that I might be interested in?
update:
For clarification: I am hoping for an answer like "this is caused by the NTFS feature 'bills-fancy-caching-magic'". From there I would like to find out, whether Qt does look over this feature intentionally.
According to the Windows API documentation, it is defined behaviour:
The DeleteFile function marks a file for deletion on close. Therefore, the file deletion does not occur until the last handle to the file is closed. Subsequent calls to CreateFile to open the file fail with ERROR_ACCESS_DENIED.
It seems to be a property of the Windows kernel and therefore not to be limited to NTFS.
The behaviour seems to be unpredictable, as other services (think virus scanners) might open the file in question.

Running the executable of hdl_simple_viewer.cpp from Point Cloud Library

The Point Cloud library comes with an executable pcl_hdl_viewer_simple that I can run (./pcl_hdl_viewer_simple) without any extra arguments to get live data from a Velodyne LIDAR HDL32.
The source code for this program is supposed to be hdl_viewer_simple.cpp. A simplified version of the code is given on this page which cannot be compiled readily and requires a tiny bit of tweaking to make it compile.
My problem is that the executable that I build myself for both the versions are not able to run. I always get the smart pointer error "Assertion px!=0" error. I am not sure if I am not executing the program in the correct way or what. The executable is supposed to be executed like
./hdl_viewer_simple -calibrationFile hdl32calib.xml -pcapFile file.pcap
in case of playing from previously recorded PCAP files or just ./hdl_viewer_simple if wanting to get live data from the real sensor. However, I always get the assertion failed error.
Has anyone been able to run the executables? I do not want to use the ROS drivers
"Assertion px!=0" is occurring because your pointer is not initialized.
Now that being said, you could initialize it inside your routines, in case the pointer is NULL, especially for data input.
in here, you can try updating the line 83 like this :
CloudConstPtr cloud(new Cloud); //initializing your pointer
and hopefully, it will work.
Cheers,

C++ Write to file not working in my addition to an existing application

I have an application that collects heart rate data and displays in in a GUI. I don't want to change anything about how the application runs, but want to save the data into a .csv file to use with data manipulation programs. The program is called BluetoothGattHeartRate. I am running the sample code found here.
My addition to the code is just
std::fstream theDump;
theDump.open("path/to/file", std::fstream::out);
if (theDump.is_open())
{
theDump.write("ImHere", 6);
}
theDump.close();
inserted into the file called HeartRateService.cpp in the Shared directory in the void HeartRateService::Characteristic_ValueChanged(GattCharacteristic^ sender, GattValueChangedEventArgs^ args) function just before the call to ValueChangeCompleted(heartRateValue);. I'm using Microsoft Visual Studio to edit and run the code, as the tutorial online says. This exact code succeeds in editing the file when run in an independent application, but it fails to open the file (I tested for this) when run in the Gatt sample code.
I don't expect that anyone has dealt with this before, but if by some miracle one of you has figured this out, please let me know how you fixed it.

Strange semantic error

I have reinstalled emacs 24.2.50 on a new linux host and started a new dotEmacs config based on magnars emacs configuration. Since I have used CEDET to some success in my previous workflow I started configuring it. However, there is some strange behaviour whenever I load a C++ source file.
[This Part Is Solved]
As expected, semantic parses all included files (and during the initial setup parses all files specified by the semantic-add-system-include variables), but it prints this an error message that goes like this:
WARNING: semantic-find-file-noselect called for /usr/include/c++/4.7/vector while in set-auto-mode for /usr/include/c++/4.7/vector. You should call the responsible function into 'mode-local-init-hook'.
In the above example the error is printed for the STL vector but a corresponding error message is printed for every file included by the one I'm visiting and any subsequent includes. As a result it takes quite a long time to finish and unfortunately the process is repeated any type I open a new buffer.
[This Problem Is Solved Too]
Furthermore it looks like the parsing doesn't really work as when I place the point above a non-c primitive type (i.e. not int,double,float, etc) instead of printing the type's definition in the modeline an error message like
Idle Service Error semantic-idle-local-symbol-highlight-idle-function: "#<buffer DEPFETResolutionAnalysis.cc> - Wrong type argument: stringp, (((0) \"IndexMap\"))"
Idle Service Error semantic-idle-summary-idle-function: "#<buffer DEPFETResolutionAnalysis.cc> - Wrong type argument: stringp, ((\"fXBetween\" 0 nil nil))"
where DEPFETResolutionAnalysis.cc is the file & buffer I'm currently editing and IndexMap and fXBetween are types defined in files included by the file I'm editing/some file included by the file I'm editing.
I have not tested any further features of CEDET/semantic as the problem is pretty annoying. My cedet config can be found here.
EDIT: With the help of Alex Ott I kinda solved the first problem. It was due to my horrible cedet initialisation. See his first answer for the proper way to configure CEDET!
There still remains the problem with the Idle Service Error (which, when enabling global-semantic-idle-local-symbol-highlight-mode, occurs permanently, not only when checking the definition of the type at point).
And there is the new problem of how to disable the site-wise init file(s).
EDIT2: I have executed semantic-debug-idle-function in a buffer where the problem occurs and it produces a ~700kb [sic!] output. It looks like it is performing some operations on a data container which, by the looks of it, contains information on all the symbols defined in the files parsed. As I have parsed a rather large package (~20Mb source files) this table is rather large. Can semantic handle a database that large or is this impossible and the reason of my problem?
EDIT3: Deleting the content of ~/.semanticdb and reparsing all includes did the trick. I still need to disable the site-wise init files but as this is not related to CEDET I will close this question (the question related to the site-wise init files can be found here).
You need to change your init file so it will perform loading of CEDET only once, not in the hook that will be called for each .h/.hpp/.c/.cpp files. You can change this config as the base, and read more in following article.
The problem that you have is caused because Semantic is trying to analyze header files, and when it tries to open them, then its initialization routines are called again, and again...
The first problem was solved by correctly configuring CEDET which is discribed on Alex Ott's homepage. His answer solves this first problem. The config file specified in his answer is a great start for a nice config; I have used the very same to config CEDET for my needs.
The second problem vanished once I updated CEDET from 1.1 to the bazaar (repository) version, which is explained here and in Alex' article. Additionaly one must delete the content of the directory ~/.semanticdb (which contains the semantic database and was corrupted I guess).
I'd like to thank Alex Ott for his help and sticking with me throughout my journey to the solution :)