ViewVC Help
View File | Revision Log | Show Annotations | Download File | View Changeset | Root Listing
root/src/vendor/FreeBSD/10.0/bin/dd/position.c
Revision: 2
Committed: Sat Feb 25 02:29:52 2006 UTC (18 years, 2 months ago) by laffer1
Content type: text/plain
Original Path: branches/MidnightBSD/bin/dd/position.c
File size: 5127 byte(s)
Log Message:
Imported from FreeBSD 6.0 sources

File Contents

# User Rev Content
1 laffer1 2 /*-
2     * Copyright (c) 1991, 1993, 1994
3     * The Regents of the University of California. All rights reserved.
4     *
5     * This code is derived from software contributed to Berkeley by
6     * Keith Muller of the University of California, San Diego and Lance
7     * Visser of Convex Computer Corporation.
8     *
9     * Redistribution and use in source and binary forms, with or without
10     * modification, are permitted provided that the following conditions
11     * are met:
12     * 1. Redistributions of source code must retain the above copyright
13     * notice, this list of conditions and the following disclaimer.
14     * 2. Redistributions in binary form must reproduce the above copyright
15     * notice, this list of conditions and the following disclaimer in the
16     * documentation and/or other materials provided with the distribution.
17     * 4. Neither the name of the University nor the names of its contributors
18     * may be used to endorse or promote products derived from this software
19     * without specific prior written permission.
20     *
21     * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22     * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24     * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25     * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26     * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27     * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28     * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29     * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30     * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31     * SUCH DAMAGE.
32     */
33    
34     #ifndef lint
35     #if 0
36     static char sccsid[] = "@(#)position.c 8.3 (Berkeley) 4/2/94";
37     #endif
38     #endif /* not lint */
39     #include <sys/cdefs.h>
40     __FBSDID("$FreeBSD: src/bin/dd/position.c,v 1.23 2004/04/06 20:06:46 markm Exp $");
41    
42     #include <sys/types.h>
43     #include <sys/mtio.h>
44    
45     #include <err.h>
46     #include <errno.h>
47     #include <inttypes.h>
48     #include <unistd.h>
49    
50     #include "dd.h"
51     #include "extern.h"
52    
53     /*
54     * Position input/output data streams before starting the copy. Device type
55     * dependent. Seekable devices use lseek, and the rest position by reading.
56     * Seeking past the end of file can cause null blocks to be written to the
57     * output.
58     */
59     void
60     pos_in(void)
61     {
62     off_t cnt;
63     int warned;
64     ssize_t nr;
65     size_t bcnt;
66    
67     /* If known to be seekable, try to seek on it. */
68     if (in.flags & ISSEEK) {
69     errno = 0;
70     if (lseek(in.fd, in.offset * in.dbsz, SEEK_CUR) == -1 &&
71     errno != 0)
72     err(1, "%s", in.name);
73     return;
74     }
75    
76     /* Don't try to read a really weird amount (like negative). */
77     if (in.offset < 0)
78     errx(1, "%s: illegal offset", "iseek/skip");
79    
80     /*
81     * Read the data. If a pipe, read until satisfy the number of bytes
82     * being skipped. No differentiation for reading complete and partial
83     * blocks for other devices.
84     */
85     for (bcnt = in.dbsz, cnt = in.offset, warned = 0; cnt;) {
86     if ((nr = read(in.fd, in.db, bcnt)) > 0) {
87     if (in.flags & ISPIPE) {
88     if (!(bcnt -= nr)) {
89     bcnt = in.dbsz;
90     --cnt;
91     }
92     } else
93     --cnt;
94     continue;
95     }
96    
97     if (nr == 0) {
98     if (files_cnt > 1) {
99     --files_cnt;
100     continue;
101     }
102     errx(1, "skip reached end of input");
103     }
104    
105     /*
106     * Input error -- either EOF with no more files, or I/O error.
107     * If noerror not set die. POSIX requires that the warning
108     * message be followed by an I/O display.
109     */
110     if (ddflags & C_NOERROR) {
111     if (!warned) {
112     warn("%s", in.name);
113     warned = 1;
114     summary();
115     }
116     continue;
117     }
118     err(1, "%s", in.name);
119     }
120     }
121    
122     void
123     pos_out(void)
124     {
125     struct mtop t_op;
126     off_t cnt;
127     ssize_t n;
128    
129     /*
130     * If not a tape, try seeking on the file. Seeking on a pipe is
131     * going to fail, but don't protect the user -- they shouldn't
132     * have specified the seek operand.
133     */
134     if (out.flags & (ISSEEK | ISPIPE)) {
135     errno = 0;
136     if (lseek(out.fd, out.offset * out.dbsz, SEEK_CUR) == -1 &&
137     errno != 0)
138     err(1, "%s", out.name);
139     return;
140     }
141    
142     /* Don't try to read a really weird amount (like negative). */
143     if (out.offset < 0)
144     errx(1, "%s: illegal offset", "oseek/seek");
145    
146     /* If no read access, try using mtio. */
147     if (out.flags & NOREAD) {
148     t_op.mt_op = MTFSR;
149     t_op.mt_count = out.offset;
150    
151     if (ioctl(out.fd, MTIOCTOP, &t_op) == -1)
152     err(1, "%s", out.name);
153     return;
154     }
155    
156     /* Read it. */
157     for (cnt = 0; cnt < out.offset; ++cnt) {
158     if ((n = read(out.fd, out.db, out.dbsz)) > 0)
159     continue;
160    
161     if (n == -1)
162     err(1, "%s", out.name);
163    
164     /*
165     * If reach EOF, fill with NUL characters; first, back up over
166     * the EOF mark. Note, cnt has not yet been incremented, so
167     * the EOF read does not count as a seek'd block.
168     */
169     t_op.mt_op = MTBSR;
170     t_op.mt_count = 1;
171     if (ioctl(out.fd, MTIOCTOP, &t_op) == -1)
172     err(1, "%s", out.name);
173    
174     while (cnt++ < out.offset) {
175     n = write(out.fd, out.db, out.dbsz);
176     if (n == -1)
177     err(1, "%s", out.name);
178     if ((size_t)n != out.dbsz)
179     errx(1, "%s: write failure", out.name);
180     }
181     break;
182     }
183     }

Properties

Name Value
cvs2svn:cvs-rev 1.1.1.1