Update to 7-Zip Version 21.04

- first test... no release!!!
This commit is contained in:
Tino Reichardt
2021-11-06 22:17:34 +01:00
parent 0f6bcfd2ed
commit 09497b7ba0
152 changed files with 6166 additions and 1341 deletions

View File

@@ -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))

View File

@@ -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

View File

@@ -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())
/* 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;
if (Name[0] != '.')
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;

View File

@@ -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
}
};
/*

View File

@@ -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;
}

View File

@@ -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();

View File

@@ -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,

View File

@@ -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;

View File

@@ -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
}