Skip to content

Commit

Permalink
util: Fix abs_file_name() bugs on Windows.
Browse files Browse the repository at this point in the history
abs_file_name() believed that a file name that begins with / or contains :
is absolute and that any other file name is relative.  On Windows, this is
wrong in at least the following ways:

   * / and \ are interchangeable on Windows.

   * A name that begins with \\ or // is also absolute.

   * A name that begins with X: but not X:\ is not absolute.

   * A name with : in some position other than the second position is
     not absolute (although it might not be valid either?).

Furthermore, Windows has more than one current working directory (one per
volume letter), so trying to make a file name absolute by just prefixing
the current working directory for the current volume results in silliness.

This patch attempts to fix the problem.

This makes OVS link against shlwapi, which is needed to use
PathIsRelative().

Found by inspection.

Acked-by: Alin Gabriel Serdean <[email protected]>
Signed-off-by: Ben Pfaff <[email protected]>
  • Loading branch information
blp committed Aug 3, 2018
1 parent 7491caa commit 4d8f04b
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 23 deletions.
6 changes: 3 additions & 3 deletions Documentation/intro/install/windows.rst
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,7 @@ component installation directories, etc. For example:
::

$ ./configure CC=./build-aux/cccl LD="$(which link)" \
LIBS="-lws2_32 -liphlpapi -lwbemuuid -lole32 -loleaut32" \
LIBS="-lws2_32 -lShlwapi -liphlpapi -lwbemuuid -lole32 -loleaut32" \
--prefix="C:/openvswitch/usr" \
--localstatedir="C:/openvswitch/var" \
--sysconfdir="C:/openvswitch/etc" \
Expand All @@ -172,7 +172,7 @@ To configure with SSL support, add the requisite additional options:
::

$ ./configure CC=./build-aux/cccl LD="`which link`" \
LIBS="-lws2_32 -liphlpapi -lwbemuuid -lole32 -loleaut32" \
LIBS="-lws2_32 -lShlwapi -liphlpapi -lwbemuuid -lole32 -loleaut32" \
--prefix="C:/openvswitch/usr" \
--localstatedir="C:/openvswitch/var"
--sysconfdir="C:/openvswitch/etc" \
Expand All @@ -184,7 +184,7 @@ Finally, to the kernel module also:
::

$ ./configure CC=./build-aux/cccl LD="`which link`" \
LIBS="-lws2_32 -liphlpapi -lwbemuuid -lole32 -loleaut32" \
LIBS="-lws2_32 -lShlwapi -liphlpapi -lwbemuuid -lole32 -loleaut32" \
--prefix="C:/openvswitch/usr" \
--localstatedir="C:/openvswitch/var" \
--sysconfdir="C:/openvswitch/etc" \
Expand Down
2 changes: 1 addition & 1 deletion appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,6 @@ build_script:
- C:\MinGW\msys\1.0\bin\bash -lc "cp /c/pthreads-win32/Pre-built.2/dll/x86/*.dll /c/openvswitch/."
- C:\MinGW\msys\1.0\bin\bash -lc "mv /bin/link.exe /bin/link_copy.exe"
- C:\MinGW\msys\1.0\bin\bash -lc "cd /c/openvswitch && ./boot.sh"
- C:\MinGW\msys\1.0\bin\bash -lc "cd /c/openvswitch && ./configure CC=build-aux/cccl LD=\"`which link`\" LIBS=\"-lws2_32 -liphlpapi -lwbemuuid -lole32 -loleaut32\" --with-pthread=C:/pthreads-win32/Pre-built.2 --with-openssl=C:/OpenSSL-Win32 --with-vstudiotarget=\"Debug\"
- C:\MinGW\msys\1.0\bin\bash -lc "cd /c/openvswitch && ./configure CC=build-aux/cccl LD=\"`which link`\" LIBS=\"-lws2_32 -lShlwapi -liphlpapi -lwbemuuid -lole32 -loleaut32\" --with-pthread=C:/pthreads-win32/Pre-built.2 --with-openssl=C:/OpenSSL-Win32 --with-vstudiotarget=\"Debug\"
- C:\MinGW\msys\1.0\bin\bash -lc "cd /c/openvswitch && make"
- C:\MinGW\msys\1.0\bin\bash -lc "cd /c/openvswitch && make datapath_windows_analyze"
60 changes: 41 additions & 19 deletions lib/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@
#ifdef HAVE_PTHREAD_SET_NAME_NP
#include <pthread_np.h>
#endif
#ifdef _WIN32
#include <shlwapi.h>
#endif

VLOG_DEFINE_THIS_MODULE(util);

Expand Down Expand Up @@ -1049,37 +1052,56 @@ base_name(const char *file_name)
}
#endif /* _WIN32 */

/* If 'file_name' starts with '/', returns a copy of 'file_name'. Otherwise,
bool
is_file_name_absolute(const char *fn)
{
#ifdef _WIN32
/* Use platform specific API */
return !PathIsRelative(fn);
#else
/* An absolute path begins with /. */
return fn[0] == '/';
#endif
}

/* If 'file_name' is absolute, returns a copy of 'file_name'. Otherwise,
* returns an absolute path to 'file_name' considering it relative to 'dir',
* which itself must be absolute. 'dir' may be null or the empty string, in
* which case the current working directory is used.
*
* Additionally on Windows, if 'file_name' has a ':', returns a copy of
* 'file_name'
*
* Returns a null pointer if 'dir' is null and getcwd() fails. */
char *
abs_file_name(const char *dir, const char *file_name)
{
if (file_name[0] == '/') {
return xstrdup(file_name);
#ifdef _WIN32
} else if (strchr(file_name, ':')) {
/* If it's already absolute, return a copy. */
if (is_file_name_absolute(file_name)) {
return xstrdup(file_name);
#endif
} else if (dir && dir[0]) {
}

/* If a base dir was supplied, use it. We assume, without checking, that
* the base dir is absolute.*/
if (dir && dir[0]) {
char *separator = dir[strlen(dir) - 1] == '/' ? "" : "/";
return xasprintf("%s%s%s", dir, separator, file_name);
} else {
char *cwd = get_cwd();
if (cwd) {
char *abs_name = xasprintf("%s/%s", cwd, file_name);
free(cwd);
return abs_name;
} else {
return NULL;
}
}

#if _WIN32
/* It's a little complicated to make an absolute path on Windows because a
* relative path might still specify a drive letter. The OS has a function
* to do the job for us, so use it. */
char abs_path[MAX_PATH];
DWORD n = GetFullPathName(file_name, sizeof abs_path, abs_path, NULL);
return n > 0 && n <= sizeof abs_path ? xmemdup0(abs_path, n) : NULL;
#else
/* Outside Windows, do the job ourselves. */
char *cwd = get_cwd();
if (!cwd) {
return NULL;
}
char *abs_name = xasprintf("%s/%s", cwd, file_name);
free(cwd);
return abs_name;
#endif
}

/* Like readlink(), but returns the link name as a null-terminated string in
Expand Down
1 change: 1 addition & 0 deletions lib/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ char *dir_name(const char *file_name);
char *base_name(const char *file_name);
#endif
char *abs_file_name(const char *dir, const char *file_name);
bool is_file_name_absolute(const char *);

char *follow_symlinks(const char *filename);

Expand Down

0 comments on commit 4d8f04b

Please sign in to comment.