diff options
author | Namhyung Kim <namhyung@kernel.org> | 2015-05-17 20:30:18 -0400 |
---|---|---|
committer | Arnaldo Carvalho de Melo <acme@redhat.com> | 2015-05-18 09:17:35 -0400 |
commit | 9c9f5a2f1944e8b6bf2b618d04b31e1c1760637e (patch) | |
tree | a532ec7e4efb95e780130bbe6bb7abb41f37f6da /tools/perf/util/util.c | |
parent | 0b1de0be1eac7b23e89cb43c17b02d38ead6b6c8 (diff) |
perf tools: Introduce copyfile_offset() function
The copyfile_offset() function is to copy source data from given offset
to a destination file with an offset. It'll be used to build an indexed
data file.
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Acked-by: Jiri Olsa <jolsa@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Andi Kleen <andi@firstfloor.org>
Cc: David Ahern <dsahern@gmail.com>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Stephane Eranian <eranian@google.com>
Link: http://lkml.kernel.org/r/20150304145824.GD7519@krava.brq.redhat.com
Link: http://lkml.kernel.org/r/1431909055-21442-4-git-send-email-namhyung@kernel.org
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'tools/perf/util/util.c')
-rw-r--r-- | tools/perf/util/util.c | 38 |
1 files changed, 29 insertions, 9 deletions
diff --git a/tools/perf/util/util.c b/tools/perf/util/util.c index 6104afb7e1ef..0c264bc685ac 100644 --- a/tools/perf/util/util.c +++ b/tools/perf/util/util.c | |||
@@ -145,11 +145,38 @@ out: | |||
145 | return err; | 145 | return err; |
146 | } | 146 | } |
147 | 147 | ||
148 | int copyfile_offset(int ifd, loff_t off_in, int ofd, loff_t off_out, u64 size) | ||
149 | { | ||
150 | void *ptr; | ||
151 | loff_t pgoff; | ||
152 | |||
153 | pgoff = off_in & ~(page_size - 1); | ||
154 | off_in -= pgoff; | ||
155 | |||
156 | ptr = mmap(NULL, off_in + size, PROT_READ, MAP_PRIVATE, ifd, pgoff); | ||
157 | if (ptr == MAP_FAILED) | ||
158 | return -1; | ||
159 | |||
160 | while (size) { | ||
161 | ssize_t ret = pwrite(ofd, ptr + off_in, size, off_out); | ||
162 | if (ret < 0 && errno == EINTR) | ||
163 | continue; | ||
164 | if (ret <= 0) | ||
165 | break; | ||
166 | |||
167 | size -= ret; | ||
168 | off_in += ret; | ||
169 | off_out -= ret; | ||
170 | } | ||
171 | munmap(ptr, off_in + size); | ||
172 | |||
173 | return size ? -1 : 0; | ||
174 | } | ||
175 | |||
148 | int copyfile_mode(const char *from, const char *to, mode_t mode) | 176 | int copyfile_mode(const char *from, const char *to, mode_t mode) |
149 | { | 177 | { |
150 | int fromfd, tofd; | 178 | int fromfd, tofd; |
151 | struct stat st; | 179 | struct stat st; |
152 | void *addr; | ||
153 | int err = -1; | 180 | int err = -1; |
154 | 181 | ||
155 | if (stat(from, &st)) | 182 | if (stat(from, &st)) |
@@ -166,15 +193,8 @@ int copyfile_mode(const char *from, const char *to, mode_t mode) | |||
166 | if (tofd < 0) | 193 | if (tofd < 0) |
167 | goto out_close_from; | 194 | goto out_close_from; |
168 | 195 | ||
169 | addr = mmap(NULL, st.st_size, PROT_READ, MAP_PRIVATE, fromfd, 0); | 196 | err = copyfile_offset(fromfd, 0, tofd, 0, st.st_size); |
170 | if (addr == MAP_FAILED) | ||
171 | goto out_close_to; | ||
172 | |||
173 | if (write(tofd, addr, st.st_size) == st.st_size) | ||
174 | err = 0; | ||
175 | 197 | ||
176 | munmap(addr, st.st_size); | ||
177 | out_close_to: | ||
178 | close(tofd); | 198 | close(tofd); |
179 | if (err) | 199 | if (err) |
180 | unlink(to); | 200 | unlink(to); |