/etc/portage/patches

From Gentoo Wiki
< /etc/portage(Redirected from Epatch)
Jump to: navigation, search

User patches provide a way for users to apply patches to package source code if the ebuild provides this feature. Ebuilds cannot be patched by this. This is useful for applying upstream patches to unresolved bugs and for the rare cases of site-specific patches.

Precondition

EAPI 6 and greater

User patching is supported as a requirement of EAPI 6 and greater. Failure to support user patching results in an error.

EAPI 5 and older

  • The ebuild is calling epatch_user explicitly
  • The ebuild is inheriting an eclass and relying on its default implementation of src_prepare

Adding user patches

First choose the location for the patches, depending on the package name and the version(s) it is intended for. Use the following locations and optionally append :${SLOT} to any of them:

  • /etc/portage/patches/${CATEGORY}/${P}
  • /etc/portage/patches/${CATEGORY}/${PN}
  • /etc/portage/patches/${CATEGORY}/${P}-${PR}

Examples:

  • /etc/portage/patches/dev-lang/python
  • /etc/portage/patches/dev-lang/python:3.4
  • /etc/portage/patches/dev-lang/python-3.4.2
  • /etc/portage/patches/dev-lang/python-3.3.5-r1

Example

An example shows how to easily apply an upstream patch for CVE-2017-8934 of x11-misc/pcmanfm.
The affected version of that package is 1.2.5 and upstream provides the patch for it but has not yet released a new version.

For applying the patch from upstream, the appropriate directory needs to be created:

root #mkdir -p /etc/portage/patches/x11-misc/pcmanfm-1.2.5

Next, an arbitrarily named file with suffix .patch has to be dropped here with the content provided from upstream:

# index 8c2049a..876f7f3 100644 (file)
# --- a/NEWS
# +++ b/NEWS
# @@ -1,3 +1,7 @@
# +* Fixed potential access violation, use runtime user dir instead of tmp dir
# +    for single instance socket.
# +
# +
#  Changes on 1.2.5 since 1.2.4:
 
 * Removed options to Cut, Remove and Rename from context menu on mounted
diff --git a/src/single-inst.c b/src/single-inst.c
index 62c37b3..aaf84ab 100644 (file)
--- a/src/single-inst.c
+++ b/src/single-inst.c
@@ -2,7 +2,7 @@
  *      single-inst.c: simple IPC mechanism for single instance app
  *
  *      Copyright 2010 Hong Jen Yee (PCMan) <pcman.tw@gmail.com>
- *      Copyright 2012 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
+ *      Copyright 2012-2017 Andriy Grytsenko (LStranger) <andrej@rep.kiev.ua>
  *
  *      This program is free software; you can redistribute it and/or modify
  *      it under the terms of the GNU General Public License as published by
@@ -404,11 +404,16 @@ static void get_socket_name(SingleInstData* data, char* buf, int len)
     }
     else
         dpynum = 0;
+#if GLIB_CHECK_VERSION(2, 28, 0)
+    g_snprintf(buf, len, "%s/%s-socket-%s-%d", g_get_user_runtime_dir(),
+               data->prog_name, host ? host : "", dpynum);
+#else
     g_snprintf(buf, len, "%s/.%s-socket-%s-%d-%s",
                 g_get_tmp_dir(),
                 data->prog_name,
                 host ? host : "",
                 dpynum,
                 g_get_user_name());
+#endif
 }

For testing, step into the package's ebuild directory and run the ebuild pcmanfm-1.2.5.ebuild clean prepare:

user $cd $(portageq get_repo_path / gentoo)/x11-misc/pcmanfm
user $ebuild pcmanfm-1.2.5.ebuild clean prepare
 * pcmanfm-1.2.5.tar.xz SHA256 SHA512 WHIRLPOOL size ;-) ...             [ ok ]
 * checking ebuild checksums ;-) ...                                     [ ok ]
 * checking auxfile checksums ;-) ...                                    [ ok ]
 * checking miscfile checksums ;-) ...                                   [ ok ]
