20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 /*
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
33 * All Rights Reserved
34 *
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
37 * contributors.
38 */
39
40 #pragma ident "%Z%%M% %I% %E% SMI"
41
42 #include "libcmdutils.h"
43
44
45 int
46 writefile(int fi, int fo, char *infile, char *outfile, char *asfile,
47 char *atfile, struct stat *s1p, struct stat *s2p)
48 {
49 int mapsize, munmapsize;
50 caddr_t cp;
51 off_t filesize = s1p->st_size;
52 off_t offset;
53 int nbytes;
54 int remains;
55 int n;
56 size_t src_size;
57 size_t targ_size;
58 char *srcbuf;
59 char *targbuf;
60
61 if (asfile != NULL) {
81 if (atfile != NULL) {
82 targ_size = strlen(outfile) + strlen(atfile) +
83 strlen(dgettext(TEXT_DOMAIN, " attribute ")) + 1;
84 } else {
85 targ_size = strlen(outfile) + 1;
86 }
87 targbuf = malloc(targ_size);
88 if (targbuf == NULL) {
89 (void) fprintf(stderr,
90 dgettext(TEXT_DOMAIN, "could not allocate memory"
91 " for path buffer: "));
92 return (1);
93 }
94 if (atfile != NULL) {
95 (void) snprintf(targbuf, targ_size, "%s%s%s",
96 outfile, dgettext(TEXT_DOMAIN, " attribute "), atfile);
97 } else {
98 (void) snprintf(targbuf, targ_size, "%s", outfile);
99 }
100
101 if (ISREG(*s1p) && s1p->st_size > SMALLFILESIZE) {
102 /*
103 * Determine size of initial mapping. This will determine the
104 * size of the address space chunk we work with. This initial
105 * mapping size will be used to perform munmap() in the future.
106 */
107 mapsize = MAXMAPSIZE;
108 if (s1p->st_size < mapsize) mapsize = s1p->st_size;
109 munmapsize = mapsize;
110
111 /*
112 * Mmap time!
113 */
114 if ((cp = mmap((caddr_t)NULL, mapsize, PROT_READ,
115 MAP_SHARED, fi, (off_t)0)) == MAP_FAILED)
116 mapsize = 0; /* can't mmap today */
117 } else
118 mapsize = 0;
119
120 if (mapsize != 0) {
121 offset = 0;
123 for (;;) {
124 nbytes = write(fo, cp, mapsize);
125 /*
126 * if we write less than the mmaped size it's due to a
127 * media error on the input file or out of space on
128 * the output file. So, try again, and look for errno.
129 */
130 if ((nbytes >= 0) && (nbytes != (int)mapsize)) {
131 remains = mapsize - nbytes;
132 while (remains > 0) {
133 nbytes = write(fo,
134 cp + mapsize - remains, remains);
135 if (nbytes < 0) {
136 if (errno == ENOSPC)
137 perror(targbuf);
138 else
139 perror(srcbuf);
140 (void) close(fi);
141 (void) close(fo);
142 (void) munmap(cp, munmapsize);
143 if (ISREG(*s2p))
144 (void) unlink(targbuf);
145 return (1);
146 }
147 remains -= nbytes;
148 if (remains == 0)
149 nbytes = mapsize;
150 }
151 }
152 /*
153 * although the write manual page doesn't specify this
154 * as a possible errno, it is set when the nfs read
155 * via the mmap'ed file is accessed, so report the
156 * problem as a source access problem, not a target file
157 * problem
158 */
159 if (nbytes < 0) {
160 if (errno == EACCES)
161 perror(srcbuf);
162 else
163 perror(targbuf);
164 (void) close(fi);
165 (void) close(fo);
166 (void) munmap(cp, munmapsize);
167 if (ISREG(*s2p))
168 (void) unlink(targbuf);
169 if (srcbuf != NULL)
170 free(srcbuf);
171 if (targbuf != NULL)
172 free(targbuf);
173 return (1);
174 }
175 filesize -= nbytes;
176 if (filesize == 0)
177 break;
178 offset += nbytes;
179 if (filesize < mapsize)
180 mapsize = filesize;
181 if (mmap(cp, mapsize, PROT_READ, MAP_SHARED |
182 MAP_FIXED, fi, offset) == MAP_FAILED) {
183 perror(srcbuf);
184 (void) close(fi);
185 (void) close(fo);
186 (void) munmap(cp, munmapsize);
187 if (ISREG(*s2p))
188 (void) unlink(targbuf);
189 if (srcbuf != NULL)
190 free(srcbuf);
191 if (targbuf != NULL)
192 free(targbuf);
193 return (1);
194 }
195 }
196 (void) munmap(cp, munmapsize);
197 } else {
198 char buf[SMALLFILESIZE];
199 for (;;) {
200 n = read(fi, buf, sizeof (buf));
201 if (n == 0) {
202 return (0);
203 } else if (n < 0) {
204 (void) close(fi);
205 (void) close(fo);
206 if (ISREG(*s2p))
207 (void) unlink(targbuf);
208 if (srcbuf != NULL)
209 free(srcbuf);
210 if (targbuf != NULL)
211 free(targbuf);
212 return (1);
213 } else if (write(fo, buf, n) != n) {
214 (void) close(fi);
215 (void) close(fo);
216 if (ISREG(*s2p))
217 (void) unlink(targbuf);
218 if (srcbuf != NULL)
219 free(srcbuf);
220 if (targbuf != NULL)
221 free(targbuf);
222 return (1);
223 }
224 }
225 }
226 if (srcbuf != NULL)
227 free(srcbuf);
228 if (targbuf != NULL)
229 free(targbuf);
230 return (0);
231 }
|
20 */
21
22 /*
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
29
30 /*
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
33 * All Rights Reserved
34 *
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
37 * contributors.
38 */
39
40 #include "libcmdutils.h"
41
42
43 int
44 writefile(int fi, int fo, char *infile, char *outfile, char *asfile,
45 char *atfile, struct stat *s1p, struct stat *s2p)
46 {
47 int mapsize, munmapsize;
48 caddr_t cp;
49 off_t filesize = s1p->st_size;
50 off_t offset;
51 int nbytes;
52 int remains;
53 int n;
54 size_t src_size;
55 size_t targ_size;
56 char *srcbuf;
57 char *targbuf;
58
59 if (asfile != NULL) {
79 if (atfile != NULL) {
80 targ_size = strlen(outfile) + strlen(atfile) +
81 strlen(dgettext(TEXT_DOMAIN, " attribute ")) + 1;
82 } else {
83 targ_size = strlen(outfile) + 1;
84 }
85 targbuf = malloc(targ_size);
86 if (targbuf == NULL) {
87 (void) fprintf(stderr,
88 dgettext(TEXT_DOMAIN, "could not allocate memory"
89 " for path buffer: "));
90 return (1);
91 }
92 if (atfile != NULL) {
93 (void) snprintf(targbuf, targ_size, "%s%s%s",
94 outfile, dgettext(TEXT_DOMAIN, " attribute "), atfile);
95 } else {
96 (void) snprintf(targbuf, targ_size, "%s", outfile);
97 }
98
99 if (S_ISREG(s1p->st_mode) && s1p->st_size > SMALLFILESIZE) {
100 /*
101 * Determine size of initial mapping. This will determine the
102 * size of the address space chunk we work with. This initial
103 * mapping size will be used to perform munmap() in the future.
104 */
105 mapsize = MAXMAPSIZE;
106 if (s1p->st_size < mapsize) mapsize = s1p->st_size;
107 munmapsize = mapsize;
108
109 /*
110 * Mmap time!
111 */
112 if ((cp = mmap((caddr_t)NULL, mapsize, PROT_READ,
113 MAP_SHARED, fi, (off_t)0)) == MAP_FAILED)
114 mapsize = 0; /* can't mmap today */
115 } else
116 mapsize = 0;
117
118 if (mapsize != 0) {
119 offset = 0;
121 for (;;) {
122 nbytes = write(fo, cp, mapsize);
123 /*
124 * if we write less than the mmaped size it's due to a
125 * media error on the input file or out of space on
126 * the output file. So, try again, and look for errno.
127 */
128 if ((nbytes >= 0) && (nbytes != (int)mapsize)) {
129 remains = mapsize - nbytes;
130 while (remains > 0) {
131 nbytes = write(fo,
132 cp + mapsize - remains, remains);
133 if (nbytes < 0) {
134 if (errno == ENOSPC)
135 perror(targbuf);
136 else
137 perror(srcbuf);
138 (void) close(fi);
139 (void) close(fo);
140 (void) munmap(cp, munmapsize);
141 if (S_ISREG(s2p->st_mode))
142 (void) unlink(targbuf);
143 return (1);
144 }
145 remains -= nbytes;
146 if (remains == 0)
147 nbytes = mapsize;
148 }
149 }
150 /*
151 * although the write manual page doesn't specify this
152 * as a possible errno, it is set when the nfs read
153 * via the mmap'ed file is accessed, so report the
154 * problem as a source access problem, not a target file
155 * problem
156 */
157 if (nbytes < 0) {
158 if (errno == EACCES)
159 perror(srcbuf);
160 else
161 perror(targbuf);
162 (void) close(fi);
163 (void) close(fo);
164 (void) munmap(cp, munmapsize);
165 if (S_ISREG(s2p->st_mode))
166 (void) unlink(targbuf);
167 if (srcbuf != NULL)
168 free(srcbuf);
169 if (targbuf != NULL)
170 free(targbuf);
171 return (1);
172 }
173 filesize -= nbytes;
174 if (filesize == 0)
175 break;
176 offset += nbytes;
177 if (filesize < mapsize)
178 mapsize = filesize;
179 if (mmap(cp, mapsize, PROT_READ, MAP_SHARED |
180 MAP_FIXED, fi, offset) == MAP_FAILED) {
181 perror(srcbuf);
182 (void) close(fi);
183 (void) close(fo);
184 (void) munmap(cp, munmapsize);
185 if (S_ISREG(s2p->st_mode))
186 (void) unlink(targbuf);
187 if (srcbuf != NULL)
188 free(srcbuf);
189 if (targbuf != NULL)
190 free(targbuf);
191 return (1);
192 }
193 }
194 (void) munmap(cp, munmapsize);
195 } else {
196 char buf[SMALLFILESIZE];
197 for (;;) {
198 n = read(fi, buf, sizeof (buf));
199 if (n == 0) {
200 return (0);
201 } else if (n < 0) {
202 (void) close(fi);
203 (void) close(fo);
204 if (S_ISREG(s2p->st_mode))
205 (void) unlink(targbuf);
206 if (srcbuf != NULL)
207 free(srcbuf);
208 if (targbuf != NULL)
209 free(targbuf);
210 return (1);
211 } else if (write(fo, buf, n) != n) {
212 (void) close(fi);
213 (void) close(fo);
214 if (S_ISREG(s2p->st_mode))
215 (void) unlink(targbuf);
216 if (srcbuf != NULL)
217 free(srcbuf);
218 if (targbuf != NULL)
219 free(targbuf);
220 return (1);
221 }
222 }
223 }
224 if (srcbuf != NULL)
225 free(srcbuf);
226 if (targbuf != NULL)
227 free(targbuf);
228 return (0);
229 }
|