{
if(!(m&M_RDWR))
throw invalid_argument("File::File mode");
- if(cm&~(C_CREATE|C_TRUNCATE))
+ if(cm&~(C_CREATE|C_TRUNCATE|C_EXCLUSIVE))
+ throw invalid_argument("File::File create");
+ if((cm&C_EXCLUSIVE) && (!(cm&C_CREATE) || (cm&C_TRUNCATE)))
throw invalid_argument("File::File create");
mode = m;
case C_CREATE: create_flags = OPEN_ALWAYS; break;
case C_TRUNCATE: create_flags = TRUNCATE_EXISTING; break;
case C_CREATE+C_TRUNCATE: create_flags = CREATE_ALWAYS; break;
+ case C_CREATE+C_EXCLUSIVE: create_flags = CREATE_NEW; break;
}
}
int err = GetLastError();
if(err==ERROR_FILE_NOT_FOUND)
throw file_not_found(fn);
+ else if(err==ERROR_FILE_EXISTS)
+ throw file_already_exists(fn);
else
throw system_error(format("CreateFile(%s)", fn), err);
}
flags |= O_CREAT;
if(cm&C_TRUNCATE)
flags |= O_TRUNC;
+ if(cm&C_EXCLUSIVE)
+ flags |= O_EXCL;
}
if(mode&M_APPEND)
flags |= O_APPEND;
int err = errno;
if(err==ENOENT)
throw file_not_found(fn);
+ else if(err==EEXIST)
+ throw file_already_exists(fn);
else
throw system_error(format("open(%s)", fn), err);
}
file_not_found(const std::string &fn): std::runtime_error(fn) { }
};
+class file_already_exists: public std::runtime_error
+{
+public:
+ file_already_exists(const std::string &fn): std::runtime_error(fn) { }
+};
+
/**
A class for reading and writing files.
{
C_NONE = 0,
C_CREATE = 1,
- C_TRUNCATE = 2
+ C_TRUNCATE = 2,
+ C_EXCLUSIVE = 4
};
private: