Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Porting to win32 #158

Merged
merged 1 commit into from

3 participants

@mattn

I ported ag to win32. I dropped color syntax on windows, But It's useful.
Thanks for your work.

@ggreer
Owner

I assume this requires cygwin? I don't have a windows machine to test it out on, but it doesn't break OS X so I'm merging it.

@ggreer ggreer merged commit e9befe3 into ggreer:master
@mattn

This patch does not require cygwin. It makes native win32 application.

@ggreer
Owner

Really? Wow. I didn't think windows had pthreads.

@mattn

If you want, I can remove dependency for pthreads. It's possible to use native thread APIs instead of pthreads.

@ggreer
Owner

It looks like there's a pthreads library for windows, so it's not necessary. Good work!

@mihaifm

@mattn
I compiled this for Windows and I ran into a problem on Win7.
It seems like MapViewOfFile sometimes fails with error 5: ERROR_ACCESS_DENIED
(btw the log_error calls for _WIN32 should use GetLastError instead of strerror(errno))
This seems to be happening for random files each time I run it, and only on Win7. On XP seems to be working fine.

Do you have any idea what might be going wrong here?

@mattn

@mihaifm Hmm, Can you figureout the way to reproduce?

@mattn

@mihaifm I fixed issue about GetLastError() in #170

@mihaifm

It replicates (inconsistently) when I try to search in a large directory.

If we encounter a failed memory map, I think we should attempt a simple read for the whole file into memory (valid for Unix as well).

Something like this.

It worked for me.

@ggreer
Owner

Is this happening on a 32-bit system of 64-bit? 32-bit can easily run out of address space when mmap()ing large files.

@mihaifm

@ggreer on Windows 7 64bit

@mattn mattn referenced this pull request from a commit in mattn/the_silver_searcher
@mattn mattn Fix ERROR_ACCESS_DENIED on windows #158 f150706
@mattn

@mihaifm Could you please try the patch below?

@mihaifm

@mattn very cool...that seems to take care of the problem

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 1, 2013
  1. @mattn

    Porting to win32

    mattn authored
