/* PSPP - a program for statistical analysis.
- Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 1997-9, 2000, 2006, 2007, 2009, 2010, 2011 Free Software Foundation, Inc.
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
#include <unistd.h>
#include "data/settings.h"
-#include "libpspp/hash.h"
+#include "libpspp/hash-functions.h"
#include "libpspp/message.h"
#include "libpspp/str.h"
#include "libpspp/version.h"
#include "gl/dirname.h"
+#include "gl/dosname.h"
#include "gl/intprops.h"
#include "gl/minmax.h"
#include "gl/relocatable.h"
return NULL;
}
-/* Returns the directory part of FILE_NAME, as a malloc()'d
- string. */
-char *
-fn_dir_name (const char *file_name)
-{
- return dir_name (file_name);
-}
-
/* Returns the extension part of FILE_NAME as a malloc()'d string.
If FILE_NAME does not have an extension, returns an empty
string. */
return IS_ABSOLUTE_FILE_NAME (name);
}
-/* Returns true if FILE_NAME is a virtual file that doesn't
- really exist on disk, false if it's a real file name. */
-bool
-fn_is_special (const char *file_name)
-{
- if (!strcmp (file_name, "-") || !strcmp (file_name, "stdin")
- || !strcmp (file_name, "stdout") || !strcmp (file_name, "stderr")
-#ifdef HAVE_POPEN
- || file_name[0] == '|'
- || (*file_name && file_name[strlen (file_name) - 1] == '|')
-#endif
- )
- return true;
-
- return false;
-}
-
-/* Returns true if file with name NAME exists. */
+/* Returns true if file with name NAME exists, and that file is not a
+ directory */
bool
fn_exists (const char *name)
{
struct stat temp;
- return stat (name, &temp) == 0;
-}
-\f
-/* Environment variables. */
+ if ( stat (name, &temp) != 0 )
+ return false;
-/* Simulates $VER and $ARCH environment variables. */
-const char *
-fn_getenv (const char *s)
-{
- if (!strcmp (s, "VER"))
- return fn_getenv_default ("STAT_VER", bare_version);
- else if (!strcmp (s, "ARCH"))
- return fn_getenv_default ("STAT_ARCH", host_system);
- else
- return getenv (s);
+ return ! S_ISDIR (temp.st_mode);
}
-/* Returns getenv(KEY) if that's non-NULL; else returns DEF. */
-const char *
-fn_getenv_default (const char *key, const char *def)
-{
- const char *value = getenv (key);
- return value ? value : def;
-}
\f
/* Basic file handling. */
static FILE *
safety_violation (const char *fn)
{
- msg (SE, _("Not opening pipe file `%s' because SAFER option set."), fn);
+ msg (SE, _("Not opening pipe file `%s' because %s option set."), fn, "SAFER");
errno = EPERM;
return NULL;
}
}
else
#endif
- {
- FILE *f = fopen (fn, mode);
-
- if (f && mode[0] != 'r')
- setvbuf (f, NULL, _IOLBF, 0);
-
- return f;
- }
+ return fopen (fn, mode);
}
/* Counterpart to fn_open that closes file F with name FN; returns 0
return fclose (f);
}
-/* Creates a new file named FN with the given PERMISSIONS bits,
- and returns a stream for it or a null pointer on failure.
- MODE should be "w" or "wb". */
-FILE *
-create_stream (const char *fn, const char *mode, mode_t permissions)
-{
- int fd;
- FILE *stream;
-
- fd = open (fn, O_WRONLY | O_CREAT | O_TRUNC, permissions);
- if (fd < 0)
- return NULL;
-
- stream = fdopen (fd, mode);
- if (stream == NULL)
- {
- int save_errno = errno;
- close (fd);
- errno = save_errno;
- }
-
- return stream;
-}
/* A file's identity:
there. */
struct file_identity
{
- dev_t device; /* Device number. */
- ino_t inode; /* Inode number. */
+ unsigned long long device; /* Device number. */
+ unsigned long long inode; /* Inode number. */
char *name; /* File name, where needed, otherwise NULL. */
};
free (dir);
}
#else /* Windows */
- char cname[PATH_MAX];
- int ok = GetFullPathName (file_name, sizeof cname, cname, NULL);
- identity->device = 0;
- identity->inode = 0;
- identity->name = xstrdup (ok ? cname : file_name);
- str_lowercase (identity->name);
+ bool ok = false;
+ HANDLE h = CreateFile (file_name, GENERIC_READ, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_READONLY, NULL);
+ if (h != INVALID_HANDLE_VALUE)
+ {
+ BY_HANDLE_FILE_INFORMATION fi;
+ ok = GetFileInformationByHandle (h, &fi);
+ if (ok)
+ {
+ identity->device = fi.dwVolumeSerialNumber;
+ identity->inode = fi.nFileIndexHigh;
+ identity->inode <<= (sizeof fi.nFileIndexLow) * CHAR_BIT;
+ identity->inode |= fi.nFileIndexLow;
+ identity->name = 0;
+ }
+ CloseHandle (h);
+ }
+
+ if (!ok)
+ {
+ identity->device = 0;
+ identity->inode = 0;
+
+ size_t bufsize;
+ size_t pathlen = 255;
+ char *cname = NULL;
+ do
+ {
+ bufsize = pathlen;
+ cname = xrealloc (cname, bufsize);
+ pathlen = GetFullPathName (file_name, bufsize, cname, NULL);
+ }
+ while (pathlen > bufsize);
+ identity->name = xstrdup (cname);
+ free (cname);
+ str_lowercase (identity->name);
+ }
#endif /* Windows */
return identity;