309 lines
15 KiB
HTML
309 lines
15 KiB
HTML
<!--startcut ==========================================================-->
|
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
|
|
<HTML>
|
|
<HEAD>
|
|
<title>An Introduction to Patch LG #32</title>
|
|
</HEAD>
|
|
<BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#A000A0"
|
|
ALINK="#FF0000">
|
|
<!--endcut ============================================================-->
|
|
|
|
<H4>
|
|
"Linux Gazette...<I>making Linux just a little more fun!</I>"
|
|
</H4>
|
|
|
|
<P> <HR> <P>
|
|
<!--===================================================================-->
|
|
|
|
<center>
|
|
<H1><font color="maroon">Patch for Beginners</font></H1>
|
|
<h4>By <a href="mailto: layers@marktwain.net">Larry Ayers</a></h4>
|
|
</center>
|
|
<P> <HR> <P>
|
|
|
|
<center><h3>Introduction</h3></center>
|
|
|
|
<p>The aim of this article is to introduce new Linux users to an invaluable
|
|
resource, Larry Wall's <i>patch</i> program. <i>Patch</i> is an interface to
|
|
the GNU <i>diff</i> utility, which is used to find differences between files;
|
|
<i>diff</i> has a multitude of options, but it's most often used to generate a file
|
|
which lists lines which have been changed, showing both the original and
|
|
changed lines and ignoring lines which have remained the same. <i>Patch</i>
|
|
is typically used to update a directory of source code files to a newer
|
|
version, obviating the need to download an entire new source archive.
|
|
Downloading a patch in effect is just downloading the lines which have been
|
|
changed.
|
|
|
|
<p><i>Patch</i> originated in the nascent, bandwidth-constrained internet
|
|
environment of a decade ago, but like many Unix tools of that era it is still
|
|
much-used today. In the February issue of the programmer's magazine
|
|
<b>Dr. Dobb's Journal</b> Larry Wall had some interesting comments on the
|
|
early days of <i>patch</i>:
|
|
|
|
<pre><blockquote>
|
|
|
|
DDJ: By the way, what came first, patch or diff?
|
|
|
|
LW: diff, by a long ways. patch is one of those things
|
|
that, in retrospect, I was totally amazed that nobody had
|
|
thought of it sooner, because I think that diff predated
|
|
patch by at least ten years or so.
|
|
|
|
I think I know why, though. And it's one of these little
|
|
psychological things. When they made diff, they added an
|
|
option called -e, I think it was, and that would spit out an
|
|
ed script, so people said to themselves, "Well, if I wanted
|
|
to automate the applying of a diff, I would use that." So it
|
|
never actually occurred to someone that you could write a
|
|
computer program to take the other forms of output and apply
|
|
them. Either that, or it did not occur to them that there
|
|
was some benefit to using the context diff form, because you
|
|
could apply it to something that had been changed and still
|
|
easily get it to do the right thing.
|
|
|
|
It's one of those things that's obvious in retrospect. But
|
|
to be perfectly honest, it wasn't really a brilliant flash
|
|
of inspiration so much as self defense. I put out the first
|
|
version of rn, and then I started putting out patches for
|
|
it, and it was a total mess. You could not get people to
|
|
apply patches because they had to apply them by hand. So,
|
|
they would skip the ones that they didn't think they needed,
|
|
and they'd apply the new ones over that, and they'd get
|
|
totally messed up. I wrote patch so that they wouldn't have
|
|
this excuse that it was too hard.
|
|
|
|
I don't know whether it's still the case, but for many
|
|
years, I told people that I thought patch had changed the
|
|
culture of computing more than either rn or Perl had. Now
|
|
that the Internet is getting a lot faster than it used to
|
|
be, and it's getting much easier to distribute whole
|
|
distributions, patches tend to be sent around only among
|
|
developers. I haven't sent out a patch kit for Perl in
|
|
years. I think patch has became less important for the
|
|
whole thing, but still continues to be a way for developers
|
|
to interchange ideas. But for a while in there, patch
|
|
really did make a big difference to how software was
|
|
developed. </blockquote></pre>
|
|
|
|
<p>Larry Wall's assessment of the diminishing importance of <i>patch</i> to
|
|
the computing community as a whole is probably accurate, but in the free
|
|
software world it's still an essential tool. The ubiquity of <i>patch</i>
|
|
makes it possible for new users and non-programmers to easily participate in
|
|
alpha- and beta-testing of software, thus benefiting the entire community.
|
|
|
|
<p>It occurred to me to write this article after noticing a thread which
|
|
periodically resurfaces in the linux-kernel mailing list. About every three
|
|
months someone will post a plea for a split Linux kernel source distribution,
|
|
so that someone just interested in, say, the i386 code and the IDE disk driver
|
|
wouldn't have to download the Alpha, Sparc, etc. files and the many SCSI
|
|
drivers for each new kernel release. A series of patient (and some
|
|
not-so-patient) replies will follow, most urging the original poster to use
|
|
patches to upgrade the kernel source. Linus Torvalds will then once again
|
|
state that he has no interest in undertaking the laborious task of splitting
|
|
the kernel source into chunks, but that if anyone else wants to, they should
|
|
feel free to do so as an independent project. So far no-one has volunteered.
|
|
I can't blame the kernel-hackers for not wanting to further complicate their
|
|
lives; I imagine it would be much more interesting and challenging to work
|
|
directly with the kernel than to overhaul the entire kernel distribution
|
|
scheme! Downloading an eleven megabyte kernel source archive <i>is</i>
|
|
time-consuming (and, for those folks paying by the minute for net access,
|
|
expensive as well) but the kernel patches can be as small as a few dozen
|
|
kilobytes, and are hardly ever larger than one megabyte. The 2.1.119
|
|
development kernel source on my hard disk has been incrementally patched up
|
|
from version 2.1.99, and I doubt if I'd follow the development as closely if I
|
|
had to download each release in its entirety.
|
|
|
|
<center><h3>Using Patch</h3></center>
|
|
|
|
<p><i>Patch</i> comes with a good manual-page which lists its numerous
|
|
options, but 99% of the time just two of them will suffice:
|
|
|
|
<ul>
|
|
<li><kbd>patch -p1 < [patchfile]</kbd>
|
|
<li><kbd>patch -R < [patchfile]</kbd> (used to undo a patch)
|
|
</ul>
|
|
|
|
<p>The <i>-p1</i> option strips the left-most directory level from the
|
|
filenames in the patch-file, as the top-level directory is likely to vary on
|
|
different machines. To use this option, place your patch within the directory
|
|
being patched, and then run <i>patch -p1 < [patchfile]</i> from within that
|
|
directory. A short excerpt from a Linux kernel patch will illustrate
|
|
this:<br>
|
|
|
|
<pre><kbd>
|
|
diff -u --recursive --new-file v2.1.118/linux/mm/swapfile.c linux/mm/swapfile.c
|
|
--- v2.1.118/linux/mm/swapfile.c Wed Aug 26 11:37:45 1998
|
|
+++ linux/mm/swapfile.c Wed Aug 26 16:01:57 1998
|
|
@@ -489,7 +489,7 @@
|
|
int swap_header_version;
|
|
int lock_map_size = PAGE_SIZE;
|
|
int nr_good_pages = 0;
|
|
- char tmp_lock_map = 0;
|
|
+ unsigned long tmp_lock_map = 0;
|
|
</kbd></pre>
|
|
|
|
<p>Applying the patch from which this segment was copied with the <i>-p1</i>
|
|
switch effectively truncates the path which <i>patch</i> will seek;
|
|
<i>patch</i> will look for a subdirectory of the current directory named
|
|
<kbd>/mm</kbd>, and should then find the <i>swapfile.c</i> file there, waiting
|
|
to be patched. In this excerpt, the line preceded by a dash will be
|
|
replaced with the line preceded by a plus sign. A typical patch will contain
|
|
updates for many files, each section consisting of the output of <i>diff
|
|
-u</i> run on two versions of a file.
|
|
|
|
<p><i>Patch</i> displays its output to the screen as it works, but this output
|
|
usually scrolls by too quickly to read. The original, pre-patch files are
|
|
renamed <i>*.orig</i>, while the new patched files will bear the original
|
|
filenames.
|
|
|
|
<center><h3>Patching Problems</h3></center>
|
|
|
|
<p>One possible source of problems using patch is differences between various
|
|
versions, all of which are available on the net. Larry Wall hasn't done much
|
|
to improve patch in recent years, possibly because his last release of the
|
|
utility works well in the majority of situations. FSF programmers
|
|
from the GNU project have been releasing new versions of patch for the past
|
|
several years. Their first revisions of patch had a few problems, but I've been
|
|
using version 2.5 (which is the version distributed with Debian 2.0) lately
|
|
with no problems. Version 2.1 has worked well for me in the past. The source
|
|
for the current GNU version of <i>patch</i> is available from the
|
|
<a href="ftp://ftp.gnu.org/pub/gnu">GNU</a> FTP site, though most people will
|
|
just use the version supplied with their distribution of Linux.
|
|
|
|
<p>Let's say you have patched a directory of source files, and the patch
|
|
didn't apply cleanly . This happens occasionally, and when it does
|
|
<i>patch</i> will show an error message indicating which file confused it,
|
|
along with the line numbers. Sometimes the error will be obvious, such as an
|
|
omitted semicolon, and can be fixed without too much trouble. Another
|
|
possibility is to delete from the patch the section which is causing trouble,
|
|
but this may or may not work, depending on the file involved.
|
|
|
|
<p>Another common error scenario: suppose you have un-tarred a kernel source
|
|
archive, and while exploring the various subdirectories under
|
|
<kbd>/linux/arch/</kbd> you notice the various machine architecture
|
|
subdirectories, such as <kbd>alpha</kbd>, <kbd>sparc</kbd>, etc. If you, like
|
|
most Linux users, are running a machine with an Intel processor (or one of the
|
|
Intel clones), you might decide to delete these directories, which are not
|
|
needed for compiling your particular kernel and which occupy needed
|
|
disk space. Some time later a new kernel patch is released and while
|
|
attempting to apply it <i>patch</i> stalls when it is unable to find the Alpha
|
|
or PPC files it would like to patch. Luckily <i>patch</i> allows user
|
|
intervention at this point, asking the question "Skip this patch?" Tell it
|
|
"y", and <i>patch</i> will proceed along its merry way. You will probably
|
|
have to answer the question numerous times, which is a good argument for
|
|
allowing the un-needed directories to remain on your disk.
|
|
|
|
|
|
<center><h3>Kernel-Patching Tips</h3></center>
|
|
|
|
<p>Many Linux users use <i>patch</i> mainly for patching the kernel source, so
|
|
a few tips are in order. Probably the easiest method is to use the
|
|
shell-script <i>patch-kernel</i>, which can be found in the
|
|
<kbd>/scripts</kbd> subdirectory of the kernel source-tree. This handy and
|
|
well-written script was written by Nick Holloway in 1995; a couple of years
|
|
later Adam Sulmicki added support for several compression algorithms,
|
|
including *.bz, *.bz2, compress, gzip, and plain-text (i.e., a patch which has
|
|
already been uncompressed). The script assumes that your kernel source is in
|
|
<kbd>/usr/src/linux,</kbd>, with your new patch located in the current
|
|
directory. Both of these defaults can be overridden by command-line switches
|
|
in this format: <kbd>patch-kernel [ sourcedir [ patchdir ] ]</kbd>.
|
|
<i>Patch-kernel</i> will abort if any part of the patch fails, but if the
|
|
patch applies cleanly it will invoke <i>find</i>, which will delete all of the
|
|
<kbd>*.orig</kbd> files which <i>patch</i> leaves behind.
|
|
|
|
<p>If you prefer to see the output of commands, or perhaps you would rather
|
|
keep the <kbd>*.orig</kbd> files until you are certain the patched source
|
|
compiles, running <i>patch</i> directly (with the patch located in the kernel
|
|
source top-level directory, as outlined above) has been very reliable in my
|
|
experience. In order to avoid uncompressing the patch before
|
|
applying it a simple pipe will do the trick:
|
|
|
|
<p><kbd>gzip -cd patchXX.gz | patch -p1</kbd><br>
|
|
|
|
<p>or:
|
|
|
|
<p><kbd>bzip2 -dc patchXX.bz2 | patch -p1</kbd>
|
|
|
|
<p>After the patch has been applied the <i>find</i> utility can be used to
|
|
check for rejected files:
|
|
|
|
<p><kbd>find . -name \*.rej</kbd>
|
|
|
|
<p>At first the syntax of this command is confusing. The period indicates
|
|
that <i>find</i> should look in the current directory and recursively in all
|
|
subdirectories beneath it. Remember the period should have a space both
|
|
before and after it. The backslash before the wildcard "*" "escapes" the
|
|
asterisk in order to avoid confusing the shell, for which an asterisk has
|
|
another meaning. If <i>find</i> locates any <kbd>*.rej</kbd> files it will
|
|
print the filenames on the screen. If <i>find</i> exits without any visible
|
|
output it's nearly certain the patch applied correctly.
|
|
|
|
<p>Another job for <i>find</i> is to remove the <kbd>*.orig</kbd> files:
|
|
|
|
<p><kbd>find . -name \*.orig -print0 | xargs -0r rm -f</kbd>
|
|
|
|
<p>This command is sufficiently cumbersome to type that it would be a good
|
|
candidate for a new shell alias. A line in your ~/.bashrc file such as:
|
|
|
|
<p><kbd>alias findorig 'find . -name \*.orig -print0 | xargs -0r rm -f'</kbd>
|
|
|
|
<p>will allow just typing <kbd>findorig</kbd> to invoke the above command.
|
|
The single quotes in the alias definition are necessary if an aliased command
|
|
contains spaces. In order to use a new alias without logging out and then
|
|
back in again, just type <kbd>source ~/.bashrc</kbd> at the prompt.
|
|
|
|
<center><h3>Incidental Comments and Conclusion</h3></center>
|
|
|
|
|
|
<p>While putting this article together I upgraded the version of <i>patch</i>
|
|
on my machine from version 2.1 to version 2.5. Both of these versions come
|
|
from the current FSF/GNU maintainers. Immediately I noticed that the default
|
|
output of version 2.5 has been changed, with less information appearing on the
|
|
screen. Gone is Larry Wall's "...hmm" which used to appear while <i>patch</i>
|
|
was attempting to determine the proper lines to patch. The output of version
|
|
2.5 is simply a list of messages such as "patching file [filename]", rather
|
|
than the more copious information shown by earlier versions. Admittedly, the
|
|
information scrolled by too quickly to read, but the output could be
|
|
redirected to a file for later perusal. This change doesn't affect the
|
|
functionality of the program, but does lessen the human element. It seems to
|
|
me that touches such as the old "...hmm" messages, as well as comments in
|
|
source code, are valuable in that they remind the user that a program is the
|
|
result of work performed by a living, breathing human being, rather than a
|
|
sterile collection of bits. The old behavior can be restored by appending the
|
|
switch <kbd>--verbose</kbd> to the <i>patch</i> command-line, but I'm sure
|
|
that many users either won't be aware of the option or won't bother to type it
|
|
in. Another difference between 2.1 and 2.5 is that the <i>*.orig</i> back-up
|
|
files aren't created unless <i>patch</i> is given the <kbd>-b</kbd> option.
|
|
|
|
<p><i>Patch</i> is not strictly necessary for an end-user who isn't interested
|
|
in trying out and providing bug-reports for "bleeding-edge" software and
|
|
kernels, but often the most interesting developments in the Linux world belong
|
|
in this category. It isn't difficult to get the hang of using <i>patch</i>, and the
|
|
effort will be amply repaid.
|
|
|
|
<p>
|
|
<hr>
|
|
<!-- hhmts start -->
|
|
Last modified: Mon 31 Aug 1998
|
|
<!-- hhmts end -->
|
|
|
|
<!--===================================================================-->
|
|
<P> <hr> <P>
|
|
<center><H5>Copyright © 1998, Larry Ayers <BR>
|
|
Published in Issue 32 of <i>Linux Gazette</i>, September 1998</H5></center>
|
|
|
|
<!--===================================================================-->
|
|
<P> <hr> <P>
|
|
<A HREF="./index.html"><IMG ALIGN=BOTTOM SRC="../gx/indexnew.gif"
|
|
ALT="[ TABLE OF CONTENTS ]"></A>
|
|
<A HREF="../index.html"><IMG ALIGN=BOTTOM SRC="../gx/homenew.gif"
|
|
ALT="[ FRONT PAGE ]"></A>
|
|
<A HREF="./bandel.html"><IMG SRC="../gx/back2.gif"
|
|
ALT=" Back "></A>
|
|
<A HREF="./ayers2.html"><IMG SRC="../gx/fwd.gif" ALT=" Next "></A>
|
|
<P> <hr> <P>
|
|
<!--startcut ==========================================================-->
|
|
</BODY>
|
|
</HTML>
|
|
<!--endcut ============================================================-->
|