Consumer doesn't see state of variable changing - multithreading

In the complete code (see below), at some point (after N iterations) the consumer (function executionServiceHandler while (inService_) is entered, despite inService_ having been changed (in the same thread) [or so it seems from log output].
I have as far as possible tried to guard std::cout as well, although I'm not sure this is necessary.
Could you perhaps crit the code. I know strictly speaking I don't need to use StopServiceCmd to let the thread complete, but in my mind I can't see why it shouldn't work.
Also, I could have used std::function, but the example is simplified from original.
I could add that I tested this on GCC (latest), after the original example failed on VCC (2017)
Code follows (EDIT - now using std::function:
#include <thread>
#include <functional>
#include <mutex>
#include <iostream>
#include <queue>
#include <sstream>
#include <condition_variable>
class ThreadCmdConsumer
{
public:
using Guard = std::lock_guard<std::mutex>;
using UniqueLock = std::unique_lock<std::mutex>;
ThreadCmdConsumer()
: inService_(),
executionServiceThread_(std::bind(&ThreadCmdConsumer::executionServiceHandler, this))
{
//Wait while thread does not exist...
UniqueLock lock(cmdQMutex_);
while (!inService_) {
conditional_.wait(lock);
}
std::cout << std::hex << this << " constructed and consumer waiting..." << std::endl;
}
~ThreadCmdConsumer() {
static std::size_t nth = 0;
{
UniqueLock lock(cmdQMutex_);
std::cout << "destructing (" << std::dec << nth++ << "): " << std::hex << this << std::endl;
}
process([this](){
//Note: inService_ can only be changed in consumer thread...
inService_ = false;
std::cout << "consumer_->inService state: " << inService_ << std::endl;
});
UniqueLock lock(cmdQMutex_);
std::cout << "producer " << std::hex << this << " destructor has lock" << std::endl;
while (inService_) {
std::cout << "producer " << std::hex << this << " destructor in service, entering wait" << std::endl;
conditional_.wait(lock);
std::cout << "producer " << std::hex << this << " destructor exited wait - has lock" << std::endl;
}
// Join will always succeed as result of StopServiceCmd that sets inService to false
// (in its own thread context). Once join completes, we are certain of executionServiceHandler
// exiting normally.
std::cout << "produces " << std::hex << this << " destructor joining" << std::endl;
lock.unlock();
try {
executionServiceThread_.join();
}
catch (const std::system_error& ex) {
UniqueLock lock(cmdQMutex_);//for cout
std::cout << "Exception during join" << ex.what() << std::endl;
abort();
}
}
void executionServiceHandler()
{
{ //Starts the service...
UniqueLock lock(cmdQMutex_);
inService_ = true;
lock.unlock();
conditional_.notify_one();
}
try {
UniqueLock lock(cmdQMutex_);
while (inService_) {
std::cout << "consumer " << std::hex << this << " has lock" << std::endl;
// Catering for spurious wake-ups too, hence while...
while (cmdQ_.empty()) {
std::cout << "consumer " << std::hex << this << " waiting" << std::endl;
conditional_.wait(lock);
std::cout << "consumer " << std::hex << this << " woken" << std::endl;
}
//Now we have the lock, and queue most certainly not empty
auto cmd = std::move(cmdQ_.front());
cmdQ_.pop();
//###lock.unlock(); // Don't want to be locked while executing... removed conservatively
(cmd)();
}
std::cout << "consumer " << std::hex << this << " execution complete" << std::endl;
}
catch(const std::exception& ex) {
std::cerr << "Unexpected " << ex.what() << std::endl;
abort();
}
//Not in service - notify when we've left (then we can truly join...)
conditional_.notify_one();
}
void process(std::function<void()>&& cmd)
{
UniqueLock lock(cmdQMutex_);
std::cout << "producer " << std::hex << this << " has lock" << std::endl;
bool notificationRequired = cmdQ_.empty();
cmdQ_.push(move(cmd));
if (notificationRequired) {
std::cout << "producer " << std::hex << this << " notifying" << std::endl;
lock.unlock();
conditional_.notify_one();
}
else {
std::cout << "producer " << std::hex << this << " not notifying" << std::endl;
}
}
private:
bool inService_;
std::queue<std::function<void()>> cmdQ_;
std::condition_variable conditional_;
std::mutex cmdQMutex_;
std::thread executionServiceThread_;
};
typedef std::function<void(const std::string&)> Handler;
struct ThreadOwner
{
ThreadCmdConsumer executor_;
// Do it done in the context of executor....
void doIt(const Handler& handler)
{ }
};
int main()
{
std::cout << "Program started" << std::endl;
//Sometimes deadlocks on thread being killed
for (int i = 0; i < 1000; ++i) {
auto handler = [](const std::string&){};
{
ThreadOwner owner;
owner.executor_.process([&handler, &owner]() {
owner.doIt(handler);
});
}
}
}

Related

this vector has vector probelem is not working

The problem is it prints the full name but not the rest of the lines about the person.
Could someone, please guide me?
I do really appreciate your help!
auto itr = find(my_vec.begin(), my_vec.end(), search );
if(itr != my_vec.end())
{
std::cout << "Match found " << search << std::endl;
std::cout << "\nFull name: " << search << std::endl;
} else {
std::cout << "Match not found "<< std::endl;
}
There are a few style problems with your code:
No need to explicitly initialize strings, they will be empty by default (see here).
Keep a consistent style. For example, either always start brackets in the same line as the function signature or in the next line.
No need to close the file explicitly at the end of the function, this is done when the object goes out of scope (see (destructor) here).
No need to include <map> and <iomanip> headers.
Don't keep unused variables.
Give suggestive names to your variables.
Do not return error codes to the OS when the app is working as it should. Not finding a name is not an error, is it?
It seems your file has 6 entries per contact, so all you have to do is print 5 more lines. You do not need to store the lines in a vector, just parse and print them as you go. Here is an example:
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <fstream>
void findContact(std::string fullName, std::string contactListPath) {
std::ifstream inFile{contactListPath};
if (!inFile) {
std::cerr << "File could not be open!" << std::endl;
return;
}
std::string line;
while (std::getline(inFile, line)) {
if (line == fullName) {
std::cout << "Match found: \n";
std::cout << "\nFull name: " << fullName;
std::cout << "\nAddress: " << (std::getline(inFile, line), line);
std::cout << "\nE-mail: " << (std::getline(inFile, line), line);
std::cout << "\nPhone: " << (std::getline(inFile, line), line);
std::cout << "\nBirthday: " << (std::getline(inFile, line), line);
std::cout << "\nNote: " << (std::getline(inFile, line), line) << std::endl;
return;
}
}
std::cout << "Match not found " << std::endl;
}
int main() {
std::string fullName;
std::string contactListPath;
std::cout << "Enter full name to search: ";
std::getline(std::cin, fullName);
std::cout << "Enter path to contact list: ";
std::getline(std::cin, contactListPath);
findContact(fullName, contactListPath);
return 0;
}
If every entry contains 6 lines. Then you can print all the lines starting from the line that you found like:
auto itr = find(my_vec.begin(), my_vec.end(), search );
if(itr != my_vec.end())
{
std::cout << "Match found " << std::endl;
// print the next 6 lines
for(int remaining = 6;remaining > 0 && itr!=my_vec.end(); itr++,remaining--) {
std::cout << *itr << std::endl;
}
} else {
std::cout << "Match not found "<< std::endl;
}

I have a server socket program runnig in Debian 10, but netstat does not show it

I am doing a server and client programs in C++ on Debian Linux
Below is the server:
void MonitoringServer::serve() {
int serverSocketFd, childSocketFd;
int clientAddrLen;
struct sockaddr_in serverAddr, clientAddr;
if ((serverSocketFd = socket(AF_INET, SOCK_STREAM, 6)) < 0) {
std::cout << "could not create socket. exiting..." << std::endl;
} else {
std::cout << "socket created with file descriptor : " << serverSocketFd << std::endl;
bzero((char*)&serverAddr, sizeof(serverAddr));
serverAddr.sin_family = AF_INET;
serverAddr.sin_addr.s_addr = inet_addr("192.168.1.92");
serverAddr.sin_port = htonl(15500);
if (bind(serverSocketFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr)) < 0) {
std::cout << "error binding server socket. exiting..." << std::endl;
stop = true;
} else {
std::cout << "socket file descriptor bound to the specified address" << std::endl;
}
int listenResult = listen(serverSocketFd, 10);
if (listenResult < 0) {
std::cout << "listen returned a negative value" << std::endl;
stop = true;
} else {
std::cout << "server socket is listening" << std::endl;
}
while (!stop) {
std::cout << "going to accept the next client connection" << std::endl;
childSocketFd = accept(serverSocketFd, (struct sockaddr*)&clientAddr, (socklen_t*)&clientAddrLen);
if (childSocketFd < 0) {
std::cout << "error accepting connections. exiting..." << std::endl;
switch (errno) {
case EBADF : std::cout << "socket not valid file descriptor" << std::endl; break;
case ECONNABORTED : std::cout << "connection aborted" << std::endl; break;
case EFAULT : std::cout << "address param not in writable part of address space" << std::endl; break;
case EINTR : std::cout << "accept() terminated by a signal" << std::endl; break;
case EINVAL : std::cout << "socket is not wiling to accept connections" << std::endl; break;
case EMFILE : std::cout << "The per-process descriptor table is full" << std::endl; break;
case ENOMEM : std::cout << "No memory available to complete the operation" << std::endl; break;
case ENOTSOCK : std::cout << "Descriptor is not a socket" << std::endl; break;
case EOPNOTSUPP : std::cout << "socket is not of type SOCK_STREAM and thus does not accept connections" << std::endl; break;
case EWOULDBLOCK : std::cout << "socket is non-blocking and no connections are present to be accepted" << std::endl; break;
default : std::cout << "unknown error in accept call : " << errno << std::endl;
}
stop = true;
}
pthread_attr_t attr;
pthread_t threadID;
int threadOpRetValue;
if (!stop) {
threadOpRetValue = pthread_attr_init(&attr);
if (threadOpRetValue < 0) {
std::cout << "error creating client handling thread. exiting..." << std::endl;
stop = true;
}
}
if (!stop) {
threadOpRetValue = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if (threadOpRetValue < 0) {
std::cout << "error configuring client handling thread. exiting..." << std::endl;
stop = true;
}
}
if (!stop) {
threadOpRetValue = pthread_create(reinterpret_cast<pthread_t *>(threadID), &attr,
&MonitoringServer::handle, &childSocketFd);
if (threadOpRetValue < 0) {
std::cout << "error creating the client socket worker thread. exiting..." << std::endl;
stop = true;
}
}
}
}
}
When I run the program, it blocks on the accept call, but I neither see the process on the netstat -a output, and the below client returns a connection refused error code.
int main(int argc, char **argv) {
std::cout << "starting client..." << std::endl;
int socketFD;
struct sockaddr_in serverAddress;
bool stop = false;
// open the socket
bzero((char*)&serverAddress, sizeof(serverAddress));
serverAddress.sin_family = AF_INET;
serverAddress.sin_addr.s_addr = inet_addr(argv[1]);
serverAddress.sin_port = htons(atoi(argv[2]));
if ((socketFD = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
std::cout << "error creating the socket. exiting..." << std::endl;
stop = true;
}
int connRetValue;
if (!stop && (connRetValue = connect(socketFD, (struct sockaddr*)&serverAddress, sizeof serverAddress)) < 0) {
std::cout << "error code " << connRetValue << std::endl;
std::cout << "error connecting to the server. exiting..." << std::endl;
connRetValue = errno;
switch (connRetValue) {
case EACCES : std::cout << "broadcast address specified" << std::endl; break;
case EADDRINUSE : std::cout << "address in use" << std::endl; break;
case EADDRNOTAVAIL : std::cout << "address not available" << std::endl; break;
case EAFNOSUPPORT : std::cout << "wrong address family" << std::endl; break;
case EBADF : std::cout << "bad socket descriptor" << std::endl; break;
case ECONNREFUSED : std::cout << "connection refused" << std::endl; break;
case EFAULT : std::cout << "address out of process address space" << std::endl; break;
case EHOSTUNREACH : std::cout << "target host is unreachable" << std::endl; break;
case EINPROGRESS : std::cout << "connection in progress in nonblocking socket" << std::endl; break;
case EINTR : std::cout << "execution interrupted by a signal" << std::endl; break;
case EISCONN : std::cout << "socket already connected" << std::endl; break;
case ENETDOWN : std::cout << "network interface mal-function" << std::endl; break;
case ENETUNREACH : std::cout << "network unreachable" << std::endl; break;
case ENOBUFS : std::cout << "unable to allocate buffer in memory" << std::endl; break;
case ENOTSOCK : std::cout << "descriptor is not a socket" << std::endl; break;
case EOPNOTSUPP : std::cout << "socket is listening. operation not allowed" << std::endl; break;
case EPROTOTYPE : std::cout << "address of different type than the socket" << std::endl; break;
case ETIMEDOUT : std::cout << "timeout" << std::endl; break;
case ECONNRESET : std::cout << "remote host reset the connection" << std::endl; break;
default : std::cout << "unknown error code : " << connRetValue << std::endl;
}
stop = true;
}
if (!stop) {
char* message = "ola bichinhos";
write(socketFD, message, strlen(message)*sizeof(char));
}
close(socketFD);
return 0;
}
I am starting to suspect of selinux imposing security restrictions on what my processes can do, but I am not sure.
Can someone tell me if there is anything wrong with this code before I start to investigate SE linux ?
I was building the address port with the wrong conversion function.
I was using htonl and it should be htons.

main.cpp:4:10: fatal error: Car.h: No such file or directory

I am using zybook, and it requires for me to create a program that maintains the inventory of a car rental agency.
The three files for this program are:
car.h - Class declaration
car.cpp - Class definition
main.cpp - main() function and other functions as described
When I wrote the program, I am getting an error:
main.cpp:4:10: fatal error: Car.h: No such file or directory
4 | #include "Car.h"
| ^~~~~~~
compilation terminated.
car.cpp:3:10: fatal error: Car.h: No such file or directory
3 | #include "Car.h"
| ^~~~~~~
compilation terminated.
Here is my code:
#include <iostream>
#include <string.h>
#include <vector>
#include "Car.h"
#include <algorithm>
using namespace std;
void addCar(vector<Car>& cars);
//bool deleteCar(vector<Car>& cars);
bool updateCarCondition(vector<Car>& cars);
void displayCar(vector<Car>& cars);
void displayAllCars(vector<Car>& cars);
bool rentCar(vector<Car>& cars);
bool returnCar(vector<Car>& cars);
int main(){
char option;
vector<Car> cars;
while (true){
cout << "CAR RENTAL AGENCY MENU" << endl;
cout << "a - Add car to inventory" << endl;
cout << "d - Delete car by id from inventory" << endl;
cout << "u - Update car by id condition in inventory" << endl;
cout << "s - Display one car by id from inventory" << endl;
cout << "i - Display list of all cars in inventory" << endl;
cout << "c - Rent a car by id in inventory" << endl;
cout << "r - Return a car by id in inventory" << endl;
cout << "q - Quit" << endl;
cout << "Choose an option: " << endl;
cin >> option;
cin.ignore();
cout << endl;
switch(option){
case 'a': addCar(cars);
break;
//case 'd': deleteCar(cars);
//break;
case 'u': updateCarCondition(cars);
break;
case 's': displayCar(cars);
break;
case 'i': displayAllCars(cars);
break;
case 'c': rentCar(cars);
break;
case 'r': returnCar(cars);
break;
case 'q': break;
default: cout << "Please enter a valid option" << endl;
}
}
return 0;
}
void addCar(vector<Car>& cars){
int id, year;
string model, make, condition;
cout << "ADD CAR TO INVENTORY" << endl;
cout << "Enter an ID: " << endl;
cin >> id;
cout << "Enter the make: " << endl;
cin >> make;
cout << "Enter the model: " << endl;
cin >> model;
cout << "Enter the year: " << endl;
cin >> year;
cout << "Enter the condition (new, slighty_used, used): " << endl;
cin >> condition;
Car car(id, make, model, year, condition);
cars.push_back(car);
}
/*bool deleteCar(vector<Car>& cars){
cout << "REMOVE CAR FROM INVENTORY" << endl;
int id;
cout << "Enter the ID of the car to delete: " << endl;
cin >> id;
vector<Car>::iterator it;
for (int i = 0; i < cars.size(); i++){
if (cars.at(i).Getid() == id){
//Car const& const_car = cars.at(i);
//std::vector<Car>::iterator itr = std::find(cars.begin(), cars.end(), const_car);
it = cars.at(i);
cars.erase(it);
return true;
}
}
return false;
}*/
bool updateCarCondition(vector<Car>& cars){
cout << "UPDARE CAR CONDITION IN INVENTORY" << endl;
int id;
string condition;
cout << "Enter the ID of the car to update condition: " << endl;
cin >> id;
cout << "Enter the condition (new, slighty_used, used): " << endl;
cin >> condition;
for (int i = 0; i < cars.size(); i++){
if (cars.at(i).Getid() == id){
cars.at(i).Setcondition(condition);
return true;
}
}
return false;
}
void displayCar(vector<Car>& cars){
cout << "DISPLAY CAR IN INVENTORY" << endl;
int id;
cout << "Enter the ID of the car to display: " << endl;
cin >> id;
for (int i = 0; i < cars.size(); i++){
if (cars.at(i).Getid() == id){
cars.at(i).displayCar();
break;
}
}
}
void displayAllCars(vector<Car>& cars){
cout << "DISPLAY ALL CARS IN INVENTORY" << endl;
for (int i = 0; i < cars.size(); i++){
cars.at(i).displayCar();
}
}
bool rentCar(vector<Car>& cars){
cout << "RENT CAR IN INVENTORY" << endl;
int id;
cout << "Enter the ID of the car to rent: " << endl;
cin >> id;
for (int i = 0; i < cars.size(); i++){
if (cars.at(i).Getid() == id){
if (cars.at(i).Getrented()){
cout << "Car is already rented" << endl;
return false;
}
else if (cars.at(i).Getrented() == false){
cout << "Car has been successfully rented to you" << endl;
cars.at(i).toggleRented();
return true;
}
}
}
cout << "Car " << id << " not found in inventory" << endl;
return false;
}
bool returnCar(vector<Car>& cars){
cout << "RENT CAR TO INVENTORY" << endl;
int id;
cout << "Enter the ID of the car to return: " << endl;
cin >> id;
for (int i = 0; i < cars.size(); i++){
if (cars.at(i).Getid() == id){
if (cars.at(i).Getrented()){
cars.at(i).toggleRented();
cout << "Car returned successfully!!" << endl;
return true;
}
}
}
cout << "Car " << id << " not found in inventory" << endl;
return false;
}

Why do I get fatal error C1075, I checked the code and nothing was wrong

I am an early C++ programmer and i wanted to create a simple little game on CMD with C++. Why do I get
fatal error C1075: end of file found before the left brace and read and write files not working
I checked every line and nothing appeared wrong.
I checked every line and nothing appeared wrong. No 'curly' red line appeared to me on any character. Maybe my eyes are wrong.
std::cout << "Enter 1 to Play: ";
int play = 0;
std::cin >> play;
if (play == 1) {
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " \n";
std::cout << " +=======================================+\n";
std::cout << " || CMD Math Tester ||\n";
std::cout << " || Version 1.0 ||\n";
std::cout << " ++-------------------------------------++\n";
std::cout << " || Answer the questions. ||\n";
std::cout << " +=======================================+\n";
std::cout << " \n";
std::cout << " \n";
std::cout << "What is 2+2: ";
int answerExpected = 4;
int answerOfUser = 0;
std::cin >> answerOfUser;
if (answerOfUser == answerExpected) {
std::cout << "That is correct!\n";
std::cout << " \n";
std::cout << "What is 10+11: ";
answerExpected = 21;
answerOfUser = 0;
std::cin >> answerOfUser;
if (answerOfUser == answerExpected) {
std::cout << "That is correct!\n";
std::cout << " \n";
std::cout << "What is 100+200: ";
answerExpected = 300;
answerOfUser = 0;
std::cin >> answerOfUser;
if (answerOfUser == answerExpected) {
std::cout << "That is correct!\n";
std::cout << " \n";
std::cout << "What is 500-250: ";
answerExpected = 250;
answerOfUser = 0;
std::cin >> answerOfUser;
if (answerOfUser = answerExpected) {
std::cout << "That is correct!\n";
std::cout << " \n";
std::cout << "What is 5*2: ";
answerExpected = 10;
answerOfUser = 0;
std::cin >> answerOfUser;
if (answerOfUser == answerExpected) {
std::cout << "That is correct!\n";
std::cout << " \n";
std::cout << "What is 5*5: ";
answerExpected = 25;
answerOfUser = 0;
std::cin >> answerOfUser;
if (answerOfUser == answerExpected) {
std::cout << "That is correct!\n";
std::cout << " \n";
std::cout << "What is 200*5: ";
answerExpected = 1000;
answerOfUser = 0;
std::cin >> answerOfUser;
if (answerOfUser == answerExpected) {
std::cout << "That is correct!\n";
std::cout << " \n";
std::cout << "What is the sqrt of 16: ";
answerExpected = 4;
answerOfUser = 0;
std::cin >> answerOfUser;
if (answerOfUser == answerExpected) {
std::cout << "That is correct!\n";
std::cout << " \n";
std::cout << "What is the sqrt of 81: ";
answerExpected = 9;
answerOfUser = 0;
std::cin >> answerOfUser;
if (answerOfUser == answerExpected) {
std::cout << "That is correct!\n";
std::cout << " \n";
std::cout << "What is the absolute of 420: ";
answerExpected = 420;
answerOfUser = 0;
std::cin >> answerOfUser;
if (answerOfUser == answerExpected) {
std::cout << "That is correct!\n";
std::cout << " \n";
std::cout << "What is the absolute of -639: ";
answerExpected = 639;
answerOfUser = 0;
std::cin >> answerOfUser;
if (answerOfUser == answerExpected) {
std::cout << "+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+\n";
std::cout << "| Congratulations |\n";
std::cout << "+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~+\n";
std::cout << " \n";
std::cout << " \n";
std::cout << "You Have passed the test!\n";
} else {
std::cout << "That is wrong.\n";
}
} else {
std::cout << "That is wrong.\n";
}
} else {
std::cout << "That is wrong.\n";
}
} else {
std::cout << "That is wrong.\n";
}
} else {
std::cout << "That is wrong.\n";
}
} else {
std::cout << "That is wrong.\n";
}
} else {
std::cout << "That is wrong.\n";
}
} else {
std::cout << "That is wrong.\n";
}
} else {
std::cout << "That is wrong.\n";
}
} else {
std::cout << "That is wrong.\n";
}
} else {
std::cout << "Enter 1 to Play: ";
std::cin >> play;
}
If you take the complete error message, you will get something like
fatal error C1075: end of file found before the left brace and read and write files not working
That mean that you don't close enough block that you open them (there is more { than }).
To correct the problem, you should indent you code source better.
Some tools like indent will do it for you. You can even find some tools online.
But there is other problems in your code:
there is no main
includes are missing
if (answerOfUser = answerExpected) (= instead of == on 4th question) is not what you want
That said, it would be far easier to split your code into different functions to improve readability.
Since your game is to ask a series of questions, you could start by one function by question... But this point of discussion has its place more on https://codereview.stackexchange.com/

How do I copy files and folders using boost and Visual Studio 2005?

I'm trying to use boost::filesystem to copy files and folders (just like a standard copy a folder and paste it in windows explorer).
Although I've been to the boost::filesystem documentation, I still don't really know how to go about doing this.
Do you have to recursively go though each directory (creating it) and find each file copying it?
Additionally, how do you copy the file in C++/Boost?
P.S. I'm using Boost 1.40.0
Update
I think I may have ended up creating an answer to this one, only concern being that I don't do any try-catch errors to check for locked files and folders.
The following code makes a copy of a directory in the relative path "../example/ecomm" and duplicates it to a non-existing path "../example/dup_ecomm":
#include <boost/test/unit_test.hpp>
#include <boost/algorithm/string.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/regex.hpp>
#include <iostream>
#include <fstream>
#include<string>
bool copy_dir( const boost::filesystem::path & ext_dir_path, // the existing directory
const boost::filesystem::path & duplicate_dir_path // the duplicate directory
)
{
std::cout << "BEGIN: copy_dir " << endl;
std::cout << "- ext_dir_path: " << ext_dir_path << endl;
std::cout << "- duplicate_dir_path: " << duplicate_dir_path << endl;
// 1. Ensure that the directory we are trying to copy exists.
if (!boost::filesystem::exists( ext_dir_path ) ) return false;
bool createdDir = boost::filesystem::create_directory( duplicate_dir_path );
// cout << "createdDir: " << createdDir << endl;
copy_dir(ext_dir_path, // the existing directory
duplicate_dir_path, // the duplicate directory,
ext_dir_path, // the base path for the existing directory
duplicate_dir_path,
true);
std::cout << "END: copy_dir " << endl;
}
bool copy_dir( const boost::filesystem::path & ext_dir_path, // the existing directory
const boost::filesystem::path & duplicate_dir_path, // the duplicate directory,
const boost::filesystem::path & base_ext_dir_path, // the base path for the existing directory
const boost::filesystem::path & base_duplicate_dir_path, // the base path for the duplicate of the exisiting directory
bool isRootPath)
{
// Debug input arguments
std::cout << "BEGIN: copy_dir " << endl;
std::cout << "- ext_dir_path: " << ext_dir_path << endl;
std::cout << "- duplicate_dir_path: " << duplicate_dir_path << endl;
std::cout << "- base_ext_dir_path: " << base_ext_dir_path << endl;
std::cout << "- base_duplicate_dir_path: " << base_duplicate_dir_path << endl;
std::cout << "- isRootPath: " << isRootPath << endl;
boost::filesystem::directory_iterator end_itr; // default construction yields past-the-end
cout << "--Beginning itr loop" << endl;
for ( boost::filesystem::directory_iterator itr( ext_dir_path );
itr != end_itr;
++itr )
{
if ( boost::filesystem::is_directory(itr->status()) )
{
cout << "---itr->path(): " << itr->path() << endl;
boost::filesystem::path newExtDir(itr->path());
string dup_path = itr->path().string();
boost::algorithm::replace_first(dup_path, base_ext_dir_path.string(), base_duplicate_dir_path.string());
cout << "dup_path: " << dup_path << endl;
boost::filesystem::path new_dup_dir(dup_path);
bool createdDir = boost::filesystem::create_directory( new_dup_dir );
cout << "creating directory " << dup_path << " created: " << createdDir << endl;
boost::filesystem::path newDuplicateDir(duplicate_dir_path);
copy_dir(newExtDir, // the existing directory
newDuplicateDir, // the duplicate directory,
base_ext_dir_path,
base_duplicate_dir_path,
false);
}
else
{
cout << "---isLeaf: " << itr->path() << endl;
string dup_path = itr->path().string();
boost::algorithm::replace_first(dup_path, base_ext_dir_path.string(), base_duplicate_dir_path.string());
string src_path = itr->path().string();
cout << "src_path: " << src_path << endl;
cout << "dup_path: " << dup_path << endl;
boost::filesystem::path s_path(src_path);
boost::filesystem::path d_path(dup_path);
boost::filesystem::copy_file(s_path, d_path);
}
}
std::cout << "--Ending itr loop" << endl;
std::cout << "END: copy_dir " << endl;
return false;
}
test_suite*
init_unit_test_suite( int, char* [] ) {
boost::filesystem::path ext_dir("..\\example\\ecomm");
boost::filesystem::path dir_dup("..\\example\\dup_ecomm");
copy_dir(ext_dir,
dir_dup); // the duplicate directory,
// ... unit tests...etc...
}
My question now is what I'm I forgetting to do in regards to locked files and directories?
boost::filesystem::recursive_directory_iterator

Resources