is it possible to turn pipes genereated via pipe() on a POSIX-system into std::istreams and std::ostreams?
if yes, how?
i would prefer to use << and >> instead of read() and write()
thanks in advance
There are non-standard constructors which take file descriptor number or FILE*. See http://gcc.gnu.org/onlinedocs/libstdc++/libstdc++-api-4.5/a00074.html#a777faeb6849444b4663d1cbe543e1ae3
Check out http://www.netbsd.org/~jmmv/process/ and http://www.highscore.de/boost/process/
EDIT http://svn.boost.org/svn/boost/sandbox/process/
I forget which one hosts the latest source, but it's a very good cross-platform IPC library with support for pipes.
It's not actually part of boost but they want (or wanted) it to be.
Related
How can I deny access to a file I open with fstream? I want to unable access to the file while I'm reading/writing to it with fstream?
You cannot do it with the standard fstream, you'll have to use platform specific functions.
On Windows, you can use CreateFile() or LockFileEx(). On Linux, there is flock(), lockf(), and fcntl() (as the previous commenter said).
If you are using MSVC, you can pass a third parameter to fstream's constructor. See the documentation for Visual Studio 6 or newer versions. Of course it won't work with other compilers and platforms.
Why do you want to lock others out anyway? There might be a better solution...
Expanding on the comment by Casebash:
To open a file in windows so that other processes cannot write to it use
file.rdbuf()->open(path, std::ios_base::app, _SH_DENYWR);
_SH_DENYRW will deny both read and write access
There is no way to do this in native C++, as it would be highly platform dependent. On Linux/UNIX, you can do this with flock or fcntl. I'm not really sure how to do it on Windows.
On windows, it looks like you have to pass some flags to CreatFile or use LockFileEx (which allows byte range locking).
Note that, all of these methods work on the underlying OS file descriptors/handles, not with fstreams. You will either need to use the Posix or Windows API to read/write from the file, or wrap the file descriptor/handle in an fstream. This is platform dependent again. I'm sure there is a way to do it, but I don't remember it off the top of my head.
I have an API which has a function that accepts an AsyncWriteStream as defined here:
http://www.boost.org/doc/libs/1_39_0/doc/html/boost_asio/reference/AsyncWriteStream.html
This is currently used (and works) to stream data to a tcp socket, using:
http://www.boost.org/doc/libs/1_41_0/doc/html/boost_asio/reference/basic_stream_socket.html
My question is that can this interface also be used to stream to a file on disk. I suspect the answer is yes but I would like to know how much effort is required and especially if there are existing implementations that support the interface.
So, to reiterate. The API function looks like:
template <class AsyncWriteStream>
void stream_read(AsyncWriteStream &stream, completion_callback CB) { ...
Internally the API writes data to AsyncWriteStream using boost::asio::async_write. I want AsyncWriteStream to then be able to stream to both tcp and file socket. Perhaps my question could also be phrased "can a basic_stream_socket be created that streams to disk instead of tcp?"
I need this to work on both Windows and Linux.
This is perhaps a duplicate. From the answers given here: Whats the deal with boost.asio and file i/o?:
For Windows use: windows::random_access_handle and manage the offset. (Note that windows::stream_handle does not support eof, see: C++ boost asio Windows file handle async_read_until infinite loop - no eof).
For Linux, open the file and then use posix::stream_descriptor. (Note that asio does not support epoll for file io, define BOOST_ASIO_DISABLE_EPOLL)
Both of the above appear to support the AsyncWriteStream interface, although I've still to test.
Is there a way to use the unix 'time' command in C++ and store each of its outputs in a variable?
EDIT: If there isn't a way, then what about calling time in a bash script and storing the returned values some way?
Thank you!
Supposing you are on UNIX, then the C++ standard std::system function will behave as defined in POSIX, that is, execute a command as with sh. Before doing this, you can connect your own stdin and stdout to a local pipe by first using dup to create aliases of STDIN_FILENO and STDOUT_FILENO, then close the aforementioned file descriptors, then pipe to open a pipe on the newly freed descriptors.
Then you can interact with std::cin and std::cout. Well, it would be a good idea to flush the C++ interface before beginning.
This isn't all really a good idea, though. It should be simpler to use the POSIX C interface to get the relevant data directly.
If you are ok with using Boost libraries, then this should do it http://www.boost.org/doc/libs/1_49_0/doc/html/date_time/examples.html#date_time.examples.seconds_since_epoch
the good part is it also handles time zones conversions :)
You can use system(3) or popen(3), but there's almost always a better, more portable, and native solution, depending on what exactly you're looking for. In your specific case it seems like what you're really looking for a combination of getrusage(2) and ftime(3).
I have a requirement for reading, updating and deleting a file. I want to write a class for this.
For example
class FileManagement {
private:
fstream myFile;
public:
void read();
void update();
void delete();
};
My question is while updating is it possible to delete only one line in a file in C++ and should be portable, if it is possible how we can achieve this.
Other question is if above option is not possible how we can achieve the above.
In C++ how we can delete a file in portable way.
Thanks!
Use standard C/C++ functions fopen(), fread(), fwrite(), rename() and remove() for that. http://www.cplusplus.com/reference/clibrary/cstdio/
I recommend Boost Filesystem.
Its description reads:
"The Boost Filesystem Library provides portable facilities to query and manipulate paths, files, and directories."
You appear to be asking two different questions at once, in a confusing way.
To delete a file, use the remove function, found in stdio.h.
To erase one line of a file, you have to read the entire file and write it back out with the line removed. There is no library routine for this. The standard "safe" technique is to read the entire file, write it back out (with the line you don't want removed) to a new file in the same directory, fsync the new file, close it, then rename the new file to the old name. If you don't care about concurrent readers or the computer crashing in the middle of the operation, you can instead open the old file read/write, read its contents into memory, rewind the file handle, and rewrite it directly.
You should look at the posix standard, and find the file operations (like fopen()). Where platforms do not support posix, or diverge from the standard, you'll likely need to
#ifdef NONPOSIXOS1 // really, this should be a good identifier of hte OS
// write code to handle the special case
#else
// write code to handle the posix compliant case
#endif
Most systems will accept posix compliant statements. You could always just define abstract base class and create different concrete implementations that use whatever platform specific instructions you need. You could have one if def that instantiates the correct concrete class.
If you are looking for a higher-level C++ library that is object-oriented and can handle both filename manipulation and file I/O, POCO is a decent choice:
http://pocoproject.org
ACE is an older, battle-tested framework that includes lots of I/O support. It's commonly used for it's excellent CORBA support, but there's a lot in there:
http://www.cs.wustl.edu/~schmidt/ACE-overview.html
And, finally, there's QT. Normally known for its cross-platform UI library, QT actually includes several other useful pieces (including file management and I/O), and you don't even have to link in the UI stuff if you don't need it.
http://qt.nokia.com/
If you'd rather not bring in another framework, I would recommend rolling your own File I/O classes using boost::filesystem and either the standard iostream or stdio functions. You can use the interfaces in the above frameworks as a reference, but you will also want to familiarize yourself with modern C++ design, as demonstrated by Boost and explained in Modern C++ Design.
I am trying to partially truncate (or shorten) an existing file, using fstream. I have tried writing an EOF character, but this seems to do nothing.
Any help would be appreciated...
I don't think you can. There are many functions for moving "up and down" the wrapper hierarchy for HANDLE<->int<->FILE *, at least on Windows, but there is no "proper" to extract the FILE * from an iostreams object (if indeed it is even implemented with one).
You may find this question to be of assistance.
Personally I would strongly recommend steering clear of iostreams, they're poorly designed, heavily C++, and nasty to look at. Take a look at Boost's iostreams, or wrap stdio.h if you need to use classes.
The relevant function for stdio is ftruncate().
The Boost.Interprocess library defines a portable truncate function. For some reason it is not documented, but you can find it this header file.
It'll depend on the OS. Most OSes support this, but in different ways. On Windows, there's a SetEndOfFile(). On Unix and similar systems, you lseek to where you want the file to end, and do an lwrite of zero bytes there. Other OSes undoubtedly use other methods.
I bit the bullet in the end and read the part of the file to be kept to an array then re-wrote it. It's not the best solution - but as the files will always be small I have decided to accept this method.