Example #1
0
DirEntList list_dir (
			const std::wstring &directory,
			const UnaryCallback <const DirEnt &, bool> &filter,
			const BinaryCallback <const DirEnt &, const DirEnt &, bool> &comp
		)
{
	DirEntList filelist;

	std::string dirname = wstring_to_mbs (directory);

	if (DIR *dir = ::opendir (dirname.c_str ())) {
		DirEnt tmp_ent;
		if (*c(dirname).rbegin() != '/') {
			dirname += '/';
		}
		while (struct dirent *ent = readdir (dir)) {
			tmp_ent.name = mbs_to_wstring (ent->d_name);
			tmp_ent.attr = get_file_attr (dirname + ent->d_name);
			if (!filter (tmp_ent)) {
				filelist.push_back (std::move (tmp_ent));
			}
		}
		closedir (dir);
		// Sort them
		filelist.sort (wrap (comp));
	}
	return filelist;
}
Example #2
0
std::string find_executable (const std::string &exe)
{
	std::string result;
	if (exe.empty ()) {
		// Empty input. Return empty string
	}
	else if (memchr (exe.data (), '/', exe.length ())) {
		// exe is a full/relative pathname
		if (exe[0] == '~') {
			result = home_expand_pathname (exe);
		}
		else {
			result = exe;
		}
		if ((get_file_attr (result) & (FILE_ATTR_DIRECTORY|FILE_ATTR_EXECUTABLE))
				!= FILE_ATTR_EXECUTABLE) {
			result.clear ();
		}
	}
	else if (const char *path = getenv ("PATH")) {
		// exe is a "bare" filename
		for (;;) {
			const char *colon = strchrnul (path, ':');
			if (path == colon) {
				result = '.';
			}
			else {
				result.assign (path, colon);
			}
			result += '/';
			result += exe;
			if ((get_file_attr (result) & (FILE_ATTR_DIRECTORY|FILE_ATTR_EXECUTABLE))
					== FILE_ATTR_EXECUTABLE) {
				break;
			}
			if (*colon != ':') {
				result.clear ();
				break;
			}
			path = colon+1;
		}
	}
	return result;
}
Example #3
0
/* We keep the do_lstat code in a separate function to avoid recursion.
 * When a path ends with a slash, the stat will fail with ENOENT. In
 * this case, we strip the trailing slashes and stat again.
 *
 * If follow is true then act like stat() and report on the link
 * target. Otherwise report on the link itself.
 */
