1 /* Write block to given position in file without changing file pointer. 2 POSIX version. 3 Copyright (C) 1997-1999, 2002, 2011-2021 Free Software Foundation, Inc. 4 This file is part of the GNU C Library. 5 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997. 6 7 This file is free software: you can redistribute it and/or modify 8 it under the terms of the GNU Lesser General Public License as 9 published by the Free Software Foundation; either version 2.1 of the 10 License, or (at your option) any later version. 11 12 This file is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU Lesser General Public License for more details. 16 17 You should have received a copy of the GNU Lesser General Public License 18 along with this program. If not, see <https://www.gnu.org/licenses/>. */ 19 20 #include <config.h> 21 22 /* Specification. */ 23 #include <unistd.h> 24 25 #include <errno.h> 26 27 #define __libc_lseek(f,o,w) lseek (f, o, w) 28 #define __set_errno(Val) errno = (Val) 29 #define __libc_write(f,b,n) write (f, b, n) 30 31 /* Note: This implementation of pwrite is not multithread-safe. */ 32 33 ssize_t 34 pwrite (int fd, const void *buf, size_t nbyte, off_t offset) /* */ 35 { 36 /* Since we must not change the file pointer preserve the value so that 37 we can restore it later. */ 38 int save_errno; 39 ssize_t result; 40 off_t old_offset = __libc_lseek (fd, 0, SEEK_CUR); 41 if (old_offset == (off_t) -1) 42 return -1; 43 44 /* Set to wanted position. */ 45 if (__libc_lseek (fd, offset, SEEK_SET) == (off_t) -1) 46 return -1; 47 48 /* Write out the data. */ 49 result = __libc_write (fd, buf, nbyte); 50 51 /* Now we have to restore the position. If this fails we have to 52 return this as an error. But if the writing also failed we 53 return this error. */ 54 save_errno = errno; 55 if (__libc_lseek (fd, old_offset, SEEK_SET) == (off_t) -1) 56 { 57 if (result == -1) 58 __set_errno (save_errno); 59 return -1; 60 } 61 __set_errno (save_errno); 62 63 return result; 64 }