1*4882a593SmuzhiyunFrom 60babcd97b871c8f037b426beb57f21d20d57a9e Mon Sep 17 00:00:00 2001 2*4882a593SmuzhiyunFrom: Shunqian Zheng <zhengsq@rock-chips.com> 3*4882a593SmuzhiyunDate: Thu, 6 Jan 2022 15:06:44 +0800 4*4882a593SmuzhiyunSubject: [PATCH] bspatch: adaption to embedded system 5*4882a593Smuzhiyun 6*4882a593SmuzhiyunUse mmap to avoid large memory allocation. 7*4882a593SmuzhiyunSupport read old file from block device(e.g. /dev/mmcblkMpN), which 8*4882a593Smuzhiyunrequires an extra old-file-size argument. 9*4882a593Smuzhiyun 10*4882a593SmuzhiyunSigned-off-by: Shunqian Zheng <zhengsq@rock-chips.com> 11*4882a593Smuzhiyun--- 12*4882a593Smuzhiyun bspatch.c | 50 +++++++++++++++++++++++++++++++++++--------------- 13*4882a593Smuzhiyun 1 file changed, 35 insertions(+), 15 deletions(-) 14*4882a593Smuzhiyun 15*4882a593Smuzhiyundiff --git a/bspatch.c b/bspatch.c 16*4882a593Smuzhiyunindex de47d2a..0c6952c 100644 17*4882a593Smuzhiyun--- a/bspatch.c 18*4882a593Smuzhiyun+++ b/bspatch.c 19*4882a593Smuzhiyun@@ -36,6 +36,8 @@ __FBSDID("$FreeBSD: src/usr.bin/bsdiff/bspatch/bspatch.c,v 1.1 2005/08/06 01:59: 20*4882a593Smuzhiyun #include <unistd.h> 21*4882a593Smuzhiyun #include <fcntl.h> 22*4882a593Smuzhiyun #include <sys/types.h> 23*4882a593Smuzhiyun+#include <sys/mman.h> 24*4882a593Smuzhiyun+#include <sys/stat.h> 25*4882a593Smuzhiyun 26*4882a593Smuzhiyun static off_t offtin(u_char *buf) 27*4882a593Smuzhiyun { 28*4882a593Smuzhiyun@@ -69,8 +71,25 @@ int main(int argc,char * argv[]) 29*4882a593Smuzhiyun off_t ctrl[3]; 30*4882a593Smuzhiyun off_t lenread; 31*4882a593Smuzhiyun off_t i; 32*4882a593Smuzhiyun- 33*4882a593Smuzhiyun- if(argc!=4) errx(1,"usage: %s oldfile newfile patchfile\n",argv[0]); 34*4882a593Smuzhiyun+ struct stat old_stat; 35*4882a593Smuzhiyun+ 36*4882a593Smuzhiyun+ if(argc!=4 && argc!=5) errx(1,"usage: %s oldfile newfile patchfile\n" 37*4882a593Smuzhiyun+ " or\n" 38*4882a593Smuzhiyun+ " %s /dev/mmcblkMpN newfile patchfile oldsize\n", argv[0]); 39*4882a593Smuzhiyun+ 40*4882a593Smuzhiyun+ oldsize = 0; 41*4882a593Smuzhiyun+ stat(argv[1], &old_stat); 42*4882a593Smuzhiyun+ if (old_stat.st_mode & S_IFBLK && argc == 5) { 43*4882a593Smuzhiyun+ oldsize = atoi(argv[4]); 44*4882a593Smuzhiyun+ } else if (old_stat.st_mode & S_IFREG && argc == 4) { 45*4882a593Smuzhiyun+ if(((fd=open(argv[1],O_RDONLY,0))<0) || 46*4882a593Smuzhiyun+ ((oldsize=lseek(fd,0,SEEK_END))<=0) || 47*4882a593Smuzhiyun+ (close(fd)==-1)) 48*4882a593Smuzhiyun+ err(1,"file %s size err!",argv[1]); 49*4882a593Smuzhiyun+ } else { 50*4882a593Smuzhiyun+ errx(1, "oldfile shall be regular file or block device,\n" 51*4882a593Smuzhiyun+ " for block device, the oldfile_size arg is needed\n"); 52*4882a593Smuzhiyun+ } 53*4882a593Smuzhiyun 54*4882a593Smuzhiyun /* Open patch file */ 55*4882a593Smuzhiyun if ((f = fopen(argv[3], "r")) == NULL) 56*4882a593Smuzhiyun@@ -105,7 +124,7 @@ int main(int argc,char * argv[]) 57*4882a593Smuzhiyun bzctrllen=offtin(header+8); 58*4882a593Smuzhiyun bzdatalen=offtin(header+16); 59*4882a593Smuzhiyun newsize=offtin(header+24); 60*4882a593Smuzhiyun- if((bzctrllen<0) || (bzdatalen<0) || (newsize<0)) 61*4882a593Smuzhiyun+ if((bzctrllen<0) || (bzdatalen<0) || (newsize<=0)) 62*4882a593Smuzhiyun errx(1,"Corrupt patch\n"); 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun /* Close patch file and re-open it via libbzip2 at the right places */ 65*4882a593Smuzhiyun@@ -133,13 +152,19 @@ int main(int argc,char * argv[]) 66*4882a593Smuzhiyun if ((epfbz2 = BZ2_bzReadOpen(&ebz2err, epf, 0, 0, NULL, 0)) == NULL) 67*4882a593Smuzhiyun errx(1, "BZ2_bzReadOpen, bz2err = %d", ebz2err); 68*4882a593Smuzhiyun 69*4882a593Smuzhiyun+ //if oldfile is a block device, get oldsize from arg 70*4882a593Smuzhiyun if(((fd=open(argv[1],O_RDONLY,0))<0) || 71*4882a593Smuzhiyun- ((oldsize=lseek(fd,0,SEEK_END))==-1) || 72*4882a593Smuzhiyun- ((old=malloc(oldsize+1))==NULL) || 73*4882a593Smuzhiyun- (lseek(fd,0,SEEK_SET)!=0) || 74*4882a593Smuzhiyun- (read(fd,old,oldsize)!=oldsize) || 75*4882a593Smuzhiyun+ ((old=mmap(NULL,oldsize,PROT_READ,MAP_SHARED|MAP_POPULATE,fd,0))==MAP_FAILED) || 76*4882a593Smuzhiyun (close(fd)==-1)) err(1,"%s",argv[1]); 77*4882a593Smuzhiyun- if((new=malloc(newsize+1))==NULL) err(1,NULL); 78*4882a593Smuzhiyun+ 79*4882a593Smuzhiyun+ /* mmap the new file */ 80*4882a593Smuzhiyun+ if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_RDWR,0666))<0) || 81*4882a593Smuzhiyun+ (lseek(fd,newsize-1,SEEK_SET)!=(newsize-1)) || 82*4882a593Smuzhiyun+ (write(fd, "E", 1) != 1) || 83*4882a593Smuzhiyun+ (lseek(fd,0,SEEK_SET)!=0) || 84*4882a593Smuzhiyun+ ((new=mmap(NULL,newsize,PROT_READ | PROT_WRITE,MAP_SHARED,fd,0))==MAP_FAILED) || 85*4882a593Smuzhiyun+ (close(fd)==-1)) 86*4882a593Smuzhiyun+ err(1,"%s",argv[2]); 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun oldpos=0;newpos=0; 89*4882a593Smuzhiyun while(newpos<newsize) { 90*4882a593Smuzhiyun@@ -193,13 +218,8 @@ int main(int argc,char * argv[]) 91*4882a593Smuzhiyun if (fclose(cpf) || fclose(dpf) || fclose(epf)) 92*4882a593Smuzhiyun err(1, "fclose(%s)", argv[3]); 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun- /* Write the new file */ 95*4882a593Smuzhiyun- if(((fd=open(argv[2],O_CREAT|O_TRUNC|O_WRONLY,0666))<0) || 96*4882a593Smuzhiyun- (write(fd,new,newsize)!=newsize) || (close(fd)==-1)) 97*4882a593Smuzhiyun- err(1,"%s",argv[2]); 98*4882a593Smuzhiyun- 99*4882a593Smuzhiyun- free(new); 100*4882a593Smuzhiyun- free(old); 101*4882a593Smuzhiyun+ munmap(new, newsize); 102*4882a593Smuzhiyun+ munmap(old, oldsize); 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun return 0; 105*4882a593Smuzhiyun } 106*4882a593Smuzhiyun-- 107*4882a593Smuzhiyun2.25.1 108*4882a593Smuzhiyun 109