1 /* chown() compatibility.
2 Copyright (C) 1998, 2000, 2002, 2003 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
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.
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
13 Lesser General Public License for more details.
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
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 This file emulates chown() under the old kernels.
35 __chown (const char *file
, uid_t owner
, gid_t group
)
39 char link
[PATH_MAX
+2];
40 char path
[2*PATH_MAX
+4];
43 static int libc_old_chown
= 0 /* -1=old linux, 1=new linux, 0=unknown */;
45 if (libc_old_chown
== 1)
46 return INLINE_SYSCALL (chown
, 3, __ptrvalue (file
), owner
, group
);
51 if (libc_old_chown
== 0)
53 err
= INLINE_SYSCALL (chown
, 3, __ptrvalue (file
), owner
, group
);
54 if (err
!= -1 || errno
!= ENOSYS
)
63 err
= __readlink (file
, link
, PATH_MAX
+1);
67 return __lchown(file
, owner
, group
);
70 filelen
= strlen (file
) + 1;
71 if (filelen
> sizeof(path
))
76 memcpy (path
, file
, filelen
);
78 /* 'The system has an arbitrary limit...' In practise, we'll hit
79 ENAMETOOLONG before this, usually. */
80 for (loopct
= 0; loopct
< 128; loopct
++)
84 if (err
>= PATH_MAX
+1)
90 link
[err
] = 0; /* Null-terminate string, just-in-case. */
92 linklen
= strlen (link
) + 1;
95 memcpy (path
, link
, linklen
);
98 filelen
= strlen (path
);
100 while (filelen
> 1 && path
[filelen
-1] == '/')
102 while (filelen
> 0 && path
[filelen
-1] != '/')
104 if (filelen
+ linklen
> sizeof(path
))
106 errno
= ENAMETOOLONG
;
109 memcpy (path
+filelen
, link
, linklen
);
112 err
= __readlink(path
, link
, PATH_MAX
+1);
117 return __lchown(path
, owner
, group
);
123 libc_hidden_def (__chown
)
125 #include <shlib-compat.h>
126 versioned_symbol (libc
, __chown
, chown
, GLIBC_2_1
);