mirror of
https://github.com/RGBCube/serenity
synced 2025-07-26 19:57:45 +00:00
Userland: Give cp a "-l" flag to make hard links
Also present on Linux and FreeBSD.
This commit is contained in:
parent
8079d566f1
commit
cd2f85dc10
1 changed files with 17 additions and 7 deletions
|
@ -36,9 +36,9 @@
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
|
||||||
bool copy_file_or_directory(String, String, bool);
|
bool copy_file_or_directory(String, String, bool, bool);
|
||||||
bool copy_file(String, String, const struct stat&, int);
|
bool copy_file(String, String, const struct stat&, int);
|
||||||
bool copy_directory(String, String);
|
bool copy_directory(String, String, bool);
|
||||||
|
|
||||||
static mode_t my_umask = 0;
|
static mode_t my_umask = 0;
|
||||||
|
|
||||||
|
@ -49,12 +49,14 @@ int main(int argc, char** argv)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool link = false;
|
||||||
bool recursion_allowed = false;
|
bool recursion_allowed = false;
|
||||||
bool verbose = false;
|
bool verbose = false;
|
||||||
Vector<const char*> sources;
|
Vector<const char*> sources;
|
||||||
const char* destination = nullptr;
|
const char* destination = nullptr;
|
||||||
|
|
||||||
Core::ArgsParser args_parser;
|
Core::ArgsParser args_parser;
|
||||||
|
args_parser.add_option(link, "Link files instead of copying", "link", 'l');
|
||||||
args_parser.add_option(recursion_allowed, "Copy directories recursively", "recursive", 'r');
|
args_parser.add_option(recursion_allowed, "Copy directories recursively", "recursive", 'r');
|
||||||
args_parser.add_option(verbose, "Verbose", "verbose", 'v');
|
args_parser.add_option(verbose, "Verbose", "verbose", 'v');
|
||||||
args_parser.add_positional_argument(sources, "Source file path", "source");
|
args_parser.add_positional_argument(sources, "Source file path", "source");
|
||||||
|
@ -65,7 +67,7 @@ int main(int argc, char** argv)
|
||||||
umask(my_umask);
|
umask(my_umask);
|
||||||
|
|
||||||
for (auto& source : sources) {
|
for (auto& source : sources) {
|
||||||
bool ok = copy_file_or_directory(source, destination, recursion_allowed);
|
bool ok = copy_file_or_directory(source, destination, recursion_allowed, link);
|
||||||
if (!ok)
|
if (!ok)
|
||||||
return 1;
|
return 1;
|
||||||
if (verbose)
|
if (verbose)
|
||||||
|
@ -80,7 +82,7 @@ int main(int argc, char** argv)
|
||||||
*
|
*
|
||||||
* Directories should only be copied if recursion_allowed is set.
|
* Directories should only be copied if recursion_allowed is set.
|
||||||
*/
|
*/
|
||||||
bool copy_file_or_directory(String src_path, String dst_path, bool recursion_allowed)
|
bool copy_file_or_directory(String src_path, String dst_path, bool recursion_allowed, bool link)
|
||||||
{
|
{
|
||||||
int src_fd = open(src_path.characters(), O_RDONLY);
|
int src_fd = open(src_path.characters(), O_RDONLY);
|
||||||
if (src_fd < 0) {
|
if (src_fd < 0) {
|
||||||
|
@ -100,8 +102,16 @@ bool copy_file_or_directory(String src_path, String dst_path, bool recursion_all
|
||||||
fprintf(stderr, "cp: -r not specified; omitting directory '%s'\n", src_path.characters());
|
fprintf(stderr, "cp: -r not specified; omitting directory '%s'\n", src_path.characters());
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return copy_directory(src_path, dst_path);
|
return copy_directory(src_path, dst_path, link);
|
||||||
}
|
}
|
||||||
|
if (link) {
|
||||||
|
if (::link(src_path.characters(), dst_path.characters()) < 0) {
|
||||||
|
perror("link");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
return copy_file(src_path, dst_path, src_stat, src_fd);
|
return copy_file(src_path, dst_path, src_stat, src_fd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +182,7 @@ bool copy_file(String src_path, String dst_path, const struct stat& src_stat, in
|
||||||
/**
|
/**
|
||||||
* Copy the contents of a source directory into a destination directory.
|
* Copy the contents of a source directory into a destination directory.
|
||||||
*/
|
*/
|
||||||
bool copy_directory(String src_path, String dst_path)
|
bool copy_directory(String src_path, String dst_path, bool link)
|
||||||
{
|
{
|
||||||
int rc = mkdir(dst_path.characters(), 0755);
|
int rc = mkdir(dst_path.characters(), 0755);
|
||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
|
@ -201,7 +211,7 @@ bool copy_directory(String src_path, String dst_path)
|
||||||
bool is_copied = copy_file_or_directory(
|
bool is_copied = copy_file_or_directory(
|
||||||
String::format("%s/%s", src_path.characters(), filename.characters()),
|
String::format("%s/%s", src_path.characters(), filename.characters()),
|
||||||
String::format("%s/%s", dst_path.characters(), filename.characters()),
|
String::format("%s/%s", dst_path.characters(), filename.characters()),
|
||||||
true);
|
true, link);
|
||||||
if (!is_copied) {
|
if (!is_copied) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue