]> git.proxmox.com Git - cargo.git/blob - vendor/tempfile/src/file/mod.rs
New upstream version 0.31.0
[cargo.git] / vendor / tempfile / src / file / mod.rs
1 use std;
2 use std::env;
3 use std::error;
4 use std::ffi::OsStr;
5 use std::fmt;
6 use std::fs::{self, File};
7 use std::io::{self, Read, Seek, SeekFrom, Write};
8 use std::mem;
9 use std::ops::Deref;
10 use std::path::{Path, PathBuf};
11
12 use Builder;
13
14 mod imp;
15
16 /// Create a new temporary file.
17 ///
18 /// The file will be created in the location returned by [`std::env::temp_dir()`].
19 ///
20 /// # Security
21 ///
22 /// This variant is secure/reliable in the presence of a pathological temporary file cleaner.
23 ///
24 /// # Resource Leaking
25 ///
26 /// The temporary file will be automatically removed by the OS when the last handle to it is closed.
27 /// This doesn't rely on Rust destructors being run, so will (almost) never fail to clean up the temporary file.
28 ///
29 /// # Errors
30 ///
31 /// If the file can not be created, `Err` is returned.
32 ///
33 /// # Examples
34 ///
35 /// ```
36 /// # extern crate tempfile;
37 /// use tempfile::tempfile;
38 /// use std::io::{self, Write};
39 ///
40 /// # fn main() {
41 /// # if let Err(_) = run() {
42 /// # ::std::process::exit(1);
43 /// # }
44 /// # }
45 /// # fn run() -> Result<(), io::Error> {
46 /// // Create a file inside of `std::env::temp_dir()`.
47 /// let mut file = tempfile()?;
48 ///
49 /// writeln!(file, "Brian was here. Briefly.")?;
50 /// # Ok(())
51 /// # }
52 /// ```
53 ///
54 /// [`std::env::temp_dir()`]: https://doc.rust-lang.org/std/env/fn.temp_dir.html
55 pub fn tempfile() -> io::Result<File> {
56 tempfile_in(&env::temp_dir())
57 }
58
59 /// Create a new temporary file in the specified directory.
60 ///
61 /// # Security
62 ///
63 /// This variant is secure/reliable in the presence of a pathological temporary file cleaner.
64 /// If the temporary file isn't created in [`std::env::temp_dir()`] then temporary file cleaners aren't an issue.
65 ///
66 /// # Resource Leaking
67 ///
68 /// The temporary file will be automatically removed by the OS when the last handle to it is closed.
69 /// This doesn't rely on Rust destructors being run, so will (almost) never fail to clean up the temporary file.
70 ///
71 /// # Errors
72 ///
73 /// If the file can not be created, `Err` is returned.
74 ///
75 /// # Examples
76 ///
77 /// ```
78 /// # extern crate tempfile;
79 /// use tempfile::tempfile_in;
80 /// use std::io::{self, Write};
81 ///
82 /// # fn main() {
83 /// # if let Err(_) = run() {
84 /// # ::std::process::exit(1);
85 /// # }
86 /// # }
87 /// # fn run() -> Result<(), io::Error> {
88 /// // Create a file inside of the current working directory
89 /// let mut file = tempfile_in("./")?;
90 ///
91 /// writeln!(file, "Brian was here. Briefly.")?;
92 /// # Ok(())
93 /// # }
94 /// ```
95 ///
96 /// [`std::env::temp_dir()`]: https://doc.rust-lang.org/std/env/fn.temp_dir.html
97 pub fn tempfile_in<P: AsRef<Path>>(dir: P) -> io::Result<File> {
98 imp::create(dir.as_ref())
99 }
100
101 /// Error returned when persisting a temporary file path fails.
102 #[derive(Debug)]
103 pub struct PathPersistError {
104 /// The underlying IO error.
105 pub error: io::Error,
106 /// The temporary file path that couldn't be persisted.
107 pub path: TempPath,
108 }
109
110 impl From<PathPersistError> for io::Error {
111 #[inline]
112 fn from(error: PathPersistError) -> io::Error {
113 error.error
114 }
115 }
116
117 impl From<PathPersistError> for TempPath {
118 #[inline]
119 fn from(error: PathPersistError) -> TempPath {
120 error.path
121 }
122 }
123
124 impl fmt::Display for PathPersistError {
125 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
126 write!(f, "failed to persist temporary file path: {}", self.error)
127 }
128 }
129
130 impl error::Error for PathPersistError {
131 fn description(&self) -> &str {
132 "failed to persist temporary file path"
133 }
134
135 fn cause(&self) -> Option<&error::Error> {
136 Some(&self.error)
137 }
138 }
139
140 /// A path to a named temporary file without an open file handle.
141 ///
142 /// This is useful when the temporary file needs to be used by a child process,
143 /// for example.
144 ///
145 /// When dropped, the temporary file is deleted.
146 pub struct TempPath {
147 path: PathBuf,
148 }
149
150 impl TempPath {
151 /// Close and remove the temporary file.
152 ///
153 /// Use this if you want to detect errors in deleting the file.
154 ///
155 /// # Errors
156 ///
157 /// If the file cannot be deleted, `Err` is returned.
158 ///
159 /// # Examples
160 ///
161 /// ```no_run
162 /// # extern crate tempfile;
163 /// # use std::io;
164 /// use tempfile::NamedTempFile;
165 ///
166 /// # fn main() {
167 /// # if let Err(_) = run() {
168 /// # ::std::process::exit(1);
169 /// # }
170 /// # }
171 /// # fn run() -> Result<(), io::Error> {
172 /// let file = NamedTempFile::new()?;
173 ///
174 /// // Close the file, but keep the path to it around.
175 /// let path = file.into_temp_path();
176 ///
177 /// // By closing the `TempPath` explicitly, we can check that it has
178 /// // been deleted successfully. If we don't close it explicitly, the
179 /// // file will still be deleted when `file` goes out of scope, but we
180 /// // won't know whether deleting the file succeeded.
181 /// path.close()?;
182 /// # Ok(())
183 /// # }
184 /// ```
185 pub fn close(mut self) -> io::Result<()> {
186 let result = fs::remove_file(&self.path);
187 mem::replace(&mut self.path, PathBuf::new());
188 mem::forget(self);
189 result
190 }
191
192 /// Persist the temporary file at the target path.
193 ///
194 /// If a file exists at the target path, persist will atomically replace it.
195 /// If this method fails, it will return `self` in the resulting
196 /// [`PathPersistError`].
197 ///
198 /// Note: Temporary files cannot be persisted across filesystems.
199 ///
200 /// # Security
201 ///
202 /// Only use this method if you're positive that a temporary file cleaner
203 /// won't have deleted your file. Otherwise, you might end up persisting an
204 /// attacker controlled file.
205 ///
206 /// # Errors
207 ///
208 /// If the file cannot be moved to the new location, `Err` is returned.
209 ///
210 /// # Examples
211 ///
212 /// ```no_run
213 /// # use std::io::{self, Write};
214 /// # extern crate tempfile;
215 /// use tempfile::NamedTempFile;
216 ///
217 /// # fn main() {
218 /// # if let Err(_) = run() {
219 /// # ::std::process::exit(1);
220 /// # }
221 /// # }
222 /// # fn run() -> Result<(), io::Error> {
223 /// let mut file = NamedTempFile::new()?;
224 /// writeln!(file, "Brian was here. Briefly.")?;
225 ///
226 /// let path = file.into_temp_path();
227 /// path.persist("./saved_file.txt")?;
228 /// # Ok(())
229 /// # }
230 /// ```
231 ///
232 /// [`PathPersistError`]: struct.PathPersistError.html
233 pub fn persist<P: AsRef<Path>>(mut self, new_path: P) -> Result<(), PathPersistError> {
234 match imp::persist(&self.path, new_path.as_ref(), true) {
235 Ok(_) => {
236 // Don't drop `self`. We don't want to try deleting the old
237 // temporary file path. (It'll fail, but the failure is never
238 // seen.)
239 mem::replace(&mut self.path, PathBuf::new());
240 mem::forget(self);
241 Ok(())
242 }
243 Err(e) => Err(PathPersistError {
244 error: e,
245 path: self,
246 }),
247 }
248 }
249
250 /// Persist the temporary file at the target path iff no file exists there.
251 ///
252 /// If a file exists at the target path, fail. If this method fails, it will
253 /// return `self` in the resulting [`PathPersistError`].
254 ///
255 /// Note: Temporary files cannot be persisted across filesystems. Also Note:
256 /// This method is not atomic. It can leave the original link to the
257 /// temporary file behind.
258 ///
259 /// # Security
260 ///
261 /// Only use this method if you're positive that a temporary file cleaner
262 /// won't have deleted your file. Otherwise, you might end up persisting an
263 /// attacker controlled file.
264 ///
265 /// # Errors
266 ///
267 /// If the file cannot be moved to the new location or a file already exists
268 /// there, `Err` is returned.
269 ///
270 /// # Examples
271 ///
272 /// ```no_run
273 /// # use std::io::{self, Write};
274 /// # extern crate tempfile;
275 /// use tempfile::NamedTempFile;
276 ///
277 /// # fn main() {
278 /// # if let Err(_) = run() {
279 /// # ::std::process::exit(1);
280 /// # }
281 /// # }
282 /// # fn run() -> Result<(), io::Error> {
283 /// let mut file = NamedTempFile::new()?;
284 /// writeln!(file, "Brian was here. Briefly.")?;
285 ///
286 /// let path = file.into_temp_path();
287 /// path.persist_noclobber("./saved_file.txt")?;
288 /// # Ok(())
289 /// # }
290 /// ```
291 ///
292 /// [`PathPersistError`]: struct.PathPersistError.html
293 pub fn persist_noclobber<P: AsRef<Path>>(
294 mut self,
295 new_path: P,
296 ) -> Result<(), PathPersistError> {
297 match imp::persist(&self.path, new_path.as_ref(), false) {
298 Ok(_) => {
299 // Don't drop `self`. We don't want to try deleting the old
300 // temporary file path. (It'll fail, but the failure is never
301 // seen.)
302 mem::replace(&mut self.path, PathBuf::new());
303 mem::forget(self);
304 Ok(())
305 }
306 Err(e) => Err(PathPersistError {
307 error: e,
308 path: self,
309 }),
310 }
311 }
312 }
313
314 impl fmt::Debug for TempPath {
315 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
316 self.path.fmt(f)
317 }
318 }
319
320 impl Drop for TempPath {
321 fn drop(&mut self) {
322 let _ = fs::remove_file(&self.path);
323 }
324 }
325
326 impl Deref for TempPath {
327 type Target = Path;
328
329 fn deref(&self) -> &Path {
330 &self.path
331 }
332 }
333
334 impl AsRef<Path> for TempPath {
335 fn as_ref(&self) -> &Path {
336 &self.path
337 }
338 }
339
340 impl AsRef<OsStr> for TempPath {
341 fn as_ref(&self) -> &OsStr {
342 self.path.as_os_str()
343 }
344 }
345
346 /// A named temporary file.
347 ///
348 /// The default constructor, [`NamedTempFile::new()`], creates files in
349 /// the location returned by [`std::env::temp_dir()`], but `NamedTempFile`
350 /// can be configured to manage a temporary file in any location
351 /// by constructing with [`NamedTempFile::new_in()`].
352 ///
353 /// # Security
354 ///
355 /// This variant is *NOT* secure/reliable in the presence of a pathological temporary file cleaner.
356 ///
357 /// # Resource Leaking
358 ///
359 /// If the program exits before the `NamedTempFile` destructor is
360 /// run, such as via [`std::process::exit()`], by segfaulting, or by
361 /// receiving a signal like `SIGINT`, then the temporary file
362 /// will not be deleted.
363 ///
364 /// Use the [`tempfile()`] function unless you absolutely need a named file.
365 ///
366 /// [`tempfile()`]: fn.tempfile.html
367 /// [`NamedTempFile::new()`]: #method.new
368 /// [`NamedTempFile::new_in()`]: #method.new_in
369 /// [`std::env::temp_dir()`]: https://doc.rust-lang.org/std/env/fn.temp_dir.html
370 /// [`std::process::exit()`]: http://doc.rust-lang.org/std/process/fn.exit.html
371 pub struct NamedTempFile {
372 path: TempPath,
373 file: File,
374 }
375
376 impl fmt::Debug for NamedTempFile {
377 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
378 write!(f, "NamedTempFile({:?})", self.path)
379 }
380 }
381
382 impl AsRef<Path> for NamedTempFile {
383 #[inline]
384 fn as_ref(&self) -> &Path {
385 self.path()
386 }
387 }
388
389 /// Error returned when persisting a temporary file fails.
390 #[derive(Debug)]
391 pub struct PersistError {
392 /// The underlying IO error.
393 pub error: io::Error,
394 /// The temporary file that couldn't be persisted.
395 pub file: NamedTempFile,
396 }
397
398 impl From<PersistError> for io::Error {
399 #[inline]
400 fn from(error: PersistError) -> io::Error {
401 error.error
402 }
403 }
404
405 impl From<PersistError> for NamedTempFile {
406 #[inline]
407 fn from(error: PersistError) -> NamedTempFile {
408 error.file
409 }
410 }
411
412 impl fmt::Display for PersistError {
413 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
414 write!(f, "failed to persist temporary file: {}", self.error)
415 }
416 }
417
418 impl error::Error for PersistError {
419 fn description(&self) -> &str {
420 "failed to persist temporary file"
421 }
422 fn cause(&self) -> Option<&error::Error> {
423 Some(&self.error)
424 }
425 }
426
427 impl NamedTempFile {
428 /// Create a new named temporary file.
429 ///
430 /// See [`Builder`] for more configuration.
431 ///
432 /// # Security
433 ///
434 /// This will create a temporary file in the default temporary file
435 /// directory (platform dependent). These directories are often patrolled by temporary file
436 /// cleaners so only use this method if you're *positive* that the temporary file cleaner won't
437 /// delete your file.
438 ///
439 /// Reasons to use this method:
440 ///
441 /// 1. The file has a short lifetime and your temporary file cleaner is
442 /// sane (doesn't delete recently accessed files).
443 ///
444 /// 2. You trust every user on your system (i.e. you are the only user).
445 ///
446 /// 3. You have disabled your system's temporary file cleaner or verified
447 /// that your system doesn't have a temporary file cleaner.
448 ///
449 /// Reasons not to use this method:
450 ///
451 /// 1. You'll fix it later. No you won't.
452 ///
453 /// 2. You don't care about the security of the temporary file. If none of
454 /// the "reasons to use this method" apply, referring to a temporary
455 /// file by name may allow an attacker to create/overwrite your
456 /// non-temporary files. There are exceptions but if you don't already
457 /// know them, don't use this method.
458 ///
459 /// # Errors
460 ///
461 /// If the file can not be created, `Err` is returned.
462 ///
463 /// # Examples
464 ///
465 /// Create a named temporary file and write some data to it:
466 ///
467 /// ```no_run
468 /// # use std::io::{self, Write};
469 /// # extern crate tempfile;
470 /// use tempfile::NamedTempFile;
471 ///
472 /// # fn main() {
473 /// # if let Err(_) = run() {
474 /// # ::std::process::exit(1);
475 /// # }
476 /// # }
477 /// # fn run() -> Result<(), ::std::io::Error> {
478 /// let mut file = NamedTempFile::new()?;
479 ///
480 /// writeln!(file, "Brian was here. Briefly.")?;
481 /// # Ok(())
482 /// # }
483 /// ```
484 ///
485 /// [`Builder`]: struct.Builder.html
486 pub fn new() -> io::Result<NamedTempFile> {
487 Builder::new().tempfile()
488 }
489
490 /// Create a new named temporary file in the specified directory.
491 ///
492 /// See [`NamedTempFile::new()`] for details.
493 ///
494 /// [`NamedTempFile::new()`]: #method.new_in
495 pub fn new_in<P: AsRef<Path>>(dir: P) -> io::Result<NamedTempFile> {
496 Builder::new().tempfile_in(dir)
497 }
498
499 /// Get the temporary file's path.
500 ///
501 /// # Security
502 ///
503 /// Only use this method if you're positive that a
504 /// temporary file cleaner won't have deleted your file. Otherwise, the path
505 /// returned by this method may refer to an attacker controlled file.
506 ///
507 /// # Examples
508 ///
509 /// ```no_run
510 /// # use std::io::{self, Write};
511 /// # extern crate tempfile;
512 /// use tempfile::NamedTempFile;
513 ///
514 /// # fn main() {
515 /// # if let Err(_) = run() {
516 /// # ::std::process::exit(1);
517 /// # }
518 /// # }
519 /// # fn run() -> Result<(), ::std::io::Error> {
520 /// let file = NamedTempFile::new()?;
521 ///
522 /// println!("{:?}", file.path());
523 /// # Ok(())
524 /// # }
525 /// ```
526 #[inline]
527 pub fn path(&self) -> &Path {
528 &self.path
529 }
530
531 /// Close and remove the temporary file.
532 ///
533 /// Use this if you want to detect errors in deleting the file.
534 ///
535 /// # Errors
536 ///
537 /// If the file cannot be deleted, `Err` is returned.
538 ///
539 /// # Examples
540 ///
541 /// ```no_run
542 /// # extern crate tempfile;
543 /// # use std::io;
544 /// use tempfile::NamedTempFile;
545 ///
546 /// # fn main() {
547 /// # if let Err(_) = run() {
548 /// # ::std::process::exit(1);
549 /// # }
550 /// # }
551 /// # fn run() -> Result<(), io::Error> {
552 /// let file = NamedTempFile::new()?;
553 ///
554 /// // By closing the `NamedTempFile` explicitly, we can check that it has
555 /// // been deleted successfully. If we don't close it explicitly,
556 /// // the file will still be deleted when `file` goes out
557 /// // of scope, but we won't know whether deleting the file
558 /// // succeeded.
559 /// file.close()?;
560 /// # Ok(())
561 /// # }
562 /// ```
563 pub fn close(self) -> io::Result<()> {
564 let NamedTempFile { path, .. } = self;
565 path.close()
566 }
567
568 /// Persist the temporary file at the target path.
569 ///
570 /// If a file exists at the target path, persist will atomically replace it.
571 /// If this method fails, it will return `self` in the resulting
572 /// [`PersistError`].
573 ///
574 /// Note: Temporary files cannot be persisted across filesystems.
575 ///
576 /// # Security
577 ///
578 /// Only use this method if you're positive that a
579 /// temporary file cleaner won't have deleted your file. Otherwise, you
580 /// might end up persisting an attacker controlled file.
581 ///
582 /// # Errors
583 ///
584 /// If the file cannot be moved to the new location, `Err` is returned.
585 ///
586 /// # Examples
587 ///
588 /// ```no_run
589 /// # use std::io::{self, Write};
590 /// # extern crate tempfile;
591 /// use tempfile::NamedTempFile;
592 ///
593 /// # fn main() {
594 /// # if let Err(_) = run() {
595 /// # ::std::process::exit(1);
596 /// # }
597 /// # }
598 /// # fn run() -> Result<(), io::Error> {
599 /// let file = NamedTempFile::new()?;
600 ///
601 /// let mut persisted_file = file.persist("./saved_file.txt")?;
602 /// writeln!(persisted_file, "Brian was here. Briefly.")?;
603 /// # Ok(())
604 /// # }
605 /// ```
606 ///
607 /// [`PersistError`]: struct.PersistError.html
608 pub fn persist<P: AsRef<Path>>(self, new_path: P) -> Result<File, PersistError> {
609 let NamedTempFile { path, file } = self;
610 match path.persist(new_path) {
611 Ok(_) => Ok(file),
612 Err(err) => {
613 let PathPersistError { error, path } = err;
614 Err(PersistError {
615 file: NamedTempFile { path, file },
616 error,
617 })
618 }
619 }
620 }
621
622 /// Persist the temporary file at the target path iff no file exists there.
623 ///
624 /// If a file exists at the target path, fail. If this method fails, it will
625 /// return `self` in the resulting PersistError.
626 ///
627 /// Note: Temporary files cannot be persisted across filesystems. Also Note:
628 /// This method is not atomic. It can leave the original link to the
629 /// temporary file behind.
630 ///
631 /// # Security
632 ///
633 /// Only use this method if you're positive that a
634 /// temporary file cleaner won't have deleted your file. Otherwise, you
635 /// might end up persisting an attacker controlled file.
636 ///
637 /// # Errors
638 ///
639 /// If the file cannot be moved to the new location or a file already exists there,
640 /// `Err` is returned.
641 ///
642 /// # Examples
643 ///
644 /// ```no_run
645 /// # use std::io::{self, Write};
646 /// # extern crate tempfile;
647 /// use tempfile::NamedTempFile;
648 ///
649 /// # fn main() {
650 /// # if let Err(_) = run() {
651 /// # ::std::process::exit(1);
652 /// # }
653 /// # }
654 /// # fn run() -> Result<(), io::Error> {
655 /// let file = NamedTempFile::new()?;
656 ///
657 /// let mut persisted_file = file.persist_noclobber("./saved_file.txt")?;
658 /// writeln!(persisted_file, "Brian was here. Briefly.")?;
659 /// # Ok(())
660 /// # }
661 /// ```
662 pub fn persist_noclobber<P: AsRef<Path>>(self, new_path: P) -> Result<File, PersistError> {
663 let NamedTempFile { path, file } = self;
664 match path.persist_noclobber(new_path) {
665 Ok(_) => Ok(file),
666 Err(err) => {
667 let PathPersistError { error, path } = err;
668 Err(PersistError {
669 file: NamedTempFile { path, file },
670 error,
671 })
672 }
673 }
674 }
675
676 /// Reopen the temporary file.
677 ///
678 /// This function is useful when you need multiple independent handles to
679 /// the same file. It's perfectly fine to drop the original `NamedTempFile`
680 /// while holding on to `File`s returned by this function; the `File`s will
681 /// remain usable. However, they may not be nameable.
682 ///
683 /// # Errors
684 ///
685 /// If the file cannot be reopened, `Err` is returned.
686 ///
687 /// # Examples
688 ///
689 /// ```no_run
690 /// # use std::io;
691 /// # extern crate tempfile;
692 /// use tempfile::NamedTempFile;
693 ///
694 /// # fn main() {
695 /// # if let Err(_) = run() {
696 /// # ::std::process::exit(1);
697 /// # }
698 /// # }
699 /// # fn run() -> Result<(), io::Error> {
700 /// let file = NamedTempFile::new()?;
701 ///
702 /// let another_handle = file.reopen()?;
703 /// # Ok(())
704 /// # }
705 /// ```
706 pub fn reopen(&self) -> io::Result<File> {
707 imp::reopen(self.as_file(), NamedTempFile::path(self))
708 }
709
710 /// Get a reference to the underlying file.
711 pub fn as_file(&self) -> &File {
712 &self.file
713 }
714
715 /// Get a mutable reference to the underlying file.
716 pub fn as_file_mut(&mut self) -> &mut File {
717 &mut self.file
718 }
719
720 /// Convert the temporary file into a `std::fs::File`.
721 ///
722 /// The inner file will be deleted.
723 pub fn into_file(self) -> File {
724 self.file
725 }
726
727 /// Closes the file, leaving only the temporary file path.
728 ///
729 /// This is useful when another process must be able to open the temporary
730 /// file.
731 pub fn into_temp_path(self) -> TempPath {
732 self.path
733 }
734 }
735
736 impl Read for NamedTempFile {
737 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
738 self.as_file_mut().read(buf)
739 }
740 }
741
742 impl<'a> Read for &'a NamedTempFile {
743 fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
744 self.as_file().read(buf)
745 }
746 }
747
748 impl Write for NamedTempFile {
749 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
750 self.as_file_mut().write(buf)
751 }
752 #[inline]
753 fn flush(&mut self) -> io::Result<()> {
754 self.as_file_mut().flush()
755 }
756 }
757
758 impl<'a> Write for &'a NamedTempFile {
759 fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
760 self.as_file().write(buf)
761 }
762 #[inline]
763 fn flush(&mut self) -> io::Result<()> {
764 self.as_file().flush()
765 }
766 }
767
768 impl Seek for NamedTempFile {
769 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
770 self.as_file_mut().seek(pos)
771 }
772 }
773
774 impl<'a> Seek for &'a NamedTempFile {
775 fn seek(&mut self, pos: SeekFrom) -> io::Result<u64> {
776 self.as_file().seek(pos)
777 }
778 }
779
780 #[cfg(unix)]
781 impl std::os::unix::io::AsRawFd for NamedTempFile {
782 #[inline]
783 fn as_raw_fd(&self) -> std::os::unix::io::RawFd {
784 self.as_file().as_raw_fd()
785 }
786 }
787
788 #[cfg(windows)]
789 impl std::os::windows::io::AsRawHandle for NamedTempFile {
790 #[inline]
791 fn as_raw_handle(&self) -> std::os::windows::io::RawHandle {
792 self.as_file().as_raw_handle()
793 }
794 }
795
796 // pub(crate)
797 pub fn create_named(path: PathBuf) -> io::Result<NamedTempFile> {
798 imp::create_named(&path).map(|file| NamedTempFile {
799 path: TempPath { path },
800 file,
801 })
802 }