[setup - the official Cygwin setup program] branch master, updated. release_2.909-2-g274b400f

Jon TURNEY via Cygwin-apps-cvs <[email protected]>
Newsgroups gmane.os.cygwin.cvs.apps
Message-ID <[email protected]>


https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/setup.git;h=274b400f42c9314e835a3520cec0e15b87e466a2

commit 274b400f42c9314e835a3520cec0e15b87e466a2
Author: Jon Turney <[email protected]>
Date:   Sat Jul 17 13:56:31 2021 +0100

    Only build for x86_64 in github workflow
    
    Only build for x86_64 in github workflow, since the requirements for
    i686 are now impossible to obtain (Fedora <=31 for non-DW2 EH compiler,
    but coprs for EOL'ed Fedoras have been expired)

https://sourceware.org/git/gitweb.cgi?p=cygwin-apps/setup.git;h=b6dab3ea3ae98d9de63bc0c5775be38e4fe08d68

commit b6dab3ea3ae98d9de63bc0c5775be38e4fe08d68
Author: Christian Franke <[email protected]>
Date:   Fri May 14 09:50:12 2021 +0200

    Add new option '--compact-os ALGORITHM'.
    
    If specified, selected Compact OS compression algorithm is applied
    to files below /bin, /sbin and /usr.  Most DLL files are excluded
    because rebase will open these files again for writing.


Diff:
---
 .github/workflows/fedora.yml |  4 +-
 Makefile.am                  |  2 +
 compactos.cc                 | 63 +++++++++++++++++++++++++++++++
 compactos.h                  | 25 +++++++++++++
 io_stream_cygfile.cc         | 89 +++++++++++++++++++++++++++++++++++++++++++-
 io_stream_cygfile.h          |  2 +
 packaging-scripts/conf.sh    |  3 +-
 7 files changed, 183 insertions(+), 5 deletions(-)

diff --git a/.github/workflows/fedora.yml b/.github/workflows/fedora.yml
index e070d305..2bd76e57 100644
--- a/.github/workflows/fedora.yml
+++ b/.github/workflows/fedora.yml
@@ -6,7 +6,7 @@ jobs:
   fedora-build:
     name: Fedora
     runs-on: ubuntu-latest
-    container: fedora:31
+    container: fedora:latest
     steps:
     # install git, so checkout uses git to fetch repository, so 'git describe' works
     - name: Install git
@@ -21,4 +21,4 @@ jobs:
       run: packaging-scripts/fedora-prereqs-install.sh
 
     - name: Build
-      run: packaging-scripts/conf.sh upx
+      run: packaging-scripts/conf.sh upx x86_64
diff --git a/Makefile.am b/Makefile.am
index d10ad6b1..63e96dae 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -108,6 +108,8 @@ inilint_SOURCES = \
 	archive_tar_file.cc \
 	choose.cc \
 	choose.h \
+	compactos.cc \
+	compactos.h \
 	compress.cc \
 	compress.h \
 	compress_bz.cc \
diff --git a/compactos.cc b/compactos.cc
new file mode 100644
index 00000000..9ed2a731
--- /dev/null
+++ b/compactos.cc
@@ -0,0 +1,63 @@
+//
+// compactos.cc
+//
+// Copyright (C) 2021 Christian Franke
+//
+// SPDX-License-Identifier: MIT
+//
+
+#include "compactos.h"
+
+/* Not yet provided by w32api headers. */
+#ifndef FSCTL_SET_EXTERNAL_BACKING
+#define FSCTL_SET_EXTERNAL_BACKING \
+  CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 195, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
+#endif
+
+#ifndef WOF_CURRENT_VERSION
+#define WOF_CURRENT_VERSION 1
+
+typedef struct _WOF_EXTERNAL_INFO {
+  DWORD Version;
+  DWORD Provider;
+} WOF_EXTERNAL_INFO;
+
+#endif
+
+#ifndef WOF_PROVIDER_FILE
+#define WOF_PROVIDER_FILE 2
+#define FILE_PROVIDER_CURRENT_VERSION 1
+
+typedef struct _FILE_PROVIDER_EXTERNAL_INFO_V1 {
+  DWORD Version;
+  DWORD Algorithm;
+  DWORD Flags;
+} FILE_PROVIDER_EXTERNAL_INFO_V1;
+
+#endif
+
+#ifndef ERROR_COMPRESSION_NOT_BENEFICIAL
+#define ERROR_COMPRESSION_NOT_BENEFICIAL 344
+#endif
+
+int CompactOsCompressFile(HANDLE h, DWORD algorithm)
+{
+  struct {
+    WOF_EXTERNAL_INFO Wof;
+    FILE_PROVIDER_EXTERNAL_INFO_V1 FileProvider;
+  } wfp;
+  wfp.Wof.Version = WOF_CURRENT_VERSION;
+  wfp.Wof.Provider = WOF_PROVIDER_FILE;
+  wfp.FileProvider.Version = FILE_PROVIDER_CURRENT_VERSION;
+  wfp.FileProvider.Algorithm = algorithm;
+  wfp.FileProvider.Flags = 0;
+
+  if (!DeviceIoControl(h, FSCTL_SET_EXTERNAL_BACKING, &wfp, sizeof(wfp), 0, 0, 0, 0))
+    {
+      if (GetLastError() != ERROR_COMPRESSION_NOT_BENEFICIAL)
+        return -1;
+      return 0;
+    }
+
+  return 1;
+}
diff --git a/compactos.h b/compactos.h
new file mode 100644
index 00000000..f1877189
--- /dev/null
+++ b/compactos.h
@@ -0,0 +1,25 @@
+//
+// compactos.h
+//
+// Copyright (C) 2021 Christian Franke
+//
+// SPDX-License-Identifier: MIT
+//
+
+#ifndef COMPACTOS_H
+#define COMPACTOS_H
+
+#include <windows.h>
+
+/* Not yet provided by w32api headers. */
+#ifndef FILE_PROVIDER_COMPRESSION_XPRESS4K
+#define FILE_PROVIDER_COMPRESSION_XPRESS4K  0
+#define FILE_PROVIDER_COMPRESSION_LZX       1
+#define FILE_PROVIDER_COMPRESSION_XPRESS8K  2
+#define FILE_PROVIDER_COMPRESSION_XPRESS16K 3
+#endif
+
+// Returns: 1=compressed, 0=not compressed, -1=error
+int CompactOsCompressFile(HANDLE h, DWORD algorithm);
+
+#endif // COMPACTOS_H
diff --git a/io_stream_cygfile.cc b/io_stream_cygfile.cc
index 2d0716ff..a9150e7e 100644
--- a/io_stream_cygfile.cc
+++ b/io_stream_cygfile.cc
@@ -18,6 +18,9 @@
 #include "filemanip.h"
 #include "mkdir.h"
 #include "mount.h"
+#include "compactos.h"
+
+#include "getopt++/StringOption.h"
 
 #include <stdlib.h>
 #include <errno.h>
@@ -27,6 +30,45 @@
 #include "IOStreamProvider.h"
 #include "LogSingleton.h"
 
+/* Option '--compact-os ALGORITHM' */
+class CompactOsStringOption : public StringOption
+{
+public:
+  CompactOsStringOption ();
+  virtual Result Process (char const *optarg, int prefixIndex) /* override */;
+  operator int () const { return intval; }
+private:
+  int intval;
+};
+
+CompactOsStringOption::CompactOsStringOption ()
+: StringOption ("", '\0', "compact-os",
+    "Compress installed files with Compact OS "
+    "(xpress4k, xpress8k, xpress16k, lzx)", false),
+  intval (-1)
+{
+}
+
+Option::Result CompactOsStringOption::Process (char const *optarg, int prefixIndex)
+{
+  Result res = StringOption::Process (optarg, prefixIndex);
+  if (res != Ok)
+    return res;
+  const std::string& strval = *this;
+  if (strval == "xpress4k")
+    intval = FILE_PROVIDER_COMPRESSION_XPRESS4K;
+  else if (strval == "xpress8k")
+    intval = FILE_PROVIDER_COMPRESSION_XPRESS8K;
+  else if (strval == "xpress16k")
+    intval = FILE_PROVIDER_COMPRESSION_XPRESS16K;
+  else if (strval == "lzx")
+    intval = FILE_PROVIDER_COMPRESSION_LZX;
+  else
+    return Failed;
+  return Ok;
+}
+
+static CompactOsStringOption CompactOsOption;
 
 /* completely private iostream registration class */
 class CygFileProvider : public IOStreamProvider
@@ -59,7 +101,8 @@ CygFileProvider CygFileProvider::theInstance = CygFileProvider();
 
 
 std::string io_stream_cygfile::cwd("/");
-  
+bool io_stream_cygfile::compact_os_is_available = (OSMajorVersion () >= 10);
+
 // Normalise a unix style path relative to 
 // cwd.
 std::string
@@ -120,7 +163,27 @@ get_root_dir_now ()
   read_mounts (std::string ());
 }
 