static int do_lstat(int follow, const char *file_name, struct mingw_stat *buf)
{
	int err;
	WIN32_FILE_ATTRIBUTE_DATA fdata;

	if (!(err = get_file_attr(file_name, &fdata))) {
		int len = strlen(file_name);

		buf->st_ino = 0;
		buf->st_uid = DEFAULT_UID;
		buf->st_gid = DEFAULT_GID;
		buf->st_nlink = 1;
		buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
		if (len > 4 && (!strcasecmp(file_name+len-4, ".exe") ||
						!strcasecmp(file_name+len-4, ".com")))
			buf->st_mode |= S_IEXEC;
		buf->st_size = fdata.nFileSizeLow |
			(((off64_t)fdata.nFileSizeHigh)<<32);
		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
			WIN32_FIND_DATAA findbuf;
			HANDLE handle = FindFirstFileA(file_name, &findbuf);
			if (handle != INVALID_HANDLE_VALUE) {
				if ((findbuf.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
						(findbuf.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
					if (follow) {
						char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
						buf->st_size = readlink(file_name, buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
					} else {
						buf->st_mode = S_IFLNK;
					}
					buf->st_mode |= S_IREAD;
					if (!(findbuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
						buf->st_mode |= S_IWRITE;
				}
				FindClose(handle);
			}
		}

		/*
		 * Assume a block is 4096 bytes and calculate number of 512 byte
		 * sectors.
		 */
		buf->st_blksize = 4096;
		buf->st_blocks = ((buf->st_size+4095)>>12)<<3;
		return 0;
	}
Example #4
0
/* do_stat is a common implementation for cygwin_lstat and cygwin_stat.
 *
 * To simplify its logic, in the case of cygwin symlinks, this implementation
 * falls back to the cygwin version of stat/lstat, which is provided as the
 * last argument.
 */
static int do_stat(const char *file_name, struct stat *buf, stat_fn_t cygstat)
{
	WIN32_FILE_ATTRIBUTE_DATA fdata;

	if (file_name[0] == '/')
		return cygstat (file_name, buf);

	if (!(errno = get_file_attr(file_name, &fdata))) {
		/*
		 * If the system attribute is set and it is not a directory then
		 * it could be a symbol link created in the nowinsymlinks mode.
		 * Normally, Cygwin works in the winsymlinks mode, so this situation
		 * is very unlikely. For the sake of simplicity of our code, let's
		 * Cygwin to handle it.
		 */
		if ((fdata.dwFileAttributes & FILE_ATTRIBUTE_SYSTEM) &&
		    !(fdata.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY))
			return cygstat(file_name, buf);

		/* fill out the stat structure */
		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
		buf->st_ino = 0;
		buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
		buf->st_nlink = 1;
		buf->st_uid = buf->st_gid = 0;
#ifdef __CYGWIN_USE_BIG_TYPES__
		buf->st_size = ((_off64_t)fdata.nFileSizeHigh << 32) +
			fdata.nFileSizeLow;
#else
		buf->st_size = (off_t)fdata.nFileSizeLow;
#endif
		buf->st_blocks = size_to_blocks(buf->st_size);
		filetime_to_timespec(&fdata.ftLastAccessTime, &buf->st_atim);
		filetime_to_timespec(&fdata.ftLastWriteTime, &buf->st_mtim);
		filetime_to_timespec(&fdata.ftCreationTime, &buf->st_ctim);
		return 0;
	} else if (errno == ENOENT) {
		/*
		 * In the winsymlinks mode (which is the default), Cygwin
		 * emulates symbol links using Windows shortcut files. These
		 * files are formed by adding .lnk extension. So, if we have
		 * not found the specified file name, it could be that it is
		 * a symbol link. Let's Cygwin to deal with that.
		 */
		return cygstat(file_name, buf);
	}
	return -1;
}
Example #5
0
File: test-stat.c Project: j6t/git
/* We keep the do_lstat code in a separate function to avoid recursion.
 * When a path ends with a slash, the stat will fail with ENOENT. In
 * this case, we strip the trailing slashes and stat again.
 */
static int do_lstat(const char *file_name, struct stat *buf)
{
	WIN32_FILE_ATTRIBUTE_DATA fdata;

	if (!(errno = get_file_attr(file_name, &fdata))) {
		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_nlink = 1;
		buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
		buf->st_size = fdata.nFileSizeLow; /* Can't use nFileSizeHigh, since it's not a stat64 */
		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
		return 0;
	}
	return -1;
}
Example #6
0
File: mingw.c Project: hesskah/git
/* We keep the do_lstat code in a separate function to avoid recursion.
 * When a path ends with a slash, the stat will fail with ENOENT. In
 * this case, we strip the trailing slashes and stat again.
 *
 * If follow is true then act like stat() and report on the link
 * target. Otherwise report on the link itself.
 */
static int do_lstat(int follow, const char *file_name, struct stat *buf)
{
	int err;
	WIN32_FILE_ATTRIBUTE_DATA fdata;

	if (!(err = get_file_attr(file_name, &fdata))) {
		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_nlink = 1;
		buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
		buf->st_size = fdata.nFileSizeLow |
			(((off_t)fdata.nFileSizeHigh)<<32);
		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
		if (fdata.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) {
			WIN32_FIND_DATAA findbuf;
			HANDLE handle = FindFirstFileA(file_name, &findbuf);
			if (handle != INVALID_HANDLE_VALUE) {
				if ((findbuf.dwFileAttributes & FILE_ATTRIBUTE_REPARSE_POINT) &&
						(findbuf.dwReserved0 == IO_REPARSE_TAG_SYMLINK)) {
					if (follow) {
						char buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
						buf->st_size = readlink(file_name, buffer, MAXIMUM_REPARSE_DATA_BUFFER_SIZE);
					} else {
						buf->st_mode = S_IFLNK;
					}
					buf->st_mode |= S_IREAD;
					if (!(findbuf.dwFileAttributes & FILE_ATTRIBUTE_READONLY))
						buf->st_mode |= S_IWRITE;
				}
				FindClose(handle);
			}
		}
		return 0;
	}
	errno = err;
	return -1;
}
Example #7
0
unsigned get_file_attr (const wchar_t *name)
{
	return get_file_attr (wstring_to_mbs (name).c_str ());
}