4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
27 /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
28 /* All Rights Reserved */
31 * University Copyright- Copyright (c) 1982, 1986, 1988
32 * The Regents of the University of California
35 * University Acknowledgment- Portions of this document are derived from
36 * software developed by the University of California, Berkeley, and its
40 #include "libcmdutils.h"
44 writefile(int fi
, int fo
, char *infile
, char *outfile
, char *asfile
,
45 char *atfile
, struct stat
*s1p
, struct stat
*s2p
)
47 int mapsize
, munmapsize
;
49 off_t filesize
= s1p
->st_size
;
60 src_size
= strlen(infile
) + strlen(asfile
) +
61 strlen(dgettext(TEXT_DOMAIN
, " attribute ")) + 1;
63 src_size
= strlen(infile
) + 1;
65 srcbuf
= malloc(src_size
);
67 (void) fprintf(stderr
,
68 dgettext(TEXT_DOMAIN
, "could not allocate memory"
69 " for path buffer: "));
73 (void) snprintf(srcbuf
, src_size
, "%s%s%s",
74 infile
, dgettext(TEXT_DOMAIN
, " attribute "), asfile
);
76 (void) snprintf(srcbuf
, src_size
, "%s", infile
);
80 targ_size
= strlen(outfile
) + strlen(atfile
) +
81 strlen(dgettext(TEXT_DOMAIN
, " attribute ")) + 1;
83 targ_size
= strlen(outfile
) + 1;
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: "));
93 (void) snprintf(targbuf
, targ_size
, "%s%s%s",
94 outfile
, dgettext(TEXT_DOMAIN
, " attribute "), atfile
);
96 (void) snprintf(targbuf
, targ_size
, "%s", outfile
);
99 if (S_ISREG(s1p
->st_mode
) && s1p
->st_size
> SMALLFILESIZE
) {
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.
105 mapsize
= MAXMAPSIZE
;
106 if (s1p
->st_size
< mapsize
) mapsize
= s1p
->st_size
;
107 munmapsize
= mapsize
;
112 if ((cp
= mmap(NULL
, mapsize
, PROT_READ
,
113 MAP_SHARED
, fi
, (off_t
)0)) == MAP_FAILED
)
114 mapsize
= 0; /* can't mmap today */
122 nbytes
= write(fo
, cp
, mapsize
);
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.
128 if ((nbytes
>= 0) && (nbytes
!= (int)mapsize
)) {
129 remains
= mapsize
- nbytes
;
130 while (remains
> 0) {
132 cp
+ mapsize
- remains
, remains
);
140 (void) munmap(cp
, munmapsize
);
141 if (S_ISREG(s2p
->st_mode
))
142 (void) unlink(targbuf
);
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
164 (void) munmap(cp
, munmapsize
);
165 if (S_ISREG(s2p
->st_mode
))
166 (void) unlink(targbuf
);
175 if (filesize
< mapsize
)
177 if (mmap(cp
, mapsize
, PROT_READ
, MAP_SHARED
|
178 MAP_FIXED
, fi
, offset
) == MAP_FAILED
) {
182 (void) munmap(cp
, munmapsize
);
183 if (S_ISREG(s2p
->st_mode
))
184 (void) unlink(targbuf
);
190 (void) munmap(cp
, munmapsize
);
192 char buf
[SMALLFILESIZE
];
194 n
= read(fi
, buf
, sizeof (buf
));
200 if (S_ISREG(s2p
->st_mode
))
201 (void) unlink(targbuf
);
205 } else if (write(fo
, buf
, n
) != n
) {
208 if (S_ISREG(s2p
->st_mode
))
209 (void) unlink(targbuf
);