Mercurial > hg > octave-lyh
diff liboctave/file-ops.cc @ 2926:66ef74ee5d9f
[project @ 1997-05-05 03:20:52 by jwe]
author | jwe |
---|---|
date | Mon, 05 May 1997 03:40:21 +0000 |
parents | 8b262e771614 |
children | dddc1b5c324e |
line wrap: on
line diff
--- a/liboctave/file-ops.cc +++ b/liboctave/file-ops.cc @@ -29,224 +29,43 @@ #include <cstdlib> #include <cstring> -#ifdef HAVE_UNISTD_H +#include <iostream.h> + #ifdef HAVE_SYS_TYPES_H #include <sys/types.h> #endif + +#ifdef HAVE_UNISTD_H #include <unistd.h> #endif -#include "error.h" +#ifdef HAVE_PWD_H +#include <pwd.h> +#endif + #include "file-ops.h" #include "lo-error.h" +#include "oct-env.h" #include "statdefs.h" - -// These must come after <sys/types.h> and <sys/stat.h>. - -#include <safe-lstat.h> -#include <safe-stat.h> - -// XXX FIXME XXX -- the is_* and mode_as_string functions are only valid -// for initialized objects. If called for an object that is not -// initialized, they should throw an exception. - -bool -file_stat::is_blk (void) const -{ -#ifdef S_ISBLK - return S_ISBLK (fs_mode); -#else - return false; -#endif -} - -bool -file_stat::is_chr (void) const -{ -#ifdef S_ISCHR - return S_ISCHR (fs_mode); -#else - return false; -#endif -} - -bool -file_stat::is_dir (void) const -{ -#ifdef S_ISDIR - return S_ISDIR (fs_mode); -#else - return false; -#endif -} - -bool -file_stat::is_fifo (void) const -{ -#ifdef S_ISFIFO - return S_ISFIFO (fs_mode); -#else - return false; -#endif -} - -bool -file_stat::is_lnk (void) const -{ -#ifdef S_ISLNK - return S_ISLNK (fs_mode); -#else - return false; -#endif -} - -bool -file_stat::is_reg (void) const -{ -#ifdef S_ISREG - return S_ISREG (fs_mode); -#else - return false; -#endif -} - -bool -file_stat::is_sock (void) const -{ -#ifdef S_ISSOCK - return S_ISSOCK (fs_mode); -#else - return false; -#endif -} - -extern "C" void mode_string (); - -string -file_stat::mode_as_string (void) const -{ - char buf[11]; - - mode_string (fs_mode, buf); - - buf[10] = '\0'; - - return string (buf); -} - -// Private stuff: - -void -file_stat::update_internal (bool force) -{ - if (! initialized || force) - { - initialized = false; - fail = false; - - const char *cname = file_name.c_str (); - - struct stat buf; - - int status = follow_links - ? SAFE_STAT (cname, &buf) : SAFE_LSTAT (cname, &buf); - - if (status < 0) - { - fail = true; - errmsg = strerror (errno); - } - else - { - fs_mode = buf.st_mode; - fs_ino = buf.st_ino; - fs_dev = buf.st_dev; - fs_nlink = buf.st_nlink; - fs_uid = buf.st_uid; - fs_gid = buf.st_gid; - fs_size = buf.st_size; - fs_atime = buf.st_atime; - fs_mtime = buf.st_mtime; - fs_ctime = buf.st_ctime; - -#if defined (HAVE_ST_RDEV) - fs_rdev = buf.st_rdev; -#endif - -#if defined (HAVE_ST_BLKSIZE) - fs_blksize = buf.st_blksize; -#endif - -#if defined (HAVE_ST_BLOCKS) - fs_blocks = buf.st_blocks; -#endif - } - - initialized = true; - } -} - -void -file_stat::copy (const file_stat& fs) -{ - file_name = fs.file_name; - follow_links = fs.follow_links; - initialized = fs.initialized; - fail = fs.fail; - errmsg = fs.errmsg; - fs_mode = fs.fs_mode; - fs_ino = fs.fs_ino; - fs_dev = fs.fs_dev; - fs_nlink = fs.fs_nlink; - fs_uid = fs.fs_uid; - fs_gid = fs.fs_gid; - fs_size = fs.fs_size; - fs_atime = fs.fs_atime; - fs_mtime = fs.fs_mtime; - fs_ctime = fs.fs_ctime; - -#if defined (HAVE_ST_RDEV) - fs_rdev = fs.fs_rdev; -#endif - -#if defined (HAVE_ST_BLKSIZE) - fs_blksize = fs.fs_blksize; -#endif - -#if defined (HAVE_ST_BLOCKS) - fs_blocks = fs.fs_blocks; -#endif -} - -// Functions for octave. - -// Has FILE been modified since TIME? Returns 1 for yes, 0 for no, -// and -1 for any error. -int -is_newer (const string& file, time_t time) -{ - file_stat fs (file); - - return fs ? fs.is_newer (time) : -1; -} +#include "str-vec.h" // We provide a replacement for mkdir(). int -oct_mkdir (const string& name, mode_t mode) +file_ops::mkdir (const string& name, mode_t mode) { - return mkdir (name.c_str (), mode); + return ::mkdir (name.c_str (), mode); } int -oct_mkdir (const string& name, mode_t mode, string& msg) +file_ops::mkdir (const string& name, mode_t mode, string& msg) { msg = string (); - int status = mkdir (name.c_str (), mode); + int status = ::mkdir (name.c_str (), mode); if (status < 0) - msg = strerror (errno); + msg = ::strerror (errno); return status; } @@ -254,30 +73,32 @@ // I don't know how to emulate this on systems that don't provide it. int -oct_mkfifo (const string& name, mode_t mode) +file_ops::mkfifo (const string& name, mode_t mode) { #if defined (HAVE_MKFIFO) - return mkfifo (name.c_str (), mode); + return ::mkfifo (name.c_str (), mode); #else - ::error ("mkfifo: not implemented on this system"); + (*current_liboctave_error_handler) + ("mkfifo: not implemented on this system"); return -1; #endif } int -oct_mkfifo (const string& name, mode_t mode, string& msg) +file_ops::mkfifo (const string& name, mode_t mode, string& msg) { msg = string (); #if defined (HAVE_MKFIFO) - int status = mkfifo (name.c_str (), mode); + int status = ::mkfifo (name.c_str (), mode); if (status < 0) - msg = strerror (errno); + msg = ::strerror (errno); return status; #else - ::error ("mkfifo: not implemented on this system"); + (*current_liboctave_error_handler) + ("mkfifo: not implemented on this system"); return -1; #endif } @@ -285,20 +106,20 @@ // We provide a replacement for rename(). int -oct_rename (const string& from, const string& to) +file_ops::rename (const string& from, const string& to) { - return rename (from.c_str (), to.c_str ()); + return ::rename (from.c_str (), to.c_str ()); } int -oct_rename (const string& from, const string& to, string& msg) +file_ops::rename (const string& from, const string& to, string& msg) { msg = string (); - int status = rename (from.c_str (), to.c_str ()); + int status = ::rename (from.c_str (), to.c_str ()); if (status < 0) - msg = strerror (errno); + msg = ::strerror (errno); return status; } @@ -306,20 +127,20 @@ // We provide a replacement for rmdir(). int -oct_rmdir (const string& name) +file_ops::rmdir (const string& name) { - return rmdir (name.c_str ()); + return ::rmdir (name.c_str ()); } int -oct_rmdir (const string& name, string& msg) +file_ops::rmdir (const string& name, string& msg) { msg = string (); - int status = rmdir (name.c_str ()); + int status = ::rmdir (name.c_str ()); if (status < 0) - msg = strerror (errno); + msg = ::strerror (errno); return status; } @@ -327,11 +148,11 @@ // We provide a replacement for tempnam(). string -oct_tempnam (void) +file_ops::tempnam (void) { string retval; - char *tmp = tempnam (0, "oct-"); + char *tmp = ::tempnam (0, "oct-"); if (tmp) { @@ -345,32 +166,119 @@ return retval; } +// If NAME has a leading ~ or ~user, Unix-style, expand it to the +// user's home directory. If no ~, or no <pwd.h>, just return NAME. + +// Mostly stolen from kpathsea. Readline also has a more complicated +// tilde-expand function, but we can probalby get by with something a +// bit simpler. + +// XXX FIXME XXX +#define DIR_SEP_CHAR '/' + +string +file_ops::tilde_expand (const string& name) +{ + string expansion = name; + +#if defined (HAVE_PWD_H) + + // If no leading tilde, do nothing. + + size_t beg = name.find_first_not_of (" \t"); + + if (beg != NPOS && name[beg] == '~') + { + // If `~' or `~/', use $HOME if it exists, or `.' if it doesn't. + + // If `~user' or `~user/', look up user in the passwd database. + + size_t len = name.length (); + + if (beg == len-1 || name[beg+1] == DIR_SEP_CHAR) + { + string home = octave_env::get_home_directory (); + + if (home.empty ()) + home = "."; + + expansion = name.substr (0, beg) + home; + + if (beg < len) + expansion.append (name.substr (beg+1)); + } + else + { + size_t end = name.find (DIR_SEP_CHAR, beg); + + size_t len = end; + + if (len != NPOS) + len -= beg + 1; + + string user = name.substr (beg+1, len); + + struct passwd *p + = static_cast<struct passwd *> (::getpwnam (user.c_str ())); + + // If no such user, just use `.'. + + string home = p ? p->pw_dir : "."; + + expansion = string (" ", beg) + home; + + if (end != NPOS) + expansion.append (name.substr (end)); + } + } + +#endif + + return expansion; +} + +// A vector version of the above. + +string_vector +file_ops::tilde_expand (const string_vector& names) +{ + string_vector retval; + + int n = names.length (); + + retval.resize (n); + + for (int i = 0; i < n; i++) + retval[i] = file_ops::tilde_expand (names[i]); + + return retval; +} int -oct_umask (mode_t mode) +file_ops::umask (mode_t mode) { #if defined (HAVE_UMASK) - return umask (mode); + return ::umask (mode); #else return 0; #endif } int -oct_unlink (const string& name) +file_ops::unlink (const string& name) { - return unlink (name.c_str ()); + return ::unlink (name.c_str ()); } int -oct_unlink (const string& name, string& errmsg) +file_ops::unlink (const string& name, string& errmsg) { errmsg = string (); - int status = unlink (name.c_str ()); + int status = ::unlink (name.c_str ()); if (status < 0) - errmsg = strerror (errno); + errmsg = ::strerror (errno); return status; }