file-stat.h

Go to the documentation of this file.
00001 /*
00002 
00003 Copyright (C) 1996-2012 John W. Eaton
00004 
00005 This file is part of Octave.
00006 
00007 Octave is free software; you can redistribute it and/or modify it
00008 under the terms of the GNU General Public License as published by the
00009 Free Software Foundation; either version 3 of the License, or (at your
00010 option) any later version.
00011 
00012 Octave is distributed in the hope that it will be useful, but WITHOUT
00013 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00014 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
00015 for more details.
00016 
00017 You should have received a copy of the GNU General Public License
00018 along with Octave; see the file COPYING.  If not, see
00019 <http://www.gnu.org/licenses/>.
00020 
00021 */
00022 
00023 #if !defined (octave_file_stat_h)
00024 #define octave_file_stat_h 1
00025 
00026 #include <string>
00027 
00028 #include "oct-time.h"
00029 
00030 #include <sys/types.h>
00031 
00032 class
00033 OCTAVE_API
00034 base_file_stat
00035 {
00036 public:
00037 
00038   base_file_stat (void)
00039     : initialized (false), fail (false), errmsg (), fs_mode (),
00040       fs_ino (), fs_dev (), fs_nlink (), fs_uid (), fs_gid (),
00041       fs_size (), fs_atime (), fs_mtime (), fs_ctime (), fs_rdev (),
00042       fs_blksize (), fs_blocks () { }
00043 
00044   base_file_stat (const base_file_stat& fs)
00045     : initialized (fs.initialized), fail (fs.fail), errmsg (fs.errmsg),
00046       fs_mode (fs.fs_mode), fs_ino (fs.fs_ino), fs_dev (fs.fs_dev),
00047       fs_nlink (fs.fs_nlink), fs_uid (fs.fs_uid), fs_gid (fs.fs_gid),
00048       fs_size (fs.fs_size), fs_atime (fs.fs_atime), fs_mtime (fs.fs_mtime),
00049       fs_ctime (fs.fs_ctime), fs_rdev (fs.fs_rdev),
00050       fs_blksize (fs.fs_blksize), fs_blocks (fs.fs_blocks) { }
00051 
00052   base_file_stat& operator = (const base_file_stat& fs)
00053   {
00054     if (this != &fs)
00055       {
00056         initialized = fs.initialized;
00057         fail = fs.fail;
00058         errmsg = fs.errmsg;
00059         fs_mode = fs.fs_mode;
00060         fs_ino = fs.fs_ino;
00061         fs_dev = fs.fs_dev;
00062         fs_nlink = fs.fs_nlink;
00063         fs_uid = fs.fs_uid;
00064         fs_gid = fs.fs_gid;
00065         fs_size = fs.fs_size;
00066         fs_atime = fs.fs_atime;
00067         fs_mtime = fs.fs_mtime;
00068         fs_ctime = fs.fs_ctime;
00069         fs_rdev = fs.fs_rdev;
00070         fs_blksize = fs.fs_blksize;
00071         fs_blocks = fs.fs_blocks;
00072       }
00073 
00074     return *this;
00075   }
00076 
00077   // The minimum difference in file time stamp values.
00078   // FIXME -- this value should come from the filesystem itself.  How
00079   // can we get that info?
00080   octave_time time_resolution (void) const
00081   {
00082     static octave_time resolution (1.0);
00083     return resolution;
00084   }
00085 
00086   // File status and info.  The is_XXX functions will return false for
00087   // file_stat objects that are not properly initialized.  The others
00088   // should all return 0 (or the equivalent, for the given object)
00089   // which is likely not meaningful.
00090 
00091   bool is_blk (void) const;
00092   bool is_chr (void) const;
00093   bool is_dir (void) const;
00094   bool is_fifo (void) const;
00095   bool is_lnk (void) const;
00096   bool is_reg (void) const;
00097   bool is_sock (void) const;
00098 
00099   static bool is_blk (mode_t mode);
00100   static bool is_chr (mode_t mode);
00101   static bool is_dir (mode_t mode);
00102   static bool is_fifo (mode_t mode);
00103   static bool is_lnk (mode_t mode);
00104   static bool is_reg (mode_t mode);
00105   static bool is_sock (mode_t mode);
00106 
00107   ino_t ino (void) const { return fs_ino; }
00108   dev_t dev (void) const { return fs_dev; }
00109 
00110   nlink_t nlink (void) const { return fs_nlink; }
00111 
00112   uid_t uid (void) const { return fs_uid; }
00113   gid_t gid (void) const { return fs_gid; }
00114 
00115   off_t size (void) const { return fs_size; }
00116 
00117   octave_time atime (void) const { return fs_atime; }
00118   octave_time mtime (void) const { return fs_mtime; }
00119   octave_time ctime (void) const { return fs_ctime; }
00120 
00121   dev_t rdev (void) const { return fs_rdev; }
00122 
00123   long blksize (void) const { return fs_blksize; }
00124   long blocks (void) const { return fs_blocks; }
00125 
00126   mode_t mode (void) const { return fs_mode; }
00127 
00128   std::string mode_as_string (void) const;
00129 
00130   bool ok (void) const { return initialized && ! fail; }
00131 
00132   operator bool () const { return ok (); }
00133 
00134   bool exists (void) const { return ok (); }
00135 
00136   std::string error (void) const { return ok () ? std::string () : errmsg; }
00137 
00138   // Has the file referenced by this object been modified since TIME?
00139   bool is_newer (const octave_time& time) const { return fs_mtime > time; }
00140 
00141   // It's nice to be able to hide the file_stat object if we don't
00142   // really care about it.
00143   static int is_newer (const std::string&, const octave_time&);
00144 
00145 protected:
00146 
00147   virtual ~base_file_stat (void) { }
00148 
00149   // TRUE means we have already called stat.
00150   bool initialized;
00151 
00152   // TRUE means the stat for this file failed.
00153   bool fail;
00154 
00155   // If a failure occurs, this contains the system error text.
00156   std::string errmsg;
00157 
00158   // file type and permissions
00159   mode_t fs_mode;
00160 
00161   // serial number
00162   ino_t fs_ino;
00163 
00164   // device number
00165   dev_t fs_dev;
00166 
00167   // number of links
00168   nlink_t fs_nlink;
00169 
00170   // user ID of owner
00171   uid_t fs_uid;
00172 
00173   // group ID of owner
00174   gid_t fs_gid;
00175 
00176   // size in bytes, for regular files
00177   off_t fs_size;
00178 
00179   // time of last access
00180   octave_time fs_atime;
00181 
00182   // time of last modification
00183   octave_time fs_mtime;
00184 
00185   // time of last file status change
00186   octave_time fs_ctime;
00187 
00188   // device number for special files
00189   dev_t fs_rdev;
00190 
00191   // best I/O block size
00192   long fs_blksize;
00193 
00194   // number of 512-byte blocks allocated
00195   long fs_blocks;
00196 };
00197 
00198 class
00199 OCTAVE_API
00200 file_stat : public base_file_stat
00201 {
00202 public:
00203 
00204   file_stat (const std::string& n = std::string (), bool fl = true)
00205     : base_file_stat (), file_name (n), follow_links (fl)
00206   {
00207     if (! file_name.empty ())
00208       update_internal ();
00209   }
00210 
00211   file_stat (const file_stat& fs)
00212     : base_file_stat (fs), file_name (fs.file_name),
00213       follow_links (fs.follow_links) { }
00214 
00215   file_stat& operator = (const file_stat& fs)
00216   {
00217     if (this != &fs)
00218       {
00219         base_file_stat::operator = (fs);
00220 
00221         file_name = fs.file_name;
00222         follow_links = fs.follow_links;
00223       }
00224 
00225     return *this;
00226   }
00227 
00228   ~file_stat (void) { }
00229 
00230   void get_stats (bool force = false)
00231   {
00232     if (! initialized || force)
00233       update_internal (force);
00234   }
00235 
00236   void get_stats (const std::string& n, bool force = false)
00237   {
00238     if (n != file_name || ! initialized  || force)
00239       {
00240         initialized = false;
00241 
00242         file_name = n;
00243 
00244         update_internal (force);
00245       }
00246   }
00247 
00248 private:
00249 
00250   // Name of the file.
00251   std::string file_name;
00252 
00253   // TRUE means follow symbolic links to the ultimate file (stat).
00254   // FALSE means get information about the link itself (lstat).
00255   bool follow_links;
00256 
00257   void update_internal (bool force = false);
00258 };
00259 
00260 class
00261 OCTAVE_API
00262 file_fstat : public base_file_stat
00263 {
00264 public:
00265 
00266   file_fstat (int n) : base_file_stat (), fid (n)
00267   {
00268     update_internal ();
00269   }
00270 
00271   file_fstat (const file_fstat& fs)
00272     : base_file_stat (fs), fid (fs.fid) { }
00273 
00274   file_fstat& operator = (const file_fstat& fs)
00275   {
00276     if (this != &fs)
00277       {
00278         base_file_stat::operator = (fs);
00279 
00280         fid = fs.fid;
00281       }
00282 
00283     return *this;
00284   }
00285 
00286   ~file_fstat (void) { }
00287 
00288   void get_stats (bool force = false)
00289   {
00290     if (! initialized || force)
00291       update_internal (force);
00292   }
00293 
00294   void get_stats (int n, bool force = false)
00295   {
00296     if (n != fid || ! initialized  || force)
00297       {
00298         initialized = false;
00299 
00300         fid = n;
00301 
00302         update_internal (force);
00303       }
00304   }
00305 
00306 private:
00307 
00308   // Open file descriptor.
00309   int fid;
00310 
00311   void update_internal (bool force = false);
00312 };
00313 
00314 #endif
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Defines