This page is out of date. Refresh to see the latest.
View
11 src/ignore.c
@@ -1,6 +1,5 @@
#include <ctype.h>
#include <dirent.h>
-#include <fnmatch.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -12,6 +11,14 @@
#include "scandir.h"
#include "util.h"
+#ifdef _WIN32
+# include <shlwapi.h>
+# define fnmatch(x, y, z) (!PathMatchSpec(y,x))
+#else
+# include <fnmatch.h>
+const int fnmatch_flags = 0 & FNM_PATHNAME;
+#endif
+
/* TODO: build a huge-ass list of files we want to ignore by default (build cache stuff, pyc files, etc) */
const char *evil_hardcoded_ignore_files[] = {
@@ -30,8 +37,6 @@ const char *ignore_pattern_files[] = {
NULL
};
-const int fnmatch_flags = 0 & FNM_PATHNAME;
-
ignores *init_ignore(ignores *parent) {
ignores *ig = ag_malloc(sizeof(ignores));
ig->names = NULL;
View
11 src/main.c
@@ -14,6 +14,9 @@
#include "search.h"
#include "util.h"
+#ifdef _WIN32
+#include <windows.h>
+#endif
int main(int argc, char **argv) {
char **base_paths = NULL;
@@ -45,7 +48,15 @@ int main(int argc, char **argv) {
parse_options(argc, argv, &base_paths, &paths);
log_debug("PCRE Version: %s", pcre_version());
+#ifdef _WIN32
+ {
+ SYSTEM_INFO si;
+ GetSystemInfo(&si);
+ workers_len = si.dwNumberOfProcessors;
+ }
+#else
workers_len = (int)sysconf(_SC_NPROCESSORS_ONLN);
+#endif
if (opts.literal)
workers_len--;
if (opts.workers)
View
4 src/options.c
@@ -86,7 +86,11 @@ void print_version() {
void init_options() {
memset(&opts, 0, sizeof(opts));
opts.casing = CASE_SENSITIVE;
+#ifdef _WIN32
+ opts.color = FALSE;
+#else
opts.color = TRUE;
+#endif
opts.max_matches_per_file = 10000;
opts.max_search_depth = 25;
opts.print_break = TRUE;
View
26 src/search.c
@@ -202,11 +202,25 @@ void search_file(const char *file_full_path) {
goto cleanup;
}
+#ifdef _WIN32
+ {
+ HANDLE hmmap = CreateFileMapping(
+ (HANDLE)_get_osfhandle(fd), 0, PAGE_READONLY, 0, f_len, "ag");
+ buf = (char*) MapViewOfFile(hmmap, FILE_SHARE_READ, 0, 0, f_len);
+ if (hmmap != NULL)
+ CloseHandle(hmmap);
+ }
+ if (buf == NULL) {
+ log_err("File %s failed to load: %s.", file_full_path, strerror(errno));
+ goto cleanup;
+ }
+#else
buf = mmap(0, f_len, PROT_READ, MAP_SHARED, fd, 0);
if (buf == MAP_FAILED) {
log_err("File %s failed to load: %s.", file_full_path, strerror(errno));
goto cleanup;
}
+#endif
if (opts.search_zip_files) {
ag_compression_type zip_type = is_zipped(buf, f_len);
@@ -228,7 +242,11 @@ void search_file(const char *file_full_path) {
cleanup:;
if (fd != -1) {
+#ifdef _WIN32
+ UnmapViewOfFile(buf);
+#else
munmap(buf, f_len);
+#endif
close(fd);
}
}
@@ -260,6 +278,9 @@ void *search_file_worker() {
}
static int check_symloop_enter(const char *path, dirkey_t *outkey) {
+#ifdef _WIN32
+ return SYMLOOP_OK;
+#else
struct stat buf;
symdir_t *item_found = NULL;
symdir_t *new_item = NULL;
@@ -286,9 +307,13 @@ static int check_symloop_enter(const char *path, dirkey_t *outkey) {
memcpy(&new_item->key, outkey, sizeof(dirkey_t));
HASH_ADD(hh, symhash, key, sizeof(dirkey_t), new_item);
return SYMLOOP_OK;
+#endif
}
static int check_symloop_leave(dirkey_t *dirkey) {
+#ifdef _WIN32
+ return SYMLOOP_OK;
+#else
symdir_t *item_found = NULL;
if (dirkey->dev == 0 && dirkey->ino == 0) {
@@ -304,6 +329,7 @@ static int check_symloop_leave(dirkey_t *dirkey) {
HASH_DELETE(hh, symhash, item_found);
free(item_found);
return SYMLOOP_OK;
+#endif
}
/* TODO: Append matches to some data structure instead of just printing them out.
View
6 src/search.h
@@ -9,7 +9,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <sys/mman.h>
+#ifdef _WIN32
+# include <windows.h>
+#else
+# include <sys/mman.h>
+#endif
#include <sys/stat.h>
#include <unistd.h>
View
10 src/util.c
@@ -8,6 +8,12 @@
#include "util.h"
#include "config.h"
+#ifdef _WIN32
+#define flockfile(x)
+#define funlockfile(x)
+#define getc_unlocked(x) getc(x)
+#endif
+
#define CHECK_AND_RETURN(ptr) \
if (ptr == NULL) { die("Memory allocation failed."); }\
return ptr;
@@ -309,6 +315,9 @@ int is_directory(const char *path, const struct dirent *d) {
}
int is_symlink(const char *path, const struct dirent *d) {
+#ifdef _WIN32
+ return 0;
+#else
#ifdef HAVE_DIRENT_DTYPE
/* Some filesystems, e.g. ReiserFS, always return a type DT_UNKNOWN from readdir or scandir. */
/* Call lstat if we find DT_UNKNOWN to get the information we need. */
@@ -325,6 +334,7 @@ int is_symlink(const char *path, const struct dirent *d) {
}
free(full_path);
return (S_ISLNK(s.st_mode));
+#endif
}
void ag_asprintf(char **ret, const char *fmt, ...) {
Something went wrong with that request. Please try again.