aboutsummaryrefslogtreecommitdiffstats
path: root/extension
diff options
context:
space:
mode:
Diffstat (limited to 'extension')
-rw-r--r--extension/ChangeLog30
-rw-r--r--extension/filefuncs.c27
-rw-r--r--extension/gawkdirfd.h8
-rw-r--r--extension/inplace.c18
-rw-r--r--extension/readdir.c86
-rw-r--r--extension/rwarray.c4
6 files changed, 163 insertions, 10 deletions
diff --git a/extension/ChangeLog b/extension/ChangeLog
index e01d6d14..ef2bcb9b 100644
--- a/extension/ChangeLog
+++ b/extension/ChangeLog
@@ -1,3 +1,33 @@
+2013-05-14 Eli Zaretskii <eliz@gnu.org>
+
+ * rwarray.c [__MINGW32__]: Include winsock2.h instead of
+ arpa/inet.h.
+
+ * readdir.c [__MINGW32__]: Include windows.h.
+ Include gawkapi.h before gawkdirfd.h, since the former defines
+ FAKE_FD_VALUE needed by the latter.
+ (ftype): Accept an additional argument, the directory that is
+ being read. Callers changed.
+ [!DT_BLK]: Produce the file's type by calling 'stat' on it, if the
+ dirent structure doesn't provide that.
+ (get_inode): New function, to produce inode values on MS-Windows.
+ (dir_get_record): Use it.
+
+ * inplace.c (chown, link) [__MINGW32__]: Redirect to existing
+ library functions.
+ (mkstemp) [__MINGW32__]: New function, for MinGW, which doesn't
+ have it in its library.
+ (do_inplace_end) [__MINGW32__]: Remove the old file before
+ renaming the new, since 'rename' on Windows cannot overwrite
+ existing files.
+
+ * gawkdirfd.h (ENOTSUP): Define to ENOSYS if not already defined.
+ (DIR_TO_FD): If not defined yet, define to FAKE_FD_VALUE.
+
+ * filefuncs.c (get_inode) [_WIN32]: New function, produces the
+ file index used on Windows as its inode.
+ (fill_stat_array) [_WIN32]: Use it.
+
2013-05-09 Arnold D. Robbins <arnold@skeeve.com>
* 4.1.0: Release tar ball made.
diff --git a/extension/filefuncs.c b/extension/filefuncs.c
index 1e8fc8d0..277bb45f 100644
--- a/extension/filefuncs.c
+++ b/extension/filefuncs.c
@@ -73,6 +73,29 @@
#define S_ISVTX 0
#define major(s) (s)
#define minor(s) (0)
+
+#include <windows.h>
+
+/* get_inode --- get the inode of a file */
+static long long
+get_inode(const char *fname)
+{
+ HANDLE fh;
+ BY_HANDLE_FILE_INFORMATION info;
+
+ fh = CreateFile(fname, 0, 0, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (fh == INVALID_HANDLE_VALUE)
+ return 0;
+ if (GetFileInformationByHandle(fh, &info)) {
+ long long inode = info.nFileIndexHigh;
+
+ inode <<= 32;
+ inode += info.nFileIndexLow;
+ return inode;
+ }
+ return 0;
+}
#endif
static const gawk_api_t *api; /* for convenience macros to work */
@@ -302,7 +325,11 @@ fill_stat_array(const char *name, awk_array_t array, struct stat *sbuf)
/* fill in the array */
array_set(array, "name", make_const_string(name, strlen(name), & tmp));
array_set_numeric(array, "dev", sbuf->st_dev);
+#ifdef _WIN32
+ array_set_numeric(array, "ino", (double)get_inode (name));
+#else
array_set_numeric(array, "ino", sbuf->st_ino);
+#endif
array_set_numeric(array, "mode", sbuf->st_mode);
array_set_numeric(array, "nlink", sbuf->st_nlink);
array_set_numeric(array, "uid", sbuf->st_uid);
diff --git a/extension/gawkdirfd.h b/extension/gawkdirfd.h
index 1fbd6f57..e75f9bce 100644
--- a/extension/gawkdirfd.h
+++ b/extension/gawkdirfd.h
@@ -21,6 +21,14 @@
#include <config.h>
+#ifndef ENOTSUP
+# define ENOTSUP ENOSYS
+#endif
+
+#ifndef DIR_TO_FD
+# define DIR_TO_FD(d) (FAKE_FD_VALUE)
+#endif
+
#if !defined(HAVE_DIRFD) && (!defined(HAVE_DECL_DIRFD) || HAVE_DECL_DIRFD == 0)
int
dirfd (DIR *dir_p)
diff --git a/extension/inplace.c b/extension/inplace.c
index ded4746c..ad6f0e23 100644
--- a/extension/inplace.c
+++ b/extension/inplace.c
@@ -51,6 +51,20 @@
#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
#endif
+#ifdef __MINGW32__
+# define chown(x,y,z) (0)
+# define link(f1,f2) rename(f1,f2)
+int
+mkstemp (char *template)
+{
+ char *tmp_fname = _mktemp (template);
+
+ if (tmp_fname)
+ return _open (tmp_fname, O_RDWR | O_CREAT | O_EXCL, S_IREAD | S_IWRITE);
+ return -1;
+}
+#endif
+
static const gawk_api_t *api; /* for convenience macros to work */
static awk_ext_id_t *ext_id;
static const char *ext_version = "inplace extension: version 1.0";
@@ -225,6 +239,10 @@ do_inplace_end(int nargs, awk_value_t *result)
free(bakname);
}
+#ifdef __MINGW32__
+ unlink(filename.str_value.str);
+#endif
+
if (rename(state.tname, filename.str_value.str) < 0)
fatal(ext_id, _("inplace_end: rename(`%s', `%s') failed (%s)"),
state.tname, filename.str_value.str, strerror(errno));
diff --git a/extension/readdir.c b/extension/readdir.c
index 5ca4dc63..9d53ad9a 100644
--- a/extension/readdir.c
+++ b/extension/readdir.c
@@ -50,10 +50,14 @@
#error Cannot compile the dirent extension on this system!
#endif
-#include "gawkdirfd.h"
+#ifdef __MINGW32__
+#include <windows.h>
+#endif
#include "gawkapi.h"
+#include "gawkdirfd.h"
+
#include "gettext.h"
#define _(msgid) gettext(msgid)
#define N_(msgid) msgid
@@ -77,7 +81,7 @@ typedef struct open_directory {
/* ftype --- return type of file as a single character string */
static const char *
-ftype(struct dirent *entry)
+ftype(struct dirent *entry, const char *dirname)
{
#ifdef DT_BLK
switch (entry->d_type) {
@@ -92,10 +96,67 @@ ftype(struct dirent *entry)
case DT_UNKNOWN: return "u";
}
#else
+ char fname[PATH_MAX];
+ struct stat sbuf;
+
+ strcpy(fname, dirname);
+ strcat(fname, "/");
+ strcat(fname, entry->d_name);
+ if (stat(fname, &sbuf) == 0) {
+ if (S_ISBLK(sbuf.st_mode))
+ return "b";
+ if (S_ISCHR(sbuf.st_mode))
+ return "c";
+ if (S_ISDIR(sbuf.st_mode))
+ return "d";
+ if (S_ISFIFO(sbuf.st_mode))
+ return "p";
+ if (S_ISREG(sbuf.st_mode))
+ return "f";
+#ifdef S_ISLNK
+ if (S_ISLNK(sbuf.st_mode))
+ return "l";
+#endif
+#ifdef S_ISSOCK
+ if (S_ISSOCK(sbuf.st_mode))
+ return "s";
+#endif
+ }
return "u";
#endif
}
+/* get_inode --- get the inode of a file */
+#ifdef ZOS_USS
+static long
+#else
+static long long
+#endif
+get_inode(struct dirent *entry, const char *dirname)
+{
+#ifdef __MINGW32__
+ char fname[PATH_MAX];
+ HANDLE fh;
+ BY_HANDLE_FILE_INFORMATION info;
+
+ sprintf(fname, "%s\\%s", dirname, entry->d_name);
+ fh = CreateFile(fname, 0, 0, NULL, OPEN_EXISTING,
+ FILE_FLAG_BACKUP_SEMANTICS, NULL);
+ if (fh == INVALID_HANDLE_VALUE)
+ return 0;
+ if (GetFileInformationByHandle(fh, &info)) {
+ long long inode = info.nFileIndexHigh;
+
+ inode <<= 32;
+ inode += info.nFileIndexLow;
+ return inode;
+ }
+ return 0;
+#else
+ return entry->d_ino;
+#endif
+}
+
/* dir_get_record --- get one record at a time out of a directory */
static int
@@ -107,6 +168,11 @@ dir_get_record(char **out, awk_input_buf_t *iobuf, int *errcode,
int len;
open_directory_t *the_dir;
const char *ftstr;
+#ifdef ZOS_USS
+ unsigned long ino;
+#else
+ unsigned long long ino;
+#endif
/*
* The caller sets *errcode to 0, so we should set it only if an
@@ -129,17 +195,17 @@ dir_get_record(char **out, awk_input_buf_t *iobuf, int *errcode,
return EOF;
}
-#ifdef ZOS_USS
- len = sprintf(the_dir->buf, "%lu/%s",
- (unsigned long) dirent->d_ino,
- dirent->d_name);
+ ino = get_inode (dirent, iobuf->name);
+
+#if defined(ZOS_USS)
+ len = sprintf(the_dir->buf, "%lu/%s", ino, dirent->d_name);
+#elif __MINGW32__
+ len = sprintf(the_dir->buf, "%I64u/%s", ino, dirent->d_name);
#else
- len = sprintf(the_dir->buf, "%llu/%s",
- (unsigned long long) dirent->d_ino,
- dirent->d_name);
+ len = sprintf(the_dir->buf, "%llu/%s", ino, dirent->d_name);
#endif
- ftstr = ftype(dirent);
+ ftstr = ftype(dirent, iobuf->name);
len += sprintf(the_dir->buf + len, "/%s", ftstr);
*out = the_dir->buf;
diff --git a/extension/rwarray.c b/extension/rwarray.c
index d7b26c4a..6185000b 100644
--- a/extension/rwarray.c
+++ b/extension/rwarray.c
@@ -39,7 +39,11 @@
#include <string.h>
#include <unistd.h>
+#ifdef __MINGW32__
+#include <winsock2.h>
+#else
#include <arpa/inet.h>
+#endif
#include <sys/types.h>
#include <sys/stat.h>