From 599b0bf438e387dbaf00dbadcbe41b2a0de90db1 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Tue, 23 Nov 2010 19:38:24 +0100 Subject: msvc: opendir: fix malloc-failure Previsouly, the code checked for malloc-failure after it had accessed the returned pointer. Move the check a bit earlier to avoid segfault. Signed-off-by: Erik Faye-Lund Signed-off-by: Junio C Hamano --- compat/msvc.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'compat/msvc.c') diff --git a/compat/msvc.c b/compat/msvc.c index ac04a4ccbd..d6096e4bd9 100644 --- a/compat/msvc.c +++ b/compat/msvc.c @@ -7,16 +7,16 @@ DIR *opendir(const char *name) { int len; DIR *p; - p = (DIR*)malloc(sizeof(DIR)); + p = malloc(sizeof(DIR)); + if (!p) + return NULL; + memset(p, 0, sizeof(DIR)); strncpy(p->dd_name, name, PATH_MAX); len = strlen(p->dd_name); p->dd_name[len] = '/'; p->dd_name[len+1] = '*'; - if (p == NULL) - return NULL; - p->dd_handle = _findfirst(p->dd_name, &p->dd_dta); if (p->dd_handle == -1) { -- cgit v1.2.3 From 17194c1e96eddb43d2608fe7bd121256d17118ee Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Tue, 23 Nov 2010 19:38:25 +0100 Subject: msvc: opendir: allocate enough memory The defintion of DIR expects the allocating function to extend dd_name by over-allocating. This is not currently done in our implementation of opendir. Fix this. Signed-off-by: Erik Faye-Lund Signed-off-by: Junio C Hamano --- compat/msvc.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'compat/msvc.c') diff --git a/compat/msvc.c b/compat/msvc.c index d6096e4bd9..c195365d2c 100644 --- a/compat/msvc.c +++ b/compat/msvc.c @@ -5,15 +5,14 @@ DIR *opendir(const char *name) { - int len; + int len = strlen(name); DIR *p; - p = malloc(sizeof(DIR)); + p = malloc(sizeof(DIR) + len + 2); if (!p) return NULL; - memset(p, 0, sizeof(DIR)); - strncpy(p->dd_name, name, PATH_MAX); - len = strlen(p->dd_name); + memset(p, 0, sizeof(DIR) + len + 2); + strcpy(p->dd_name, name); p->dd_name[len] = '/'; p->dd_name[len+1] = '*'; -- cgit v1.2.3 From 20c6788aced1237489824db3b25285afed0ad169 Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Tue, 23 Nov 2010 19:38:26 +0100 Subject: msvc: opendir: do not start the search compat/mingw.c's readdir expects to be the one that starts the search, and if it isn't, then the first entry will be missing or incorrect. Fix this by removing the call to _findfirst, and initializing dd_handle to INVALID_HANDLE_VALUE. At the same time, make sure we use FindClose instead of _findclose, which is symmetric to readdir's FindFirstFile. Take into account that the find-handle might already be closed by readdir. Signed-off-by: Erik Faye-Lund Signed-off-by: Junio C Hamano --- compat/msvc.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'compat/msvc.c') diff --git a/compat/msvc.c b/compat/msvc.c index c195365d2c..88c6093258 100644 --- a/compat/msvc.c +++ b/compat/msvc.c @@ -16,17 +16,13 @@ DIR *opendir(const char *name) p->dd_name[len] = '/'; p->dd_name[len+1] = '*'; - p->dd_handle = _findfirst(p->dd_name, &p->dd_dta); - - if (p->dd_handle == -1) { - free(p); - return NULL; - } + p->dd_handle = (long)INVALID_HANDLE_VALUE; return p; } int closedir(DIR *dir) { - _findclose(dir->dd_handle); + if (dir->dd_handle != (long)INVALID_HANDLE_VALUE) + FindClose((HANDLE)dir->dd_handle); free(dir); return 0; } -- cgit v1.2.3 From 9585ed519c59d5ac46f8e12b339220cdd0567b7d Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Tue, 23 Nov 2010 19:38:27 +0100 Subject: win32: dirent: handle errors Previously all error conditions were ignored. Be nice, and set errno when we should. Signed-off-by: Erik Faye-Lund Signed-off-by: Junio C Hamano --- compat/msvc.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) (limited to 'compat/msvc.c') diff --git a/compat/msvc.c b/compat/msvc.c index 88c6093258..199eb220f4 100644 --- a/compat/msvc.c +++ b/compat/msvc.c @@ -5,8 +5,29 @@ DIR *opendir(const char *name) { - int len = strlen(name); + DWORD attrs = GetFileAttributes(name); + int len; DIR *p; + + /* check for valid path */ + if (attrs == INVALID_FILE_ATTRIBUTES) { + errno = ENOENT; + return NULL; + } + + /* check if it's a directory */ + if (!(attrs & FILE_ATTRIBUTE_DIRECTORY)) { + errno = ENOTDIR; + return NULL; + } + + /* check that the pattern won't be too long for FindFirstFileA */ + len = strlen(name); + if (len + 2 >= MAX_PATH) { + errno = ENAMETOOLONG; + return NULL; + } + p = malloc(sizeof(DIR) + len + 2); if (!p) return NULL; @@ -21,6 +42,11 @@ DIR *opendir(const char *name) } int closedir(DIR *dir) { + if (!dir) { + errno = EBADF; + return -1; + } + if (dir->dd_handle != (long)INVALID_HANDLE_VALUE) FindClose((HANDLE)dir->dd_handle); free(dir); -- cgit v1.2.3 From e7772600e94146ddbf5ef6b08d0ea7d6fc8fbcad Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Tue, 23 Nov 2010 19:38:28 +0100 Subject: msvc: opendir: handle paths ending with a slash Signed-off-by: Erik Faye-Lund Signed-off-by: Junio C Hamano --- compat/msvc.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'compat/msvc.c') diff --git a/compat/msvc.c b/compat/msvc.c index 199eb220f4..fdbfb70a62 100644 --- a/compat/msvc.c +++ b/compat/msvc.c @@ -23,6 +23,8 @@ DIR *opendir(const char *name) /* check that the pattern won't be too long for FindFirstFileA */ len = strlen(name); + if (is_dir_sep(name[len - 1])) + len--; if (len + 2 >= MAX_PATH) { errno = ENAMETOOLONG; return NULL; -- cgit v1.2.3 From d1b6e6e015501272c7491b3a4adf3cd3904edefa Mon Sep 17 00:00:00 2001 From: Erik Faye-Lund Date: Tue, 23 Nov 2010 19:38:29 +0100 Subject: win32: use our own dirent.h The mingw-runtime implemenation of opendir, readdir and closedir sets errno to 0 on success, something that POSIX explicitly forbids. 3ba7a06 ("A loose object is not corrupt if it cannot be read due to EMFILE") introduce a dependency on this behaviour, leading to a broken "git clone" on Windows. compat/mingw.c contains an implementation of readdir, and compat/msvc.c contains implementations of opendir and closedir. Move these to compat/win32/dirent.[ch], and change to our own DIR structure at the same time. This provides a generic Win32-implementation of opendir, readdir and closedir which works on both MinGW and MSVC and does not reset errno, and as a result git clone is working again on Windows. Signed-off-by: Erik Faye-Lund Signed-off-by: Junio C Hamano --- compat/msvc.c | 52 ---------------------------------------------------- 1 file changed, 52 deletions(-) (limited to 'compat/msvc.c') diff --git a/compat/msvc.c b/compat/msvc.c index fdbfb70a62..71843d7eef 100644 --- a/compat/msvc.c +++ b/compat/msvc.c @@ -3,56 +3,4 @@ #include #include "../strbuf.h" -DIR *opendir(const char *name) -{ - DWORD attrs = GetFileAttributes(name); - int len; - DIR *p; - - /* check for valid path */ - if (attrs == INVALID_FILE_ATTRIBUTES) { - errno = ENOENT; - return NULL; - } - - /* check if it's a directory */ - if (!(attrs & FILE_ATTRIBUTE_DIRECTORY)) { - errno = ENOTDIR; - return NULL; - } - - /* check that the pattern won't be too long for FindFirstFileA */ - len = strlen(name); - if (is_dir_sep(name[len - 1])) - len--; - if (len + 2 >= MAX_PATH) { - errno = ENAMETOOLONG; - return NULL; - } - - p = malloc(sizeof(DIR) + len + 2); - if (!p) - return NULL; - - memset(p, 0, sizeof(DIR) + len + 2); - strcpy(p->dd_name, name); - p->dd_name[len] = '/'; - p->dd_name[len+1] = '*'; - - p->dd_handle = (long)INVALID_HANDLE_VALUE; - return p; -} -int closedir(DIR *dir) -{ - if (!dir) { - errno = EBADF; - return -1; - } - - if (dir->dd_handle != (long)INVALID_HANDLE_VALUE) - FindClose((HANDLE)dir->dd_handle); - free(dir); - return 0; -} - #include "mingw.c" -- cgit v1.2.3