Thrift: Checking in readonly option for TFileTransport

Reviewed by: boz


git-svn-id: https://svn.apache.org/repos/asf/incubator/thrift/trunk@665093 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/lib/cpp/src/transport/TFileTransport.cpp b/lib/cpp/src/transport/TFileTransport.cpp
index 2e9d810..4ecaa95 100644
--- a/lib/cpp/src/transport/TFileTransport.cpp
+++ b/lib/cpp/src/transport/TFileTransport.cpp
@@ -50,7 +50,7 @@
 }
 #endif
 
-TFileTransport::TFileTransport(string path)
+TFileTransport::TFileTransport(string path, bool readOnly)
   : readState_()
   , readBuff_(NULL)
   , currentEvent_(NULL)
@@ -75,6 +75,7 @@
   , offset_(0)
   , lastBadChunk_(0)
   , numCorruptedEventsInChunk_(0)
+  , readOnly_(readOnly)
 {
   // initialize all the condition vars/mutexes
   pthread_mutex_init(&mutex_, NULL);
@@ -175,6 +176,14 @@
   return true;
 }
 
+void TFileTransport::write(const uint8_t* buf, uint32_t len) {
+  if (readOnly_) {
+    throw TTransportException("TFileTransport: attempting to write to file opened readonly");
+  }
+
+  enqueueEvent(buf, len, false);
+}
+
 void TFileTransport::enqueueEvent(const uint8_t* buf, uint32_t eventLen, bool blockUntilFlush) {
   // make sure that event size is valid
   if ( (maxEventSize_ > 0) && (eventLen > maxEventSize_) ) {
@@ -708,8 +717,9 @@
 
 // Utility Functions
 void TFileTransport::openLogFile() {
-  mode_t mode = S_IRUSR| S_IWUSR| S_IRGRP | S_IROTH;
-  fd_ = ::open(filename_.c_str(), O_RDWR | O_CREAT | O_APPEND, mode);
+  mode_t mode = readOnly_ ? S_IRUSR | S_IRGRP | S_IROTH : S_IRUSR | S_IWUSR| S_IRGRP | S_IROTH;
+  int flags = readOnly_ ? O_RDONLY : O_RDWR | O_CREAT | O_APPEND;
+  fd_ = ::open(filename_.c_str(), flags, mode);
 
   // make sure open call was successful
   if(fd_ == -1) {
diff --git a/lib/cpp/src/transport/TFileTransport.h b/lib/cpp/src/transport/TFileTransport.h
index e31e85c..24c0c66 100644
--- a/lib/cpp/src/transport/TFileTransport.h
+++ b/lib/cpp/src/transport/TFileTransport.h
@@ -153,7 +153,7 @@
 class TFileTransport : public TFileReaderTransport,
                        public TFileWriterTransport {
  public:
-  TFileTransport(std::string path);
+  TFileTransport(std::string path, bool readOnly=false);
   ~TFileTransport();
 
   // TODO: what is the correct behaviour for this?
@@ -162,10 +162,7 @@
     return true;
   }
   
-  void write(const uint8_t* buf, uint32_t len) {
-    enqueueEvent(buf, len, false);
-  }
-  
+  void write(const uint8_t* buf, uint32_t len);
   void flush();
 
   uint32_t readAll(uint8_t* buf, uint32_t len);
@@ -360,6 +357,8 @@
   // event corruption information
   uint32_t lastBadChunk_;
   uint32_t numCorruptedEventsInChunk_;
+
+  bool readOnly_;
 };
 
 // Exception thrown when EOF is hit