How to get a std::iostream from a file by opening it with share locking on Windows? - iostream

I am looking for a simple solution to open a file, probably using CreateFile and being sure that nobody can read/write to it and still being able to obtain a std::iostream object, which is needed later.

I think you can do the following:
#include <iostream>
#include <fstream>
fstream my_stream;
my_stream.open("my.file", std::ios_base::in | std::ios_base::out, _SH_DENYRW);
my_stream << "test";

Related

Prevent visual C++ from closing automatically

I have a new project where I created a HelloWorld.cpp Source file.
But when I am running it in Start without dedugging mode (CTRL+ F5), it opens the console and closes automatically.
#include <iostream>
#include<stdlib.h>
#ifdef _WIN32
#define WINPAUSE system("pause")
#endif
using namespace std;
void main()
{
cout << "Hello, World!" ;
}
Mr. Patel, did you try using the second solution on that linked question and then tried to use the run without debugging option? The Visual Studio will only keep the command prompt open if you set the subsystem option in the linker to console. If it is not set, the window will close as soon as the program finishes running.
At any rate, note that this will only work if you run your program from inside Visual Studio, running your .exe directly will still have it close as soon as possible. If you want your program to wait on the user, you would need to do it yourself (at least as far as I know). A very simple solution would be to write your main function like this:
int main (int argc, char* argv[]) {
...//Your code goes here.
std::cout << "Enter any character to end the program.\n";
char end;
std::cin >> end;
return(0);
}
Note that to use the cin and cout streams, you should include the iostream header in your code.

libssh/libssh.h not found on Windows 10 using gcc

I'm trying to use libssh on Windows 10 with gcc. The work is being done from the command line.
I don't know how to make libssh/ part of the search path.
The #include was libssh/libssh.h, but that failed. (The brackets were left out of this sentence.)
#include <libssh.h>
#include <stdlib.h>
int main()
{
ssh_session my_ssh_session = ssh_new();
if (my_ssh_session == NULL)
exit(-1);
...
ssh_free(my_ssh_session);
}
When I modify the include statement to be just libssh.h and use the following on the command line:
gcc -IC:\libssh\include\libssh ssh.c -oout.exe
That works to get past the libssh.h file not found.
But, the other files that are called, such as libssh/legacy.h are not found.
How do I get the libssh to be part of the search path?
I added c:\libssh\include\libssh to the environment path. That didn't work.
You need to let #include <libssh/libssh.h>
because libssh.h call a header legacy.h which is also located in the libssh folder so if you put directly the header libssh.h it won't be able to locate legacy.h
#include <libssh/libssh.h>
#include <stdlib.h>
int main()
{
ssh_session my_ssh_session = ssh_new();
if (my_ssh_session == NULL)
exit(-1);
// remove the dots it'll create an error
ssh_free(my_ssh_session);
}
to have libssh a part of the path you should do
gcc -I/path/to/libssh/include/directory -L/path/to/libssh/lib/directory -lssh ssh.c oout.exe
I also got stuck into that, now I face another issue, the one to link the libssh.dll or ssh.dll inside the compiled code to use it as stand-alone.

close() system call not removes descriptor from /proc/pid/fdinfo

Im using fanotify to track disk changes.
fanotify associates file descriptor to my process, which I need to close once Im done dealing with the event.
However, even though the close(fd) is successful, It seems that the file descriptor remains open.
Im using the man fanotify example
The close(..) returns with no errors, but looking at /proc/<pid>/fdinfo tells a different story.
Is there a way to overcome this?
Without clearing the descriptors associated with a process, a read(..) call may encounter read: Too many open files
The error Im receiving is:
EMFILE The per-process limit on the number of open files has been reached. See the description of RLIMIT_NOFILE in getrlimit(2).
I expected to test it with this sample code, but here it works OK:
#include <iostream>
#include <cstdio>
#include <string>
#include <unistd.h>
int main ()
{
close(2);
std::string line; std::getline(std::cin, line);
return 0;
}

Check if Windows file is redirected to itself

