diff options
Diffstat (limited to 'extension/readdir.c')
-rw-r--r-- | extension/readdir.c | 86 |
1 files changed, 76 insertions, 10 deletions
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; |