diff options
author | Jim Meyering <jim@meyering.net> | 2005-09-19 15:45:05 +0000 |
---|---|---|
committer | Jim Meyering <jim@meyering.net> | 2005-09-19 15:45:05 +0000 |
commit | ee8931ea8eae960a9f3224627a16a5e5c3ad7a82 (patch) | |
tree | f4058db22ef0f59095f70f8eba70c1d65378fc8f | |
parent | a1052bb3d9473a3d459c379daac3a923b2f9dc0f (diff) | |
download | coreutils-ee8931ea8eae960a9f3224627a16a5e5c3ad7a82.tar.xz |
(unlinkat): New function.
-rw-r--r-- | lib/openat.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/lib/openat.c b/lib/openat.c index 8908931b2..3e3251ba1 100644 --- a/lib/openat.c +++ b/lib/openat.c @@ -170,3 +170,43 @@ fstatat (int fd, char const *file, struct stat *st, int flag) errno = saved_errno; return err; } + +/* Replacement for Solaris' function by the same name. + <http://www.google.com/search?q=unlinkat+site:docs.sun.com> + Simulate it by doing save_cwd/fchdir/(unlink|rmdir)/restore_cwd. + If either the save_cwd or the restore_cwd fails (relatively unlikely, + and usually indicative of a problem that deserves close attention), + then give a diagnostic and exit nonzero. + Otherwise, this function works just like Solaris' unlinkat. */ +int +unlinkat (int fd, char const *file, int flag) +{ + struct saved_cwd saved_cwd; + int saved_errno; + int err; + + if (fd == AT_FDCWD) + return (flag == AT_REMOVEDIR ? rmdir (file) : unlink (file)); + + 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; +} |