Skip to content

Instantly share code, notes, and snippets.

@stefaang
Forked from billziss-gh/cygwin-ls
Last active April 8, 2019 11:37
Show Gist options
  • Save stefaang/3429fcbac1dadd69db6f36c59d6ca98e to your computer and use it in GitHub Desktop.
Save stefaang/3429fcbac1dadd69db6f36c59d6ca98e to your computer and use it in GitHub Desktop.
Cygwin ls and hidden files
#!/bin/python
import os
import sys
import argparse
parser = argparse.ArgumentParser(description='List with cygwin')
parser.add_argument('-a', '--all', action='store_true', help='include all files')
parser.add_argument('-A', '--almost-all', action='store_true', help='include all files except . and ..')
args = parser.parse_args(sys.argv[1:])
if not (args.all or args.almost_all):
dllname = "cygwin_ls_readdir.dll"
progdir = os.path.dirname(sys.argv[0])
dllpath = os.path.join(progdir, "plat", os.uname()[0], dllname)
if not os.path.exists(dllpath):
os.makedirs(os.path.dirname(dllpath))
os.spawnl(os.P_WAIT, "/bin/bash",
"/bin/bash", os.path.join(progdir, "../src", os.path.splitext(dllname)[0] + ".c"), "-o", dllpath)
os.putenv("LD_PRELOAD", dllpath)
os.execv("/bin/ls", ["/bin/ls"] + sys.argv[1:])
///usr/bin/gcc -shared "$0" "$@" -lntdll; exit
// Written by Bill Zissimopoulos, 2015-2017.
#include <dirent.h>
#include <io.h>
#include <sys/cygwin.h>
#include <wchar.h>
#include <winternl.h>
#if 0
#include <stdio.h>
#define TRACE(...) fprintf(stderr, __VA_ARGS__)
#else
#define TRACE(...) ((void)0)
#endif
static struct dirent *(*real_readdir)(DIR *dirp);
struct dirent *readdir(DIR *dirp)
{
NTSTATUS NTAPI NtQueryAttributesFile(
POBJECT_ATTRIBUTES ObjectAttributes,
PFILE_BASIC_INFORMATION FileInformation);
HANDLE h;
struct dirent *dirent;
WCHAR name[NAME_MAX + 1];
UNICODE_STRING uname;
OBJECT_ATTRIBUTES obja;
FILE_BASIC_INFORMATION info;
NTSTATUS status;
h = (HANDLE)_get_osfhandle(dirfd(dirp));
if ((HANDLE)-1 == h)
return real_readdir(dirp);
while (0 != (dirent = real_readdir(dirp)))
{
if ('.' == dirent->d_name[0] && ('\0' == dirent->d_name[1] ||
('.' == dirent->d_name[1] && '\0' == dirent->d_name[2])))
break;
if (0 != cygwin_conv_path(CCP_POSIX_TO_WIN_W | CCP_RELATIVE, dirent->d_name, name, sizeof name))
break;
uname.Length = uname.MaximumLength = wcslen(name) * sizeof(WCHAR);
uname.Buffer = name;
InitializeObjectAttributes(&obja, &uname, 0, h, 0);
status = NtQueryAttributesFile(&obja, &info);
TRACE("%s: NtQueryAttributesFile(\"%ls\")=%lx\n", __func__, uname.Buffer, status);
if (!NT_SUCCESS(status) || 0 == (info.FileAttributes & FILE_ATTRIBUTE_HIDDEN))
break;
}
TRACE("%s: name=\"%s\"\n", __func__, 0 != dirent ? dirent->d_name : (char *)0);
return dirent;
}
static __attribute__((constructor)) void init(void)
{
real_readdir = (void *)cygwin_internal(CW_HOOK, "readdir", readdir);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment