X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=src%2Ffilename.c;h=b78897e211bc2be19fec1e01e62e177bcce69e51;hb=012b055f5f7b4ddd2a608e64c53eaae101b5634e;hp=4aaf7d17f916d5c92aca4d4d2aad8f11d07376e9;hpb=4944c86a9318bc5b5578ab145a95c116ffd2c9fd;p=pspp-builds.git diff --git a/src/filename.c b/src/filename.c index 4aaf7d17..b78897e2 100644 --- a/src/filename.c +++ b/src/filename.c @@ -14,53 +14,40 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - 02111-1307, USA. */ + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. */ -/* AIX requires this to be the first thing in the file. */ #include -#if __GNUC__ -#define alloca __builtin_alloca -#else -#if HAVE_ALLOCA_H -#include -#else -#ifdef _AIX -#pragma alloca -#else -#ifndef alloca /* predefined by HP cc +Olibcalls */ -char *alloca (); -#endif -#endif -#endif -#endif - -#include +#include "error.h" +#include "filename.h" +#include #include #include #include #include "alloc.h" #include "error.h" -#include "filename.h" #include "settings.h" #include "str.h" #include "version.h" +#include "xreadlink.h" + +#include "gettext.h" +#define _(msgid) gettext (msgid) -#undef DEBUGGING -/*#define DEBUGGING 1 */ #include "debug-print.h" /* PORTME: Everything in this file is system dependent. */ -#if unix +#ifdef unix #include #if HAVE_UNISTD_H #include #endif -#include "stat.h" +#include +#include "stat-macros.h" #endif -#if __WIN32__ +#ifdef __WIN32__ #define NOGDI #define NOUSER #define NONLS @@ -94,20 +81,20 @@ fn_interp_vars (const char *input, const char *(*getenv) (const char *)) if (NULL == strchr (input, '$')) return xstrdup (input); - ds_init (NULL, &output, strlen (input)); + ds_init (&output, strlen (input)); for (;;) switch (*input) { case '\0': - return ds_value (&output); + return ds_c_str (&output); case '$': input++; if (*input == '$') { - ds_putchar (&output, '$'); + ds_putc (&output, '$'); input++; } else @@ -133,22 +120,22 @@ fn_interp_vars (const char *input, const char *(*getenv) (const char *)) while (*input && *input != stop && (stop || isalpha ((unsigned char) *input))) - ds_putchar (&output, *input++); + ds_putc (&output, *input++); - value = getenv (ds_value (&output) + start); + value = getenv (ds_c_str (&output) + start); ds_truncate (&output, start); - ds_concat (&output, value); + ds_puts (&output, value); if (stop && *input == stop) input++; } default: - ds_putchar (&output, *input++); + ds_putc (&output, *input++); } } -#if unix +#ifdef unix /* Expands csh tilde notation from the path INPUT into a malloc()'d returned string. */ char * @@ -159,13 +146,13 @@ fn_tilde_expand (const char *input) if (NULL == strchr (input, '~')) return xstrdup (input); - ds_init (NULL, &output, strlen (input)); + ds_init (&output, strlen (input)); ip = input; for (ip = input; *ip; ) if (*ip != '~' || (ip != input && ip[-1] != PATH_DELIMITER)) - ds_putchar (&output, *ip++); + ds_putc (&output, *ip++); else { static const char stop_set[3] = {DIR_SEPARATOR, PATH_DELIMITER, 0}; @@ -185,27 +172,27 @@ fn_tilde_expand (const char *input) pwd = getpwnam (username); if (!pwd || !pwd->pw_dir) - ds_putchar (&output, *ip++); + ds_putc (&output, *ip++); else - ds_concat (&output, pwd->pw_dir); + ds_puts (&output, pwd->pw_dir); } else { const char *home = fn_getenv ("HOME"); if (!home) - ds_putchar (&output, *ip++); + ds_putc (&output, *ip++); else - ds_concat (&output, home); + ds_puts (&output, home); } ip = cp; } - return ds_value (&output); + return ds_c_str (&output); } #else /* !unix */ char * -fn_tilde_expand (char *input) +fn_tilde_expand (const char *input) { return xstrdup (input); } @@ -220,7 +207,7 @@ fn_tilde_expand (char *input) If PREPEND is non-NULL, then it is prepended to each filename; i.e., it looks like PREPEND/PATH_COMPONENT/NAME. This is not done with absolute directories in the path. */ -#if unix || __MSDOS__ || __WIN32__ +#if defined (unix) || defined (__MSDOS__) || defined (__WIN32__) char * fn_search_path (const char *basename, const char *path, const char *prepend) { @@ -238,7 +225,7 @@ fn_search_path (const char *basename, const char *path, const char *prepend) } msg (VM (4), _("Searching for `%s'..."), basename); - ds_init (NULL, &filename, 64); + ds_init (&filename, 64); for (;;) { @@ -258,21 +245,21 @@ fn_search_path (const char *basename, const char *path, const char *prepend) ds_clear (&filename); if (prepend && !fn_absolute_p (bp)) { - ds_concat (&filename, prepend); - ds_putchar (&filename, DIR_SEPARATOR); + ds_puts (&filename, prepend); + ds_putc (&filename, DIR_SEPARATOR); } - ds_concat_buffer (&filename, bp, ep - bp); + ds_concat (&filename, bp, ep - bp); if (ep - bp - && ds_value (&filename)[ds_length (&filename) - 1] != DIR_SEPARATOR) - ds_putchar (&filename, DIR_SEPARATOR); - ds_concat (&filename, basename); + && ds_c_str (&filename)[ds_length (&filename) - 1] != DIR_SEPARATOR) + ds_putc (&filename, DIR_SEPARATOR); + ds_puts (&filename, basename); - msg (VM (5), " - %s", ds_value (&filename)); - if (fn_exists_p (ds_value (&filename))) + msg (VM (5), " - %s", ds_c_str (&filename)); + if (fn_exists_p (ds_c_str (&filename))) { - msg (VM (4), _("Found `%s'."), ds_value (&filename)); + msg (VM (4), _("Found `%s'."), ds_c_str (&filename)); free (subst_path); - return ds_value (&filename); + return ds_c_str (&filename); } if (0 == *ep) @@ -336,7 +323,7 @@ fn_prepend_dir (const char *file, const char *dir) existing file. Returns a malloc()'d copy of the canonical name. This function must always succeed; if it needs to bail out then it should return xstrdup(FN1). */ -#if unix +#ifdef unix char * fn_normalize (const char *filename) { @@ -373,16 +360,10 @@ fn_normalize (const char *filename) else { errno = 0; -#if __CHECKER__ - memset (dest, 0, maxlen); -#endif while (getcwd (dest, maxlen - (dest - fn2)) == NULL && errno == ERANGE) { maxlen *= 2; dest = fn2 = xrealloc (fn2, maxlen + 1); -#if __CHECKER__ - memset (dest, 0, maxlen); -#endif errno = 0; } if (errno) @@ -452,7 +433,7 @@ fn_normalize (const char *filename) } } } -#elif __WIN32__ +#elif defined (__WIN32__) char * fn_normalize (const char *fn1) { @@ -527,7 +508,7 @@ fn_dirname (const char *filename) if (len == 1 && filename[0] == '/') p = filename + 1; else if (len && filename[len - 1] == DIR_SEPARATOR) - p = mm_find_reverse (filename, len - 1, filename + len - 1, 1); + p = buf_find_reverse (filename, len - 1, filename + len - 1, 1); else p = strrchr (filename, DIR_SEPARATOR); if (p == NULL) @@ -550,6 +531,7 @@ fn_basename (const char *filename) } #endif +#if unix /* Returns the current working directory, as a malloc()'d string. From libc.info. */ char * @@ -569,6 +551,22 @@ fn_get_cwd (void) buffer = xmalloc (size); } } +#else +char * +fn_get_cwd (void) +{ + int size = 2; + char *buffer = xmalloc (size); + if ( buffer) + { + buffer[0]='.'; + buffer[1]='\0'; + } + + return buffer; + +} +#endif /* Find out information about files. */ @@ -576,13 +574,13 @@ fn_get_cwd (void) int fn_absolute_p (const char *name) { -#if unix +#ifdef unix if (name[0] == '/' || !strncmp (name, "./", 2) || !strncmp (name, "../", 3) || name[0] == '~') return 1; -#elif __MSDOS__ +#elif defined (__MSDOS__) if (name[0] == '\\' || !strncmp (name, ".\\", 2) || !strncmp (name, "..\\", 3) @@ -600,7 +598,7 @@ fn_special_p (const char *filename) { if (!strcmp (filename, "-") || !strcmp (filename, "stdin") || !strcmp (filename, "stdout") || !strcmp (filename, "stderr") -#if unix +#ifdef unix || filename[0] == '|' || (*filename && filename[strlen (filename) - 1] == '|') #endif @@ -614,7 +612,7 @@ fn_special_p (const char *filename) int fn_exists_p (const char *name) { -#if unix +#ifdef unix struct stat temp; return stat (name, &temp) == 0; @@ -627,40 +625,13 @@ fn_exists_p (const char *name) #endif } -#if unix -/* Stolen from libc.info but heavily modified, this is a wrapper - around readlink() that allows for arbitrary filename length. */ -char * -fn_readlink (const char *filename) -{ - int size = 128; - - for (;;) - { - char *buffer = xmalloc (size); - int nchars = readlink (filename, buffer, size); - if (nchars == -1) - { - free (buffer); - return NULL; - } - - if (nchars < size - 1) - { - buffer[nchars] = 0; - return buffer; - } - free (buffer); - size *= 2; - } -} -#else /* Not UNIX. */ +/* Returns the symbolic link value for FILENAME as a dynamically + allocated buffer, or a null pointer on failure. */ char * fn_readlink (const char *filename) { - return NULL; + return xreadlink (filename, 32); } -#endif /* Not UNIX. */ /* Environment variables. */ @@ -717,10 +688,10 @@ fn_open (const char *fn, const char *mode) else if (mode[0] == 'w' && !strcmp (fn, "stderr")) return stderr; -#if unix +#ifdef unix if (fn[0] == '|') { - if (set_safer) + if (get_safer_mode ()) return safety_violation (fn); return popen (&fn[1], mode); @@ -730,7 +701,7 @@ fn_open (const char *fn, const char *mode) char *s; FILE *f; - if (set_safer) + if (get_safer_mode ()) return safety_violation (fn); s = local_alloc (strlen (fn)); @@ -763,7 +734,7 @@ fn_close (const char *fn, FILE *f) { if (!strcmp (fn, "-")) return 0; -#if unix +#ifdef unix else if (fn[0] == '|' || (*fn && fn[strlen (fn) - 1] == '|')) { pclose (f); @@ -879,3 +850,93 @@ fn_close_ext (struct file_ext *f) } return 1; } + +#ifdef unix +/* A file's identity. */ +struct file_identity + { + dev_t device; /* Device number. */ + ino_t inode; /* Inode number. */ + }; + +/* Returns a pointer to a dynamically allocated structure whose + value can be used to tell whether two files are actually the + same file. Returns a null pointer if no information about the + file is available, perhaps because it does not exist. The + caller is responsible for freeing the structure with + fn_free_identity() when finished. */ +struct file_identity * +fn_get_identity (const char *filename) +{ + struct stat s; + + if (stat (filename, &s) == 0) + { + struct file_identity *identity = xmalloc (sizeof *identity); + identity->device = s.st_dev; + identity->inode = s.st_ino; + return identity; + } + else + return NULL; +} + +/* Frees IDENTITY obtained from fn_get_identity(). */ +void +fn_free_identity (struct file_identity *identity) +{ + free (identity); +} + +/* Compares A and B, returning a strcmp()-type result. */ +int +fn_compare_file_identities (const struct file_identity *a, + const struct file_identity *b) +{ + assert (a != NULL); + assert (b != NULL); + if (a->device != b->device) + return a->device < b->device ? -1 : 1; + else + return a->inode < b->inode ? -1 : a->inode > b->inode; +} +#else /* not unix */ +/* A file's identity. */ +struct file_identity + { + char *normalized_filename; /* File's normalized name. */ + }; + +/* Returns a pointer to a dynamically allocated structure whose + value can be used to tell whether two files are actually the + same file. Returns a null pointer if no information about the + file is available, perhaps because it does not exist. The + caller is responsible for freeing the structure with + fn_free_identity() when finished. */ +struct file_identity * +fn_get_identity (const char *filename) +{ + struct file_identity *identity = xmalloc (sizeof *identity); + identity->normalized_filename = fn_normalize (filename); + return identity; +} + +/* Frees IDENTITY obtained from fn_get_identity(). */ +void +fn_free_identity (struct file_identity *identity) +{ + if (identity != NULL) + { + free (identity->normalized_filename); + free (identity); + } +} + +/* Compares A and B, returning a strcmp()-type result. */ +int +fn_compare_file_identities (const struct file_identity *a, + const struct file_identity *b) +{ + return strcmp (a->normalized_filename, b->normalized_filename); +} +#endif /* not unix */