ash: builtin: Mark more regular built-ins
[oweals/busybox.git] / libbb / copy_file.c
index be90066311fbb34c48e8c0def9d206db9c262068..49d1ec9c61d50ce62720e435643e7f3ceb1960c2 100644 (file)
@@ -48,7 +48,7 @@ static int ask_and_unlink(const char *dest, int flags)
                // (No "opening without O_EXCL", no "unlink only if -f")
                // Or else we will end up having 3 open()s!
                fprintf(stderr, "%s: overwrite '%s'? ", applet_name, dest);
-               if (!bb_ask_confirmation())
+               if (!bb_ask_y_confirmation())
                        return 0; /* not allowed to overwrite */
        }
        if (unlink(dest) < 0) {
@@ -327,7 +327,7 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags)
                ) {
                        security_context_t con;
                        if (getfscreatecon(&con) == -1) {
-                               bb_perror_msg("getfscreatecon");
+                               bb_simple_perror_msg("getfscreatecon");
                                return -1;
                        }
                        if (con) {
@@ -339,9 +339,28 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags)
                                freecon(con);
                        }
                }
+#endif
+#if ENABLE_FEATURE_CP_REFLINK
+# undef BTRFS_IOCTL_MAGIC
+# define BTRFS_IOCTL_MAGIC 0x94
+# undef BTRFS_IOC_CLONE
+# define BTRFS_IOC_CLONE _IOW (BTRFS_IOCTL_MAGIC, 9, int)
+               if (flags & FILEUTILS_REFLINK) {
+                       retval = ioctl(dst_fd, BTRFS_IOC_CLONE, src_fd);
+                       if (retval == 0)
+                               goto do_close;
+                       /* reflink did not work */
+                       if (flags & FILEUTILS_REFLINK_ALWAYS) {
+                               bb_perror_msg("failed to clone '%s' from '%s'", dest, source);
+                               goto do_close;
+                       }
+                       /* fall through to standard copy */
+                       retval = 0;
+               }
 #endif
                if (bb_copyfd_eof(src_fd, dst_fd) == -1)
                        retval = -1;
+ IF_FEATURE_CP_REFLINK(do_close:)
                /* Careful with writing... */
                if (close(dst_fd) < 0) {
                        bb_perror_msg("error writing to '%s'", dest);
@@ -369,14 +388,15 @@ int FAST_FUNC copy_file(const char *source, const char *dest, int flags)
                char *lpath = xmalloc_readlink_or_warn(source);
                if (lpath) {
                        int r = symlink(lpath, dest);
-                       free(lpath);
                        if (r < 0) {
                                /* shared message */
                                bb_perror_msg("can't create %slink '%s' to '%s'",
                                        "sym", dest, lpath
                                );
+                               free(lpath);
                                return -1;
                        }
+                       free(lpath);
                        if (flags & FILEUTILS_PRESERVE_STATUS)
                                if (lchown(dest, source_stat.st_uid, source_stat.st_gid) < 0)
                                        bb_perror_msg("can't preserve %s of '%s'", "ownership", dest);