From: Jan Rękorajski Date: Sun, 8 Nov 2020 20:58:05 +0000 (+0100) Subject: - teach rpm how to read /proc files X-Git-Tag: auto/th/rpm-4.16.1.2-1~28 X-Git-Url: http://git.pld-linux.org/?p=packages%2Frpm.git;a=commitdiff_plain;h=2aa7d974ad81aa11e64f99d8a0b8af5d8176b044;hp=8fa0ac2fcc16b1980e284e5b3e4af8554d7fde52 - teach rpm how to read /proc files - add cpuinfo() deps --- diff --git a/cpuinfo-deps.patch b/cpuinfo-deps.patch new file mode 100644 index 0000000..1dab910 --- /dev/null +++ b/cpuinfo-deps.patch @@ -0,0 +1,289 @@ +diff -ur rpm-4.16.0/lib/depends.c rpm-4.16.0-cpuinfo/lib/depends.c +--- rpm-4.16.0/lib/depends.c 2020-11-08 20:19:15.625093667 +0100 ++++ rpm-4.16.0-cpuinfo/lib/depends.c 2020-11-08 20:23:46.685893216 +0100 +@@ -697,6 +697,16 @@ + } + } + ++ if (strstr(N, "cpuinfo(") == N) { ++ if (tsmem->cpuinfo == NULL) ++ rpmdsCpuinfoPool(rpmtsPool(ts), &(tsmem->cpuinfo)); ++ ++ if (tsmem->cpuinfo != NULL && rpmdsSearch(tsmem->cpuinfo, dep) >= 0) { ++ rpmdsNotify(dep, "(cpuinfo provides)", rc); ++ goto exit; ++ } ++ } ++ + /* Dont look at pre-requisites of already installed packages */ + if (!adding && isTransientReq(dsflags)) + goto exit; +diff -ur rpm-4.16.0/lib/rpmds.c rpm-4.16.0-cpuinfo/lib/rpmds.c +--- rpm-4.16.0/lib/rpmds.c 2020-11-08 20:19:15.625093667 +0100 ++++ rpm-4.16.0-cpuinfo/lib/rpmds.c 2020-11-08 20:16:25.941242497 +0100 +@@ -2,6 +2,8 @@ + * \file lib/rpmds.c + */ + #include "system.h" ++#include ++#include + #include + + #include +@@ -9,6 +11,9 @@ + #include + #include + #include ++#include ++ ++#include "rpmio/rpmio_internal.h" /* XXX for rpmioSlurp */ + + #include "lib/rpmds_internal.h" + +@@ -1655,3 +1670,203 @@ + { + return rpmdsUnamePool(NULL, dsp); + } ++ ++struct cpuinfo_s { ++ const char *name; ++ int done; ++ int flags; ++}; ++ ++static struct cpuinfo_s ctags[] = { ++ { "processor", 0, 0 }, ++ { "Processor", 0, 1 }, /* XXX armv5 */ ++ { "vendor_id", 0, 0 }, ++ { "cpu_family", 0, 1 }, ++ { "model", 0, 1 }, ++ { "model_name", 0, 0 }, ++ { "stepping", 0, 1 }, ++ { "cpu_MHz", 0, 1 }, ++ { "CPU_implementer",0, 1 }, /* XXX armv5 */ ++ { "CPU_architecture",0, 1 }, /* XXX armv5 */ ++ { "CPU_variant", 0, 1 }, /* XXX armv5 */ ++ { "CPU_part", 0, 1 }, /* XXX armv5 */ ++ { "CPU_revision", 0, 1 }, /* XXX armv5 */ ++ { "Hardware", 0, 2 }, /* XXX armv5 */ ++ { "Revision", 0, 1 }, /* XXX armv5 */ ++ { "Serial", 0, 1 }, /* XXX armv5 */ ++ { "cache_size", 0, 1 }, ++ { "physical_id", 0, 0 }, ++ { "siblings", 0, 0 }, ++ { "core_id", 0, 0 }, ++ { "cpu_cores", 0, 0 }, ++ { "fdiv_bug", 0, 3 }, ++ { "hlt_bug", 0, 3 }, ++ { "f00f_bug", 0, 3 }, ++ { "coma_bug", 0, 3 }, ++ { "fpu", 0, 0 }, /* XXX use flags attribute instead. */ ++ { "fpu_exception", 0, 3 }, ++ { "cpuid_level", 0, 0 }, ++ { "wp", 0, 3 }, ++ { "flags", 0, 4 }, ++ { "Features", 0, 4 }, /* XXX armv5 */ ++ { "bogomips", 0, 1 }, ++ { "BogoMIPS", 0, 1 }, /* XXX armv5 */ ++ { "clflush_size", 0, 1 }, ++ { NULL, 0, -1 } ++}; ++ ++/** ++ * Return dependency format to use for a cpuinfo line. ++ * @param name field name ++ * @return type of format (0 == ignore, -1 == not found) ++ */ ++static int rpmdsCpuinfoCtagFlags(const char * name) ++{ ++ struct cpuinfo_s * ct; ++ int flags = -1; ++ ++ for (ct = ctags; ct->name != NULL; ct++) { ++ if (strcmp(ct->name, name)) ++ continue; ++ if (ct->done) ++ continue; ++ ct->done = 1; /* XXX insure single occurrence */ ++ flags = ct->flags; ++ break; ++ } ++ return flags; ++} ++ ++#define _PROC_CPUINFO "/proc/cpuinfo" ++ ++int rpmdsCpuinfoPool(rpmstrPool pool, rpmds *dsp) ++{ ++ char * cpuinfo_path = NULL; ++ struct cpuinfo_s * ct; ++ const char * NS = "cpuinfo"; ++ char * iob = NULL; ++ char * f, * fe, * fend; ++ char * g, * ge; ++ char * t; ++ int rc = -1; ++ ++ cpuinfo_path = rpmExpand("%{?_rpmds_cpuinfo_path}", NULL); ++ /* XXX may need to validate path existence somewhen. */ ++ if (cpuinfo_path == NULL || *cpuinfo_path != '/') { ++ cpuinfo_path = _free(cpuinfo_path); ++ cpuinfo_path = xstrdup(_PROC_CPUINFO); ++ } ++ ++ /* Reset done variables. */ ++ for (ct = ctags; ct->name != NULL; ct++) ++ ct->done = 0; ++ ++ rc = rpmioSlurp(cpuinfo_path, (uint8_t **) &iob, NULL); ++ if (rc != 0 || iob == NULL) ++ goto exit; ++ ++ for (f = (char *)iob; *f != '\0'; f = fend) { ++ /* find EOL */ ++ fe = f; ++ while (*fe != '\0' && !(*fe == '\n' || *fe == '\r')) ++ fe++; ++ ge = fe; ++ while (*fe != '\0' && (*fe == '\n' || *fe == '\r')) ++ *fe++ = '\0'; ++ fend = fe; ++ ++ /* rtrim on line. */ ++ while (--ge > f && isspace(*ge)) ++ *ge = '\0'; ++ ++ /* ltrim on line. */ ++ while (*f && isspace(*f)) ++ f++; ++ ++ /* split on ':' */ ++ fe = f; ++ while (*fe && *fe != ':') ++ fe++; ++ if (*fe == '\0') ++ continue; ++ g = fe + 1; ++ ++ /* rtrim on field 1. */ ++ *fe = '\0'; ++ while (--fe > f && isspace(*fe)) ++ *fe = '\0'; ++ if (*f == '\0') ++ continue; ++ ++ /* ltrim on field 2. */ ++ while (*g && isspace(*g)) ++ g++; ++ if (*g == '\0') ++ continue; ++ ++ for (t = f; *t != '\0'; t++) { ++ if (isspace(*t)) ++ *t = '_'; ++ } ++ ++ switch (rpmdsCpuinfoCtagFlags(f)) { ++ case -1: /* not found */ ++ case 0: /* ignore */ ++ default: ++ continue; ++ break; ++ case 1: /* Provides: cpuinfo(f) = g */ ++ for (t = g; *t != '\0'; t++) { ++ if (isspace(*t) || *t == '(' || *t == ')') ++ *t = '_'; ++ } ++ rc = rpmdsNSAdd(pool, dsp, NS, f, g, RPMSENSE_EQUAL); ++ if (rc < 0) ++ goto exit; ++ break; ++ case 2: /* Provides: cpuinfo(g) */ ++ for (t = g; *t != '\0'; t++) { ++ if (isspace(*t) || *t == '(' || *t == ')') ++ *t = '_'; ++ } ++ rc = rpmdsNSAdd(pool, dsp, NS, g, "", RPMSENSE_ANY); ++ if (rc < 0) ++ goto exit; ++ break; ++ case 3: /* if ("yes") Provides: cpuinfo(f) */ ++ if (!strcmp(g, "yes")) { ++ rc = rpmdsNSAdd(pool, dsp, NS, f, "", RPMSENSE_ANY); ++ if (rc < 0) ++ goto exit; ++ } ++ break; ++ case 4: /* Provides: cpuinfo(g[i]) */ ++ { char ** av = NULL; ++ int i = 0; ++ rc = poptParseArgvString(g, NULL, (const char ***)&av); ++ if (!rc && av != NULL) ++ while ((t = av[i++]) != NULL) { ++ rc = rpmdsNSAdd(pool, dsp, NS, t, "", RPMSENSE_ANY); ++ if (rc < 0) ++ goto exit; ++ } ++ t = NULL; ++ if (av != NULL) ++ free(av); ++ } break; ++ } ++ } ++ ++exit: ++ _free(cpuinfo_path); ++ free(iob); ++ /* freeze the pool to save memory, but only if private pool */ ++ if (*dsp && (*dsp)->pool != pool) ++ rpmstrPoolFreeze((*dsp)->pool, 0); ++ return (rc < 0) ? -1 : 0; ++} ++ ++int rpmdsCpuinfo(rpmds * dsp) ++{ ++ return rpmdsCpuinfoPool(NULL, dsp); ++} +diff -ur rpm-4.16.0/lib/rpmds.h rpm-4.16.0-cpuinfo/lib/rpmds.h +--- rpm-4.16.0/lib/rpmds.h 2020-11-08 20:19:15.625093667 +0100 ++++ rpm-4.16.0-cpuinfo/lib/rpmds.h 2020-11-08 20:03:44.001865655 +0100 +@@ -419,6 +419,13 @@ + */ + int rpmdsUname(rpmds * dsp); + ++/** ++ * Load cpuinfo provides into a dependency set. ++ * @retval *dsp (loaded) dependency set ++ * @return 0 on success ++ */ ++int rpmdsCpuinfo(rpmds * dsp); ++ + /** \ingroup rpmds + * Create and load a dependency set. + * @param pool shared string pool (or NULL for private pool) +@@ -483,6 +490,14 @@ + */ + int rpmdsUnamePool(rpmstrPool pool, rpmds * dsp); + ++/** ++ * Load cpuinfo provides into a dependency set. ++ * @param pool shared string pool (or NULL for private pool) ++ * @retval *dsp (loaded) dependency set ++ * @return 0 on success ++ */ ++int rpmdsCpuinfoPool(rpmstrPool pool, rpmds * dsp); ++ + + typedef enum rpmrichOp_e { + RPMRICHOP_SINGLE = 1, +diff -ur rpm-4.16.0/lib/rpmts_internal.h rpm-4.16.0-cpuinfo/lib/rpmts_internal.h +--- rpm-4.16.0/lib/rpmts_internal.h 2020-11-08 20:19:15.625093667 +0100 ++++ rpm-4.16.0-cpuinfo/lib/rpmts_internal.h 2020-11-08 20:22:24.382319931 +0100 +@@ -22,6 +22,7 @@ + + rpmds rpmlib; /*!< rpmlib() dependency set. */ + rpmds uname; /*!< uname() dependency set. */ ++ rpmds cpuinfo; /*!< cpuinfo() dependency set. */ + rpmte * order; /*!< Packages sorted by dependencies. */ + int orderCount; /*!< No. of transaction elements. */ + int orderAlloced; /*!< No. of allocated transaction elements. */ diff --git a/rpm.spec b/rpm.spec index 9d5dc2c..c7bef13 100644 --- a/rpm.spec +++ b/rpm.spec @@ -26,7 +26,7 @@ Summary(ru.UTF-8): Менеджер пакетов от RPM Summary(uk.UTF-8): Менеджер пакетів від RPM Name: rpm Version: 4.16.0 -Release: 0.5 +Release: 0.7 Epoch: 1 License: GPL v2 / LGPL v2.1 Group: Base @@ -75,6 +75,8 @@ Patch20: uname-deps.patch Patch21: aarch64.patch Patch22: ix86-platforms.patch Patch23: shortcircuited-deps.patch +Patch24: cpuinfo-deps.patch +Patch25: rpmio-read-proc-files.patch URL: https://rpm.org/ BuildRequires: acl-devel BuildRequires: db-devel >= %{db_ver} @@ -564,6 +566,8 @@ Dokumentacja API RPM-a oraz przewodniki w formacie HTML generowane ze %patch21 -p1 %patch22 -p1 %patch23 -p1 +%patch24 -p1 +%patch25 -p1 install %{SOURCE15} scripts/perl.prov.in diff --git a/rpmio-read-proc-files.patch b/rpmio-read-proc-files.patch new file mode 100644 index 0000000..27118bf --- /dev/null +++ b/rpmio-read-proc-files.patch @@ -0,0 +1,25 @@ +--- rpm-4.16.0/rpmio/rpmio.c~ 2020-08-27 15:13:08.000000000 +0200 ++++ rpm-4.16.0/rpmio/rpmio.c 2020-11-08 21:31:26.311430982 +0100 +@@ -1709,6 +1709,22 @@ + } + b[blen] = '\0'; + } ++#if defined(__linux__) ++ /* XXX st->st_size = 0 for /proc files on linux, see stat(2). */ ++ /* XXX glibc mmap'd libio no workie for /proc files on linux?!? */ ++ else if (!strncmp(fn, "/proc/", sizeof("/proc/")-1)) { ++ blen = blenmax; ++ b = xmalloc(blen+1); ++ b[0] = '\0'; ++ ++ size = read(Fileno(fd), b, blen); ++ if (size < 0) { ++ rc = 1; ++ goto exit; ++ } ++ blen = size; ++ } ++#endif + + exit: + if (fd) (void) Fclose(fd); diff --git a/uname-deps.patch b/uname-deps.patch index 4863617..61ba652 100644 --- a/uname-deps.patch +++ b/uname-deps.patch @@ -7,7 +7,7 @@ index 28a4a784d..1d8ce1f8a 100644 } + char * N = rpmdsN(dep); -+ if (strstr(N, "uname") == N) { ++ if (strstr(N, "uname(") == N) { + if (tsmem->uname == NULL) + rpmdsUnamePool(rpmtsPool(ts), &(tsmem->uname)); + @@ -32,44 +32,53 @@ index f7ee76392..754969e39 100644 #include #include /* rpmvercmp */ -@@ -1596,3 +1597,51 @@ rpmRC rpmdsParseRichDep(rpmds dep, rpmds *leftds, rpmds *rightds, rpmrichOp *op, +@@ -1596,3 +1597,60 @@ rpmRC rpmdsParseRichDep(rpmds dep, rpmds *leftds, rpmds *rightds, rpmrichOp *op, return rc; } ++/** ++ * Merge a single provides, wrapping N as "NS(N)". ++ */ ++static int rpmdsNSAdd(rpmstrPool pool, rpmds *dsp, const char * NS, ++ const char *N, const char *EVR, rpmsenseFlags Flags) ++{ ++ char *t; ++ rpmds ds; ++ int rc; ++ ++ t = (char *) alloca(strlen(NS)+sizeof("()")+strlen(N)); ++ *t = '\0'; ++ (void) stpcpy( stpcpy( stpcpy( stpcpy(t, NS), "("), N), ")"); ++ ++ ds = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME, t, EVR, Flags); ++ rc = rpmdsMerge(dsp, ds); ++ rpmdsFree(ds); ++ return rc; ++} ++ +int rpmdsUnamePool(rpmstrPool pool, rpmds * dsp) +{ + int rc = -1; + static const char * NS = "uname"; + struct utsname un; -+ rpmds ds; + + if (uname(&un) < 0) + goto exit; + -+ ds = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME, "uname(sysname)", un.sysname, RPMSENSE_EQUAL); -+ rc = rpmdsMerge(dsp, ds); -+ rpmdsFree(ds); ++ rc = rpmdsNSAdd(pool, dsp, NS, "sysname", un.sysname, RPMSENSE_EQUAL); + if (rc < 0) + goto exit; -+ ds = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME, "uname(nodename)", un.nodename, RPMSENSE_EQUAL); -+ rc = rpmdsMerge(dsp, ds); -+ rpmdsFree(ds); ++ rc = rpmdsNSAdd(pool, dsp, NS, "nodename", un.nodename, RPMSENSE_EQUAL); + if (rc < 0) + goto exit; -+ ds = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME, "uname(release)", un.release, RPMSENSE_EQUAL); -+ rc = rpmdsMerge(dsp, ds); -+ rpmdsFree(ds); ++ rc = rpmdsNSAdd(pool, dsp, NS, "release", un.release, RPMSENSE_EQUAL); + if (rc < 0) + goto exit; -+ ds = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME, "uname(machine)", un.machine, RPMSENSE_EQUAL); -+ rc = rpmdsMerge(dsp, ds); -+ rpmdsFree(ds); ++ rc = rpmdsNSAdd(pool, dsp, NS, "machine", un.machine, RPMSENSE_EQUAL); + if (rc < 0) + goto exit; +#if defined(__linux__) -+ ds = rpmdsSinglePool(pool, RPMTAG_PROVIDENAME, "uname(domainname)", un.domainname, RPMSENSE_EQUAL); -+ rc = rpmdsMerge(dsp, ds); -+ rpmdsFree(ds); ++ rc = rpmdsNSAdd(pool, dsp, NS, "domainname", un.domainname, RPMSENSE_EQUAL); + if (rc < 0) + goto exit; +#endif