Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/kornelski/7z.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Pavlov <ipavlov@users.sourceforge.net>2021-11-29 06:03:01 +0300
committerfn ⌃ ⌥ <70830482+FnControlOption@users.noreply.github.com>2021-11-29 06:03:01 +0300
commit1194dc935382931bbfdd4e49004bd755e6165df1 (patch)
tree60354d8832278528f74c48ca3b5e446175747409 /CPP/Windows
parentd789d4137d8a7c16696c5bc1b13f24bb887eb7ea (diff)
21.0421.04
Diffstat (limited to 'CPP/Windows')
-rw-r--r--CPP/Windows/ErrorMsg.cpp4
-rw-r--r--CPP/Windows/FileDir.cpp55
-rw-r--r--CPP/Windows/FileFind.cpp44
-rw-r--r--CPP/Windows/FileFind.h30
-rw-r--r--CPP/Windows/FileIO.cpp19
-rw-r--r--CPP/Windows/FileIO.h11
-rw-r--r--CPP/Windows/FileName.cpp30
-rw-r--r--CPP/Windows/System.cpp7
-rw-r--r--CPP/Windows/SystemInfo.cpp24
9 files changed, 184 insertions, 40 deletions
diff --git a/CPP/Windows/ErrorMsg.cpp b/CPP/Windows/ErrorMsg.cpp
index 63fd7922..f6343a5c 100644
--- a/CPP/Windows/ErrorMsg.cpp
+++ b/CPP/Windows/ErrorMsg.cpp
@@ -77,8 +77,8 @@ static bool MyFormatMessage(DWORD errorCode, UString &message)
break;
}
- /* strerror() for unknow errors still shows message "Unknown error -12345678")
- So we must trasfer error codes before strerror() */
+ /* strerror() for unknown errors still shows message "Unknown error -12345678")
+ So we must transfer error codes before strerror() */
if (!s)
{
if ((errorCode & 0xFFFF0000) == (UInt32)((MY__FACILITY__WRes << 16) | 0x80000000))
diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp
index c06e7f37..8193f61f 100644
--- a/CPP/Windows/FileDir.cpp
+++ b/CPP/Windows/FileDir.cpp
@@ -5,6 +5,7 @@
#ifndef _WIN32
#include <stdio.h>
+#include <stdlib.h>
#include <errno.h>
#include <limits.h>
#include <unistd.h>
@@ -887,17 +888,39 @@ bool GetCurrentDir(FString &path)
char s[MY__PATH_MAX + 1];
char *res = getcwd(s, MY__PATH_MAX);
- if (!res)
+ if (res)
{
- // if (errno != ERANGE)
- return false;
+ path = fas2fs(s);
+ return true;
+ }
+ {
+ // if (errno != ERANGE) return false;
+ #if defined(__GLIBC__) || defined(__APPLE__)
+ /* As an extension to the POSIX.1-2001 standard, glibc's getcwd()
+ allocates the buffer dynamically using malloc(3) if buf is NULL. */
+ res = getcwd(NULL, 0);
+ if (res)
+ {
+ path = fas2fs(res);
+ ::free(res);
+ return true;
+ }
+ #endif
+ return false;
}
- path = fas2fs(s);
- return true;
}
-static void FILETME_To_timespec(const FILETIME *ft, timespec &ts)
+
+// #undef UTIME_OMIT // to debug
+
+#ifndef UTIME_OMIT
+ /* we can define UTIME_OMIT for debian and another systems.
+ Is it OK to define UTIME_OMIT to -2 here, if UTIME_OMIT is not defined? */
+ // #define UTIME_OMIT -2
+#endif
+
+static bool FILETME_To_timespec(const FILETIME *ft, timespec &ts)
{
if (ft)
{
@@ -909,14 +932,20 @@ static void FILETME_To_timespec(const FILETIME *ft, timespec &ts)
ts.tv_sec = sec2;
const UInt64 winTime = (((UInt64)ft->dwHighDateTime) << 32) + ft->dwLowDateTime;
ts.tv_nsec = (long)((winTime % 10000000) * 100);
- return;
+ return true;
}
}
// else
{
ts.tv_sec = 0;
- // ts.tv_nsec = UTIME_NOW; // set to the current time
- ts.tv_nsec = UTIME_OMIT; // keep old timesptamp
+ ts.tv_nsec =
+ #ifdef UTIME_OMIT
+ UTIME_OMIT; // keep old timesptamp
+ #else
+ // UTIME_NOW; // set to the current time
+ 0;
+ #endif
+ return false;
}
}
@@ -968,8 +997,12 @@ bool SetDirTime(CFSTR path, const FILETIME *cTime, const FILETIME *aTime, const
struct timespec times[2];
UNUSED_VAR(cTime)
- FILETME_To_timespec(aTime, times[0]);
- FILETME_To_timespec(mTime, times[1]);
+ bool needChange;
+ needChange = FILETME_To_timespec(aTime, times[0]);
+ needChange |= FILETME_To_timespec(mTime, times[1]);
+
+ if (!needChange)
+ return true;
const int flags = 0; // follow link
// = AT_SYMLINK_NOFOLLOW; // don't follow link
diff --git a/CPP/Windows/FileFind.cpp b/CPP/Windows/FileFind.cpp
index 8ef0f7b6..591f8df0 100644
--- a/CPP/Windows/FileFind.cpp
+++ b/CPP/Windows/FileFind.cpp
@@ -1001,7 +1001,17 @@ void CFileInfo::SetFrom_stat(const struct stat &st)
// NTime::UnixTimeToFileTime(st.st_mtime, MTime);
// NTime::UnixTimeToFileTime(st.st_atime, ATime);
#ifdef __APPLE__
+ // #ifdef _DARWIN_FEATURE_64_BIT_INODE
+ /*
+ here we can use birthtime instead of st_ctimespec.
+ but we use st_ctimespec for compatibility with previous versions and p7zip.
+ st_birthtimespec in OSX
+ st_birthtim : at FreeBSD, NetBSD
+ */
+ // timespec_To_FILETIME(st.st_birthtimespec, CTime);
+ // #else
timespec_To_FILETIME(st.st_ctimespec, CTime);
+ // #endif
timespec_To_FILETIME(st.st_mtimespec, MTime);
timespec_To_FILETIME(st.st_atimespec, ATime);
#else
@@ -1093,15 +1103,18 @@ void CEnumerator::SetDirPrefix(const FString &dirPrefix)
bool CDirEntry::IsDots() const throw()
{
- if (
- #if !defined(_AIX)
- !IsDir() ||
- #endif
- Name.IsEmpty())
- return false;
- if (Name[0] != '.')
+ /* some systems (like CentOS 7.x on XFS) have (Type == DT_UNKNOWN)
+ we can call fstatat() for that case, but we use only (Name) check here */
+
+ #if !defined(_AIX)
+ if (Type != DT_DIR && Type != DT_UNKNOWN)
return false;
- return Name.Len() == 1 || (Name.Len() == 2 && Name[1] == '.');
+ #endif
+
+ return Name.Len() != 0
+ && Name.Len() <= 2
+ && Name[0] == '.'
+ && (Name.Len() == 1 || Name[1] == '.');
}
@@ -1135,6 +1148,19 @@ bool CEnumerator::NextAny(CDirEntry &fi, bool &found)
#if !defined(_AIX)
fi.Type = de->d_type;
+ /* some systems (like CentOS 7.x on XFS) have (Type == DT_UNKNOWN)
+ we can set (Type) from fstatat() in that case.
+ But (Type) is not too important. So we don't set it here with slow fstatat() */
+ /*
+ // fi.Type = DT_UNKNOWN; // for debug
+ if (fi.Type == DT_UNKNOWN)
+ {
+ struct stat st;
+ if (fstatat(dirfd(_dir), de->d_name, &st, AT_SYMLINK_NOFOLLOW) == 0)
+ if (S_ISDIR(st.st_mode))
+ fi.Type = DT_DIR;
+ }
+ */
#endif
/*
@@ -1191,7 +1217,7 @@ bool CEnumerator::Next(CDirEntry &fileInfo, bool &found)
}
*/
-bool CEnumerator::Fill_FileInfo(const CDirEntry &de, CFileInfo &fileInfo, bool followLink)
+bool CEnumerator::Fill_FileInfo(const CDirEntry &de, CFileInfo &fileInfo, bool followLink) const
{
// printf("\nCEnumerator::Fill_FileInfo()\n");
struct stat st;
diff --git a/CPP/Windows/FileFind.h b/CPP/Windows/FileFind.h
index 009e84e7..8f28ee33 100644
--- a/CPP/Windows/FileFind.h
+++ b/CPP/Windows/FileFind.h
@@ -103,6 +103,15 @@ public:
return S_ISLNK(mod);
}
#endif
+
+ bool IsOsSymLink() const
+ {
+ #ifdef _WIN32
+ return HasReparsePoint();
+ #else
+ return IsPosixLink();
+ #endif
+ }
};
struct CFileInfo: public CFileInfoBase
@@ -223,13 +232,15 @@ struct CDirEntry
#endif
FString Name;
+ /*
#if !defined(_AIX)
bool IsDir() const
{
- // DT_DIR is
+ // (Type == DT_UNKNOWN) on some systems
return Type == DT_DIR;
}
#endif
+ */
bool IsDots() const throw();
};
@@ -246,7 +257,22 @@ public:
void SetDirPrefix(const FString &dirPrefix);
bool Next(CDirEntry &fileInfo, bool &found);
- bool Fill_FileInfo(const CDirEntry &de, CFileInfo &fileInfo, bool followLink);
+ bool Fill_FileInfo(const CDirEntry &de, CFileInfo &fileInfo, bool followLink) const;
+ bool DirEntry_IsDir(const CDirEntry &de, bool followLink) const
+ {
+ #if !defined(_AIX)
+ if (de.Type == DT_DIR)
+ return true;
+ if (de.Type != DT_UNKNOWN)
+ return false;
+ #endif
+ CFileInfo fileInfo;
+ if (Fill_FileInfo(de, fileInfo, followLink))
+ {
+ return fileInfo.IsDir();
+ }
+ return false; // change it
+ }
};
/*
diff --git a/CPP/Windows/FileIO.cpp b/CPP/Windows/FileIO.cpp
index b6f2f26e..84aad042 100644
--- a/CPP/Windows/FileIO.cpp
+++ b/CPP/Windows/FileIO.cpp
@@ -498,7 +498,24 @@ bool COutFile::Write(const void *data, UInt32 size, UInt32 &processedSize) throw
data = (const void *)((const unsigned char *)data + processedLoc);
size -= processedLoc;
}
- while (size > 0);
+ while (size != 0);
+ return true;
+}
+
+bool COutFile::WriteFull(const void *data, size_t size) throw()
+{
+ do
+ {
+ UInt32 processedLoc = 0;
+ const UInt32 sizeCur = (size > kChunkSizeMax ? kChunkSizeMax : (UInt32)size);
+ if (!WritePart(data, sizeCur, processedLoc))
+ return false;
+ if (processedLoc == 0)
+ return (size == 0);
+ data = (const void *)((const unsigned char *)data + processedLoc);
+ size -= processedLoc;
+ }
+ while (size != 0);
return true;
}
diff --git a/CPP/Windows/FileIO.h b/CPP/Windows/FileIO.h
index 276e595e..85cae631 100644
--- a/CPP/Windows/FileIO.h
+++ b/CPP/Windows/FileIO.h
@@ -244,6 +244,7 @@ public:
bool SetMTime(const FILETIME *mTime) throw();
bool WritePart(const void *data, UInt32 size, UInt32 &processedSize) throw();
bool Write(const void *data, UInt32 size, UInt32 &processedSize) throw();
+ bool WriteFull(const void *data, size_t size) throw();
bool SetEndOfFile() throw();
bool SetLength(UInt64 length) throw();
};
@@ -315,6 +316,16 @@ public:
bool Create(const char *name, bool createAlways);
bool Open(const char *name, DWORD creationDisposition);
ssize_t write_full(const void *data, size_t size, size_t &processed) throw();
+
+ bool WriteFull(const void *data, size_t size) throw()
+ {
+ size_t processed;
+ ssize_t res = write_full(data, size, processed);
+ if (res == -1)
+ return false;
+ return processed == size;
+ }
+
bool SetLength(UInt64 length) throw();
bool SetTime(const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime) throw();
bool SetMTime(const FILETIME *mTime) throw();
diff --git a/CPP/Windows/FileName.cpp b/CPP/Windows/FileName.cpp
index 4ee94575..d61ff7e1 100644
--- a/CPP/Windows/FileName.cpp
+++ b/CPP/Windows/FileName.cpp
@@ -6,6 +6,7 @@
#include <limits.h>
#include <unistd.h>
#include "../Common/StringConvert.h"
+#include "FileDir.h"
#endif
#include "FileName.h"
@@ -65,6 +66,19 @@ void NormalizeDirPathPrefix(UString &dirPath)
}
#ifdef _WIN32
+
+#ifndef USE_UNICODE_FSTRING
+#ifdef WIN_LONG_PATH
+static void NormalizeDirSeparators(UString &s)
+{
+ const unsigned len = s.Len();
+ for (unsigned i = 0; i < len; i++)
+ if (s[i] == '/')
+ s.ReplaceOneCharAtPos(i, WCHAR_PATH_SEPARATOR);
+}
+#endif
+#endif
+
void NormalizeDirSeparators(FString &s)
{
const unsigned len = s.Len();
@@ -72,6 +86,7 @@ void NormalizeDirSeparators(FString &s)
if (s[i] == '/')
s.ReplaceOneCharAtPos(i, FCHAR_PATH_SEPARATOR);
}
+
#endif
@@ -391,16 +406,9 @@ static bool GetCurDir(UString &path)
#else
- #define MY__PATH_MAX PATH_MAX
- // #define MY__PATH_MAX 1024
-
- char s[MY__PATH_MAX + 1];
- char *res = getcwd(s, MY__PATH_MAX);
- if (!res)
- {
- // if (errno != ERANGE)
- return false;
- }
+ FString s;
+ if (!NDir::GetCurrentDir(s))
+ return false;
path = GetUnicodeString(s);
return true;
@@ -721,7 +729,7 @@ static bool GetSuperPathBase(CFSTR s, UString &res)
true false * use Super path
true true true don't use any path, we already used mainPath
true true false use main path as Super Path, we don't try mainMath
- That case is possible now if GetCurDir returns unknow
+ That case is possible now if GetCurDir returns unknown
type of path (not drive and not network)
We can change that code if we want to try mainPath, if GetSuperPathBase returns error,
diff --git a/CPP/Windows/System.cpp b/CPP/Windows/System.cpp
index 099407ec..3a14b77d 100644
--- a/CPP/Windows/System.cpp
+++ b/CPP/Windows/System.cpp
@@ -202,9 +202,12 @@ bool GetRamSize(UInt64 &size)
size = val;
#elif defined(_AIX)
-
// fixme
-
+ #elif defined(__gnu_hurd__)
+ // fixme
+ #elif defined(__FreeBSD_kernel__) && defined(__GLIBC__)
+ // GNU/kFreeBSD Debian
+ // fixme
#else
struct sysinfo info;
diff --git a/CPP/Windows/SystemInfo.cpp b/CPP/Windows/SystemInfo.cpp
index 9346afd5..82145d9c 100644
--- a/CPP/Windows/SystemInfo.cpp
+++ b/CPP/Windows/SystemInfo.cpp
@@ -20,6 +20,22 @@
#include <sys/auxv.h>
+// #undef AT_HWCAP // to debug
+// #undef AT_HWCAP2 // to debug
+
+/* the following patch for some debian systems.
+ Is it OK to define AT_HWCAP and AT_HWCAP2 here with these constant numbers? */
+
+#if defined(__FreeBSD_kernel__) && defined(__GLIBC__)
+ #ifndef AT_HWCAP
+ #define AT_HWCAP 16
+ #endif
+ #ifndef AT_HWCAP2
+ #define AT_HWCAP2 26
+ #endif
+#endif
+
+
#ifdef MY_CPU_ARM_OR_ARM64
#include <asm/hwcap.h>
#endif
@@ -75,7 +91,7 @@ static bool ReadFile_to_Buffer(CFSTR fileName, CByteBuffer &buf)
#endif
-#ifndef __APPLE__
+#if defined(_WIN32) || defined(AT_HWCAP) || defined(AT_HWCAP2)
static void PrintHex(AString &s, UInt64 v)
{
char temp[32];
@@ -657,6 +673,7 @@ void AddCpuFeatures(AString &s)
#endif
+ #ifdef AT_HWCAP
s.Add_OptSpaced("hwcap:");
{
unsigned long h = getauxval(AT_HWCAP);
@@ -671,7 +688,9 @@ void AddCpuFeatures(AString &s)
if (h & HWCAP_NEON) s += ":NEON";
#endif
}
-
+ #endif // AT_HWCAP
+
+ #ifdef AT_HWCAP2
{
unsigned long h = getauxval(AT_HWCAP2);
#ifndef MY_CPU_ARM
@@ -688,6 +707,7 @@ void AddCpuFeatures(AString &s)
#endif
}
}
+ #endif // AT_HWCAP2
#endif // _AIX
#endif // _WIN32
}