]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/i386/chown.c
Update.
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / i386 / chown.c
CommitLineData
958f238f 1/* Copyright (C) 1998, 1999 Free Software Foundation, Inc.
19212f87
UD
2 This file is part of the GNU C Library.
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB. If not,
16 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17 Boston, MA 02111-1307, USA. */
18
19#include <errno.h>
20#include <unistd.h>
0dee6738
UD
21
22#include <sysdep.h>
19212f87
UD
23#include <sys/syscall.h>
24
958f238f
UD
25#include <kernel-features.h>
26
19212f87
UD
27/*
28 In Linux 2.1.x the chown functions have been changed. A new function lchown
29 was introduced. The new chown now follows symlinks - the old chown and the
30 new lchown do not follow symlinks.
31 The new lchown function has the same number as the old chown had and the
32 new chown has a new number. When compiling with headers from Linux > 2.1.8x
33 it's impossible to run this libc with older kernels. In these cases libc
34 has therefore to route calls to chown to the old chown function.
35*/
36
37extern int __syscall_chown (const char *__file,
38 uid_t __owner, gid_t __group);
958f238f 39#if defined __NR_lchown || __ASSUME_LCHOWN_SYSCALL > 0
b937f591 40/* Running under Linux > 2.1.80. */
19212f87
UD
41
42
43int
44__real_chown (const char *file, uid_t owner, gid_t group)
45{
958f238f
UD
46# if __ASSUME_LCHOWN_SYSCALL == 0
47 static int __libc_old_chown;
19212f87
UD
48 int result;
49
50 if (!__libc_old_chown)
51 {
52 int saved_errno = errno;
0dee6738 53 result = INLINE_SYSCALL (chown, 3, file, owner, group);
19212f87
UD
54
55 if (result >= 0 || errno != ENOSYS)
56 return result;
57
58 __set_errno (saved_errno);
59 __libc_old_chown = 1;
60 }
61
62 return __lchown (file, owner, group);
958f238f
UD
63# else
64 return INLINE_SYSCALL (chown, 3, file, owner, group);
65# endif
19212f87
UD
66}
67#endif
68
69
958f238f 70#if !defined __NR_lchown && __ASSUME_LCHOWN_SYSCALL == 0
63bda0c1
UD
71/* Compiling under older kernels. */
72int
73__chown_is_lchown (const char *file, uid_t owner, gid_t group)
74{
0dee6738 75 return INLINE_SYSCALL (chown, 3, file, owner, group);
63bda0c1
UD
76}
77#elif defined HAVE_ELF && defined PIC && defined DO_VERSIONING
78/* Compiling for compatibiity. */
19212f87
UD
79int
80__chown_is_lchown (const char *file, uid_t owner, gid_t group)
81{
82 return __lchown (file, owner, group);
83}
84#endif
85
86#if defined HAVE_ELF && defined PIC && defined DO_VERSIONING
87strong_alias (__chown_is_lchown, _chown_is_lchown)
88symbol_version (__chown_is_lchown, __chown, GLIBC_2.0);
89symbol_version (_chown_is_lchown, chown, GLIBC_2.0);
90
91# ifdef __NR_lchown
92strong_alias (__real_chown, _real_chown)
93default_symbol_version (__real_chown, __chown, GLIBC_2.1);
94default_symbol_version (_real_chown, chown, GLIBC_2.1);
95# else
96strong_alias (__chown_is_lchown, __chown_is_lchown21)
97strong_alias (__chown_is_lchown, _chown_is_lchown21)
98default_symbol_version (__chown_is_lchown21, __chown, GLIBC_2.1);
99default_symbol_version (_chown_is_lchown21, chown, GLIBC_2.1);
100# endif
101#else
102# ifdef __NR_lchown
103strong_alias (__real_chown, __chown)
104weak_alias (__real_chown, chown)
105# else
106strong_alias (__chown_is_lchown, __chown)
107weak_alias (__chown_is_lchown, chown)
108# endif
109#endif