]>
Commit | Line | Data |
---|---|---|
40ce7301 JB |
1 | diff -Nur coreutils-4.5.3.orig/doc/coreutils.texi coreutils-4.5.3/doc/coreutils.texi |
2 | --- coreutils-4.5.3.orig/doc/coreutils.texi Sun Oct 27 22:19:34 2002 | |
3 | +++ coreutils-4.5.3/doc/coreutils.texi Sun Oct 27 22:48:17 2002 | |
4 | @@ -6188,6 +6188,11 @@ | |
5 | @xref{Backup options}. | |
6 | Make a backup of each file that would otherwise be overwritten or removed. | |
7 | ||
8 | +@item -C | |
9 | +@opindex -C | |
10 | +Install file, unless target already exists and is the same file, in which | |
11 | +case the modification time is not changed. | |
12 | + | |
13 | @item -c | |
14 | @opindex -c | |
15 | Ignored; for compatibility with old Unix versions of @command{install}. | |
16 | diff -Nur coreutils-4.5.3.orig/src/install.c coreutils-4.5.3/src/install.c | |
17 | --- coreutils-4.5.3.orig/src/install.c Thu Sep 26 10:39:20 2002 | |
18 | +++ coreutils-4.5.3/src/install.c Sun Oct 27 22:48:17 2002 | |
19 | @@ -25,6 +25,7 @@ | |
20 | #include <stdio.h> | |
21 | #include <getopt.h> | |
22 | #include <sys/types.h> | |
23 | +#include <sys/mman.h> | |
24 | #include <pwd.h> | |
25 | #include <grp.h> | |
26 | ||
27 | @@ -113,6 +114,9 @@ | |
28 | no effect. */ | |
29 | static mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; | |
30 | ||
31 | +/* Compare files before installing (-C) */ | |
32 | +static int docompare=0; | |
33 | + | |
34 | /* If nonzero, strip executable files after copying them. */ | |
35 | static int strip_files; | |
36 | ||
37 | @@ -136,6 +140,82 @@ | |
38 | {NULL, 0, NULL, 0} | |
39 | }; | |
40 | ||
41 | +int compare (const char *file, const char *to) | |
42 | +{ | |
43 | + void *p, *q; | |
44 | + int ret=0; | |
45 | + size_t size; | |
46 | + int done=0; | |
47 | + struct stat file_s, to_s; | |
48 | + int file_fd, to_fd; | |
49 | + | |
50 | + stat(file, &file_s); | |
51 | + stat(to, &to_s); | |
52 | + | |
53 | + if (file_s.st_size != to_s.st_size) | |
54 | + return 1; | |
55 | + | |
56 | + file_fd = open(file, O_RDONLY); | |
57 | + if (file_fd < 0) | |
58 | + return 1; | |
59 | + | |
60 | + to_fd = open(to, O_RDONLY); | |
61 | + if (to_fd < 0) | |
62 | + { | |
63 | + close(file_fd); | |
64 | + return 1; | |
65 | + } | |
66 | + | |
67 | + size = (size_t) file_s.st_size; | |
68 | + if (size <= 4194309) /* Don't try to mmap() files > 4 MB */ | |
69 | + { | |
70 | + p = mmap(NULL, size, PROT_READ, MAP_SHARED, file_fd, (off_t) 0); | |
71 | + if (p != MAP_FAILED) | |
72 | + { | |
73 | + q = mmap(NULL, size, PROT_READ, MAP_SHARED, to_fd, (off_t) 0); | |
74 | + if (q == MAP_FAILED) | |
75 | + { | |
76 | + munmap(p, size); | |
77 | + } | |
78 | + else | |
79 | + { | |
80 | + ret = (memcmp(p, q, size)==0) ? 0 : 1; | |
81 | + munmap(p, size); | |
82 | + munmap(q, size); | |
83 | + done = 1; | |
84 | + } | |
85 | + } | |
86 | + } | |
87 | + if (!done) | |
88 | + { | |
89 | + char buf1[65536], buf2[65536]; | |
90 | + int n1, n2; | |
91 | + | |
92 | + lseek(file_fd, 0, SEEK_SET); | |
93 | + lseek(to_fd, 0, SEEK_SET); | |
94 | + while (ret == 0) | |
95 | + { | |
96 | + n1 = read(file_fd, buf1, sizeof(buf1)); | |
97 | + if (n1 == 0) | |
98 | + break; | |
99 | + else if (n1 > 0) | |
100 | + { | |
101 | + n2 = read(to_fd, buf2, n1); | |
102 | + if (n2 == n1) | |
103 | + ret = memcmp(buf1, buf2, n1); | |
104 | + else | |
105 | + ret = 1; /* ouf of sync */ | |
106 | + } | |
107 | + else | |
108 | + ret = 1; /* read failure */ | |
109 | + } | |
110 | + } | |
111 | + | |
112 | + close(file_fd); | |
113 | + close(to_fd); | |
114 | + return ret; | |
115 | +} | |
116 | + | |
117 | static void | |
118 | cp_option_init (struct cp_options *x) | |
119 | { | |
120 | @@ -206,7 +286,7 @@ | |
121 | we'll actually use backup_suffix_string. */ | |
122 | backup_suffix_string = getenv ("SIMPLE_BACKUP_SUFFIX"); | |
123 | ||
124 | - while ((optc = getopt_long (argc, argv, "bcsDdg:m:o:pvV:S:", long_options, | |
125 | + while ((optc = getopt_long (argc, argv, "bcCsDdg:m:o:pvV:S:", long_options, | |
126 | NULL)) != -1) | |
127 | { | |
128 | switch (optc) | |
129 | @@ -228,6 +308,9 @@ | |
130 | break; | |
131 | case 'c': | |
132 | break; | |
133 | + case 'C': | |
134 | + docompare=1; | |
135 | + break; | |
136 | case 's': | |
137 | strip_files = 1; | |
138 | break; | |
139 | @@ -436,6 +519,12 @@ | |
140 | return 1; | |
141 | } | |
142 | ||
143 | + if (docompare) | |
144 | + { | |
145 | + if(compare(from, to)==0) /* Files are identical */ | |
146 | + return 0; | |
147 | + } | |
148 | + | |
149 | fail = copy (from, to, nonexistent_dst, x, ©_into_self, NULL); | |
150 | ||
151 | return fail; | |
152 | @@ -613,6 +702,9 @@ | |
153 | --backup[=CONTROL] make a backup of each existing destination file\n\ | |
154 | -b like --backup but does not accept an argument\n\ | |
155 | -c (ignored)\n\ | |
156 | + -C Install file, unless the target already exists and is the same,\n\ | |
157 | + in which case the modification time won't be changed.\n\ | |
158 | + For compatibility with *BSD.\n\ | |
159 | -d, --directory treat all arguments as directory names; create all\n\ | |
160 | components of the specified directories\n\ | |
161 | "), stdout); |