>>> Unpacking source...
>>> Unpacking pcmanfm-1.2.5.tar.xz to /var/tmp/portage/x11-misc/pcmanfm-1.2.5/work
>>> Source unpacked in /var/tmp/portage/x11-misc/pcmanfm-1.2.5/work
>>> Preparing source in /var/tmp/portage/x11-misc/pcmanfm-1.2.5/work/pcmanfm-1.2.5 ...
 * Applying patches from /etc/portage/patches/x11-misc/pcmanfm-1.2.5 ...
 *   CVE-2017-8934.patch ...                               [ ok ]
 * User patches applied.
>>> Source prepared.

With the message "User patches applied." all is good and the package needs to be re-emerged as normally.

Once the patch gets merged to the ebuild repository, do not forget to remove it from the /etc/portage/patches directory. Otherwise next time compiling the ebuild might fail.

Using a git directory as a source of patches

Instead of creating the directory, a symlink can be created to a git directory on the system.

root #mkdir -p /etc/portage/patches/sys-libs && ln -s /home/user/projects/glibc /etc/portage/patches/sys-libs/glibc
Note
When using userpriv as a FEATURES value in Portage (eg. in /etc/portage/make.conf), Portage drops root privileges to portage:portage which means that the folder that the symlink points to must be accessible by the user or group portage otherwise the patches will be silently ignored and not applied (file epatch_user.log contains the string none); ie. in this case, all the folders of /home/user/projects/glibc are already accessible due to o+rx permissions but in the case of root and using this path /root/projects/glibc then /root, unlike /home, is inaccessible due to u+rx permissions...

Now, in the git directory, perform the usual work. After finishing remove all patches from the previous run and use git format-patch to create a patchset from the branch based on another known branch.

user $rm -f *.patch && git format-patch origin/master

This solution relies on the fact that only files ending with .patch are processed in the patch directory.

Enabling /etc/portage/patches for all ebuilds

If an ebuild has EAPI=5 or older and does not call epatch_user, but user patches are still needed to be applied, it is possible to use /etc/portage/bashrc and hooks provided by Portage. Candidates are post_src_unpack, pre_src_prepare or post_src_prepare. The first two have the advantage of being run before eautoreconf (or similar) and the last two have the advantage of being run in the right directory, so only pre_src_prepare shares those advantages.

Normally only ebuilds inheriting epatch can access epatch_user, so one would need to test for its presence and non-epatch ebuilds would not get patched at all. There is a trick of pulling in only the necessary bits from epatch.eclass, running epatch_user and dropping them.

With pre_src_prepare and the above trick, changing directories do not need to be played with, all ebuilds can be supported whether they import epatch or not, and the patches will applied as soon as possible in the chain. While it might still be better to have this feature as part of Portage, the following snippet should cover everyday needs pretty well.

FILE /etc/portage/bashrc
pre_src_prepare() {
    [[ ${EAPI:-0} == [012345] ]] || return
    if ! type estack_push > /dev/null 2>&1; then
        local estack_names="eshopts_push eshopts_pop evar_push evar_push_set evar_pop estack_push estack_pop"
        source <(awk "/^# @(FUNCTION|VARIABLE): / { p = 0 } /^# @(FUNCTION|VARIABLE): (${estack_names// /|})\$/ { p = 1 } p { print }" ${PORTDIR}/eclass/estack.eclass)
    fi
    if ! type epatch_user > /dev/null 2>&1; then
        local epatch_names="EPATCH_SOURCE EPATCH_USER_SOURCE epatch_user_death_notice epatch_user epatch"
        source <(awk "/^# @(FUNCTION|VARIABLE): / { p = 0 } /^# @(FUNCTION|VARIABLE): (${epatch_names// /|})\$/ { p = 1 } p { print }" ${PORTDIR}/eclass/epatch.eclass)
    fi

    epatch_user

    for name in $epatch_names; do
        unset $name
    done
    for name in $estack_names; do
        unset $name
    done

}

See also

External resources