-io_stream_cygfile::io_stream_cygfile (const std::string& name, const std::string& mode, mode_t perms) : fp(), lasterr (0), fname(), wname (NULL)
+static bool
+compactos_is_useless (const std::string& name)
+{
+  const char * const p = name.c_str();
+  if (!(!strncmp (p, "/bin/", 5) || !strncmp (p, "/sbin/", 6) || !strncmp (p, "/usr/", 5)))
+    return true; /* File is not in R/O tree. */
+  const size_t len = name.size(); /* >= 5 */
+  if (!strcmp (p + (len - 4), ".dll") || !strcmp (p + (len - 3), ".so")) {
+    if ((len >= 5 + 11 && !strcmp (p + (len - 11), "cygwin1.dll"))
+	|| strstr (p + 5, "/sys-root/mingw/"))
+      return false; /* Ignored by rebase. */
+    return true; /* Rebase will open file for writing which uncompresses the file. */
+  }
+  if (!strcmp (p + (len - 4), ".bz2") || !strcmp (p + (len - 3), ".gz")
+      || !strcmp (p + (len - 3), ".xz"))
+    return true; /* File is already compressed. */
+  return false;
+}
+
+io_stream_cygfile::io_stream_cygfile (const std::string& name, const std::string& mode, mode_t perms)
+: fp(), lasterr (0), fname(), wname (NULL), compact_os_algorithm(-1)
 {
   errno = 0;
   if (!name.size())
@@ -153,6 +216,10 @@ io_stream_cygfile::io_stream_cygfile (const std::string& name, const std::string
 	Log (LOG_TIMESTAMP) << "io_stream_cygfile: fopen(" << name << ") failed " << errno << " "
 	  << strerror(errno) << endLog;
       }
+
+      if (mode[0] == 'w' && compact_os_is_available && CompactOsOption >= 0
+	  && !compactos_is_useless (name))
+	compact_os_algorithm = CompactOsOption;
     }
 }
 
