I am a new Linux and Unix system user. I also know that I can patch binary package using up2date or yum command in Linux. I was wondering is if there’s a way to apply a patch file to downloaded source code on a Linux / UNIX like operating system source tree?
Linux and UNIX source software often comes with security and other patches. You can download them from Internet or project home page. There is a command called patch that apply a diff file or patch to an original source tree.
[donotprint][/donotprint]
The patch command takes a patch file patchfile containing a difference listing produced by the diff program and applies those differences to one or more original files, producing patched versions. Normally the patched versions are put in place of the originals.
patch command syntax
The basic syntax is as follows:
$ patch < patch.file
$ patch source.code.file < patch.file
$ patch -p LEVEL < {/path/to/patch/file}
To apply a patch, one could run the following command in a shell:
$ patch < /path/to/file
In this example, patch foo.c with patch.diff file:
$ patch foo.c < patch.diff
Patches can be undone, or reversed, with the '-R' option:
$ patch -R < /path/to/file
How do I create a patch?
To create a patch, one could run the following diff command:
$ diff -u oldfile-name-here newfile-name-here > patch.diff
Example: Creating and applying the patch for hello.c sample program on a Linux or Unix like system
Create a hello.c as follows:
#include<stdio.h> main(){ printf("Hello, world!n"); } |
Make a copy of the hello.c (or file you wish to modify); both files must be in the same directory, though it may be any directory using cp command:
$ cp hello.c hello-new.c
Edit the file hello-new.c to make it as you want it. In this example, I am fixing a few compiler warning by adding return value from main():
#include<stdio.h> int main(void){ printf("Hello, world!n"); return 0; } |
Next, use command diff to create a unified diff patch file called hello.patch:
$ diff -u hello.c hello-new.c > hello.patch
To see patch use cat command as follows:
$ cat hello.patch
Sample outputs:
--- hello.c 2014-04-29 17:59:49.000000000 +0530 +++ hello-new.c 2014-04-29 18:00:43.000000000 +0530 @@ -1,5 +1,6 @@ #include<stdio.h> -main(){ +int main(void){ printf("Hello, world!n"); + return 0; } |
To apply the patch from hello.patch, enter:
### The hello.patch patchfile knows the name of the file to be patched ## patch < hello.patch |
Sample outputs:
patching file hello.c
Finally, here is my updated and patched hello.c:
$ cat hello.c
Sample outputs:
#include<stdio.h> int main(void){ printf("Hello, world!n"); return 0; } |
You can now compile program:
$ cc hello.c -o hello
Run it as follows:
$ ./hello
Sample outputs:
Hello, world!
A note about working on an entire source tree
First, make a copy of the source tree:
## Original source code is in lighttpd-1.4.35/ directory ##
$ cp -R lighttpd-1.4.35/ lighttpd-1.4.35-new/
Cd to lighttpd-1.4.35-new directory and make changes as per your requirements:
$ cd lighttpd-1.4.35-new/
$ vi geoip-mod.c
$ vi Makefile
Finally, create a patch with the following command:
$ cd ..
$ diff -rupN lighttpd-1.4.35/ lighttpd-1.4.35-new/ > my.patch
You can use my.patch file to patch lighttpd-1.4.35 source code on a different computer/server using patch command as discussed above:
patch -p1 < my.patch
See the man page of patch and other command for more information and usage - bash(1)