I'm trying to figure out how I can test if a file is being redirected to itself, e.g. .\command.exe file1 > file1
In the *nix world, I'd just use something like this:
// Language agnostic...
if (file_dev == out_dev && file_ino == out_ino) {
printf("%s\n", "same file!");
}
But in Windows, if I try to do this:
// This (language) is Go...
// create fileStat...
// now stat stdout
outStat, err := os.Stdout.Stat()
// error check
if os.SameFile(fileStat, outStat) {
fmt.Println("same file!")
}
...I get the IncorrectFunction error.
I read this (How to check if stdout has been redirected to NUL on Windows (a.k.a. /dev/null on Linux)?) question, and from what I gather you can't stat stdout?
This is a mostly language agnostic question -- I can translate whatever to Go (the language I'm using). I'm mostly concerned about how, using Windows' ABI (API?), I would find where stdout is being redirected to.
This answer is Windows-specific but as you've tagged windows I figure that's ok.
I can't help with Go, but in C/C++ you can do something like this:
#include <tchar.h>
#include <Windows.h>
#include <iostream>
int _tmain(int argc, _TCHAR* argv[])
{
wchar_t chPath[MAX_PATH];
if (GetFinalPathNameByHandle(GetStdHandle(STD_OUTPUT_HANDLE), chPath, MAX_PATH, 0))
std::wcout << L"stdout = " << chPath << std::endl;
else
std::cout << "stdout not redirected" << std::endl;
return 0;
}
GetFinalPathNameByHandle will fail if stdout is a console handle, but if it's been redirected to a file it will return the file path.
You can call HANDLE GetStdHandle( DWORD stdHandle ) with STD_INPUT_HANDLE and STD_OUTPUT_HANDLE to open the file handle.
Then call DWORD GetFileType( HANDLE hFile ) to check if the returned type is FILE_TYPE_DISK
Finally, call
DWORD WINAPI GetFinalPathNameByHandle( _In_ HANDLE hFile, _Out_ LPTSTR lpszFilePath, _In_ DWORD cchFilePath, _In_ DWORD dwFlags );
to obtain the file pathname and compare the names for equivalency.
Well, first up, I don't think your method in UNIX-land is actually going to protect you.
By the time your code gets to checking devices and inodes, the shell has already truncated the file. It is responsible for processing the output redirections and it does this before your program even starts, so that you're given a fresh file for your output.
I suspect you'd have the same problem in Windows in that cmd.exe will truncate your file before your script even started running.
Having said that, I believe at some point you're going to have to trust that the user knows what they're doing :-)
The other alternative is, of course, not to do output redirection but instead to require the input and output files as arguments:
cmd.exe myscipt myscript
That way, you could detect if the user was going to write to the input file (using canonicalised file names or inodes) and prevent it.
Although that still won't prevent the user from doing something silly like:
cmd.exe myscipt >myscript
blowing away your script before you get a chance to notify them they should have provided two arguments rather than one.
I think the bottom line is, if the user does output redirection, there's no way for your program to catch it before it's too late.

Redirect stdout and stderr to the output debug console of microsoft visual studio

I am using microsoft visual studio to do C++.
I don't see std::err and std::out in the output console of the IDE.
Is there a way to redirect them ?
You can indeed redirect std::out and std::err. Simply right click on your project in the solution explorer and select Properties. Then select Configuration Properties -> Debugging and put the appropriate arguments into the Command Arguments field. For example, to redirect std::err to a file, I would type in 2> ErrorLog.txt.
The things you type in Command Arguments simply get appended as command line arguments when Visual Studio runs your program, just like you had manually typed them in to the console. So, the above example simply tells VisualStudio to run your program with the command <programName>.exe 2> ErrorLog.txt instead of just <programName>.exe.
I know this is an old thread but I can't help but giving the answer since I can't believe there still is no real answer. What you can do is redirect the cout to a ostringstream of your choice. To do this, derive a new class from streambuf that will send the stream to OutputDebugString (Lets call this class OutputDebugStream) and create an instance of the class, myStream. Now call:
cout.rdbuf(&myStream)
I used cout for an example. This same technique can be used with cerr, just call
cerr.rdbuf(&myStream).
Stdout is a little more difficult if you are not using cout. You can redirect stdout during runtime by using freopen(), but it must be to a file. To get this to redirect to the Debug screen is a little more difficult. One way is to use fmemopen() if it is available (it is not standard) and write a streambuf to output this data to the Debug screen. Alternatively, you can redirect to a file and write a stream to open as input and redirect to the debug stream. A bit more work, but I think it is possible.
I use the following macro for output to the visual studio console
#ifdef _MSC_VER
#include <Windows.h>
#include <iostream>
#include <sstream>
#include <opencv/cxcore.h>
#define DBOUT( s ) \
{ \
std::wostringstream os_; \
os_ << s; \
OutputDebugStringW( os_.str().c_str() ); \
}
#else
#define DBOUT( s ) \
{ \
std::cout << s; \
}
#endif
Now if I could only get it to work within a cuda kernel?!

Resources