diff options
Diffstat (limited to 'extension')
-rw-r--r-- | extension/ChangeLog | 30 | ||||
-rw-r--r-- | extension/filefuncs.c | 27 | ||||
-rw-r--r-- | extension/gawkdirfd.h | 8 | ||||
-rw-r--r-- | extension/inplace.c | 18 | ||||
-rw-r--r-- | extension/readdir.c | 86 | ||||
-rw-r--r-- | extension/rwarray.c | 4 |
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> |