- if (save_cwd (&saved_cwd) != 0)
- openat_save_fail (errno);
-
- if (fchdir (fd) != 0)
- {
- saved_errno = errno;
- free_cwd (&saved_cwd);
- errno = saved_errno;
- return -1;
- }
-
- err = (flag == AT_REMOVEDIR ? rmdir (file) : unlink (file));
- saved_errno = errno;
-
- if (restore_cwd (&saved_cwd) != 0)
- openat_restore_fail (errno);
-
- free_cwd (&saved_cwd);
-
- errno = saved_errno;
- return err;
-}
+/* Replacement for Solaris' function by the same name.
+ Invoke chown or lchown on file, FILE, using OWNER and GROUP, in the
+ directory open on descriptor FD. If FLAG is AT_SYMLINK_NOFOLLOW, then
+ use lchown, otherwise, use chown. If possible, do it without changing
+ the working directory. Otherwise, resort to using save_cwd/fchdir,
+ then mkdir/restore_cwd. If either the save_cwd or the restore_cwd
+ fails, then give a diagnostic and exit nonzero. */
+
+#define AT_FUNC_NAME fchownat
+#define AT_FUNC_F1 lchown
+#define AT_FUNC_F2 chown
+#define AT_FUNC_USE_F1_COND flag == AT_SYMLINK_NOFOLLOW
+#define AT_FUNC_POST_FILE_PARAM_DECLS , uid_t owner, gid_t group, int flag
+#define AT_FUNC_POST_FILE_ARGS , owner, group
+#include "at-func.c"