file library



  • Wobei die Aufgabe recht einfach ist. Ich weiß zwar nicht, wie sich die Shade sich unter Verhalten wie iostrem vorstellt, aber ich hätte keine Skrupel etwas wie

    /* Ausgabe (über streambuf) regeln; da müsste ich wieder nachsehen :-)  */
    class OFileLock {
      int fd;
      ostream& out;
    public:
      OFileLock (ostream const& out) : out (out) {
        fd = out.get_fd ();
        flock (fd, LOCK_EX);
      }
      ~OFileLock () {
        flock (fd, LOCK_UN);
      }
    
    };
    
    int main (int, char** argv)
    {
      OFileLock out (ofstream (*++argv));
      out << *argv;
    }
    

    zu tippen.



  • ich würde das eher mit einem Streammanipulator lösen

    #include <fcntl.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <fstream>
    
    namespace file
    {
      class lock
      {
         template<class charT, class traits> 
         friend std::basic_ostream<charT,traits> &
         operator<<(std::basic_ostream<charT,traits> &out, const lock &obj);
    
         flock lock_m;
      public:
         lock(const lock &obj)
         { memmove(static_cast<void*>(&lock_m),
              static_cast<const void*>(&obj.lock_m),sizeof(flock)); }
         lock(bool read, short whence, off_t start, off_t len) //lock
         { 
           lock_m.l_type=read ? F_RDLCK : F_WRLCK;
           lock_m.l_start=start;
           lock_m.l_whence=whence; 
           lock_m.l_len=len; 
           lock_m.l_pid=getpid();
         }
         lock(short whence, off_t start, off_t len) //unlock
         { 
           lock_m.l_type=F_UNLCK;
           lock_m.l_start=start;
           lock_m.l_whence=whence; 
           lock_m.l_len=len; 
           lock_m.l_pid=getpid();
         }
         //hinzugefügt {
         inline void unlock(void) { lock_m.l_type=F_UNLCK; }
         inline void readlock(void) { lock_m.l_type=F_RDLOCK; }
         inline void writelock(void) { lock_m.l_type=F_WRDLOCK; }
         void pos(short whence, off_t start, off_t len)
         {
           lock_m.l_start=start;
           lock_m.l_whence=whence;
           lock_m.l_len=len;
         }
         //}
      };
      template<class charT, class traits=std::char_traits<charT> >
      std::basic_ostream<charT,traits> &
      operator<<(std::basic_ostream<charT,traits> &out, const lock &obj)
      {
         fcntl(fd /*<- ein Problem ist nur an fd zu kommen*/,F_SETLK,lock.lock_m);
         return out;
      }
    }
    

    jetzt muss man nur noch irgend wie an fd kommen und die Parameter von lock sollten eher an std::basic_ostream angepasst werden

    [ Dieser Beitrag wurde am 27.02.2003 um 18:39 Uhr von kingruedi editiert. ]

    [ Dieser Beitrag wurde am 27.02.2003 um 21:17 Uhr von kingruedi editiert. ]



  • Original erstellt von kingruedi:
    ich würde das eher mit einem Streammanipulator lösen

    Daran hab' ich auch kurz gedacht, und festgestellt, dass

    OFileLock (std::cout) << "test" << 2 << 3 << 4;
    

    nicht so viel schlechter zu lesen ist als

    std::cout << lock << "test" << 2 << 3 << 4 /* << unlock? */;
    

    . Und flexibler scheint's auch zu sein?



  • naja, dass kommt ganz drauf an, wie man es benutzt

    const lock &lock(lock &l, bool read, short whence, off_t pos, off_t len)
    {
      if(read)
       l.readlock();
      else
       l.writelock();
      l.pos(whence,pos,len);
      return l;
    }
    const lock &unlock(lock &l)
    {
      l.unlock();
      return l;
    }
    lock l;
    out << lock(l,...) << "xx" << unlock(l);
    

    oder ähnliches



  • schön das ihr euch unter unix auskennt. aber unter windows gibt es afaik kein flock. da muss man die rechte beim CreateFile angeben (zumindest kenne ich keine andere Lösung) - was die Sache doch n bisschen komplizierter macht 🙂



  • omg ist das übel.

    Naja, so was vielleicht?

    template<class charT, class traits=std::char_traits<charT> >
    class lockofstream : public basic_ofstream<charT,traits>
    {
      struct file
      {
         file(const char *filename) : filename_(filename)
         {
    #ifdef UNIX
            int fd=open(filename,O_CREAT);
            flock(fd,LOCK_EX);
            close(fd);
    #else
            //...
    #endif
         }
         ~file() 
         {
    #ifdef UNIX
            int fd=open(filename_,0);
            flock(fd,LOCK_UN);
            close(fd);
    #else
            //...
    #endif
         }
      private:
        const char *filename_; 
      } file_;
      basic_ostream<charT,traits> out_;
    public:
      lockofstream(const char *filename,ios_base::openmode mode = ios_base::in)
        : file_(filename), out_(filename,mode)
      { }
      ~lockofstream() { }
    };
    


  • kingruedi der code macht mir angst 😮 😉
    ich kenne zwar nicht den optimalsten weg wie man c++ code porten kann aber dieser ist es bestimt nicht



  • Shade: Geht das nicht mit LockFile?



  • Original erstellt von <Matthias>:
    Shade: Geht das nicht mit LockFile?

    Ja, LockFile gibt es auch - ABER LockFile kann nur ein HFILE locken - und das bekomme ich nur, wenn ich es mit CreateFile öffne...



  • Original erstellt von Dimah:
    kingruedi der code macht mir angst 😮 😉
    ich kenne zwar nicht den optimalsten weg wie man c++ code porten kann aber dieser ist es bestimt nicht

    😃 ja, dass ist wirklich nicht der beste weg 😉


Anmelden zum Antworten