@@ -367,6 +434,24 @@ io_stream_cygfile::set_mtime (time_t mtime)
 		   FILE_ATTRIBUTE_NORMAL | FILE_FLAG_BACKUP_SEMANTICS, 0);
   if (h == INVALID_HANDLE_VALUE)
     return 1;
+
+  if (compact_os_algorithm >= 0)
+    {
+      /* Compact OS must be applied after last WriteFile()
+	 and before SetFileTime(). */
+      int rc = CompactOsCompressFile (h, compact_os_algorithm);
+      if (rc < 0)
+	{
+	  DWORD err = GetLastError();
+	  Log (LOG_TIMESTAMP) << "Compact OS disabled after error " << err
+			      << " on " << fname << endLog;
+	  compact_os_is_available = false;
+	}
+      else
+	Log (LOG_BABBLE) << "Compact OS algorithm " << compact_os_algorithm
+			 << (rc == 0 ? " not" : "") << " applied to " << fname << endLog;
+    }
+
   SetFileTime (h, 0, 0, &ftime);
   CloseHandle (h);
   return 0;
diff --git a/io_stream_cygfile.h b/io_stream_cygfile.h
index 1ece2428..b9779094 100644
--- a/io_stream_cygfile.h
+++ b/io_stream_cygfile.h
@@ -61,7 +61,9 @@ private:
   std::string fname;
   wchar_t *wname;
   wchar_t *w_str ();
+  int compact_os_algorithm;
   static std::string cwd;
+  static bool compact_os_is_available;
 };
 
 #endif /* SETUP_IO_STREAM_CYGFILE_H */
diff --git a/packaging-scripts/conf.sh b/packaging-scripts/conf.sh
index 10d78b46..f01b1990 100755
--- a/packaging-scripts/conf.sh
+++ b/packaging-scripts/conf.sh
@@ -1,6 +1,7 @@
 #!/bin/bash -e
 
 TARGET=${1:-upx}
+ARCHES=${2:-i686 x86_64}
 
 function arch() {
 cpu=$1
@@ -16,6 +17,6 @@ make ${TARGET}
 cd ..
 }
 
-for ARCH in i686 x86_64 ; do
+for ARCH in ${ARCHES} ; do
     arch ${ARCH}
 done
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.