]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/pread.c
Use <> for include of kernel-features.h.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / pread.c
CommitLineData
6ddd37a4 1/* Copyright (C) 1997-2000,2002,2003,2004,2006 Free Software Foundation, Inc.
af6f3906
UD
2 This file is part of the GNU C Library.
3 Contributed by Ulrich Drepper <drepper@cygnus.com>, 1997.
4
5 The GNU C Library is free software; you can redistribute it and/or
41bdb6e2
AJ
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
af6f3906
UD
9
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
41bdb6e2 13 Lesser General Public License for more details.
af6f3906 14
41bdb6e2
AJ
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, write to the Free
17 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18 02111-1307 USA. */
af6f3906 19
cd682e15 20#include <assert.h>
d71b808a 21#include <errno.h>
741845cb 22#include <endian.h>
af6f3906 23#include <unistd.h>
0dee6738 24
6ee8d334 25#include <sysdep-cancel.h>
36ecfe56 26#include <sys/syscall.h>
4bbb61e4 27#include <bp-checks.h>
36ecfe56 28
6ddd37a4 29#include <kernel-features.h>
958f238f 30
4b172769
RM
31#ifdef __NR_pread64 /* Newer kernels renamed but it's the same. */
32# ifdef __NR_pread
33# error "__NR_pread and __NR_pread64 both defined???"
34# endif
35# define __NR_pread __NR_pread64
36#endif
37
958f238f 38#if defined __NR_pread || __ASSUME_PREAD_SYSCALL > 0
af6f3906 39
958f238f 40# if __ASSUME_PREAD_SYSCALL == 0
d71b808a
UD
41static ssize_t __emulate_pread (int fd, void *buf, size_t count,
42 off_t offset) internal_function;
958f238f 43# endif
d71b808a
UD
44
45
6ee8d334 46static ssize_t
ce6e047f
UD
47#ifdef NO_CANCELLATION
48inline __attribute ((always_inline))
49#endif
6ee8d334 50do_pread (int fd, void *buf, size_t count, off_t offset)
af6f3906 51{
d71b808a
UD
52 ssize_t result;
53
54 /* First try the syscall. */
cd682e15 55 assert (sizeof (offset) == 4);
4bbb61e4 56 result = INLINE_SYSCALL (pread, 5, fd, CHECK_N (buf, count), count,
cd682e15 57 __LONG_LONG_PAIR (offset >> 31, offset));
958f238f 58# if __ASSUME_PREAD_SYSCALL == 0
d71b808a
UD
59 if (result == -1 && errno == ENOSYS)
60 /* No system call available. Use the emulation. */
61 result = __emulate_pread (fd, buf, count, offset);
958f238f 62# endif
d71b808a
UD
63
64 return result;
af6f3906
UD
65}
66
6ee8d334
UD
67
68ssize_t
69__libc_pread (fd, buf, count, offset)
70 int fd;
71 void *buf;
72 size_t count;
73 off_t offset;
74{
75 if (SINGLE_THREAD_P)
76 return do_pread (fd, buf, count, offset);
77
78 int oldtype = LIBC_CANCEL_ASYNC ();
79
80 ssize_t result = do_pread (fd, buf, count, offset);
81
82 LIBC_CANCEL_RESET (oldtype);
83
84 return result;
85}
86
bef24895 87strong_alias (__libc_pread, __pread)
778c59c8 88weak_alias (__libc_pread, pread)
d71b808a 89
778c59c8 90# define __libc_pread(fd, buf, count, offset) \
d71b808a 91 static internal_function __emulate_pread (fd, buf, count, offset)
36ecfe56 92#endif
958f238f
UD
93
94#if __ASSUME_PREAD_SYSCALL == 0
95# include <sysdeps/posix/pread.c>
96#endif