Skip to content

Commit

Permalink
support to copy link and dirs for windows
Browse files Browse the repository at this point in the history
  • Loading branch information
waruqi committed Feb 6, 2024
1 parent 4809161 commit 3b4b1d2
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 13 deletions.
33 changes: 24 additions & 9 deletions src/tbox/platform/windows/directory.c
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ static tb_long_t tb_directory_walk_copy(tb_char_t const* path, tb_file_info_t co
tb_size_t size = tuple[1].ul;
tb_char_t const* name = path + size;

// the copy flags
tb_size_t flags = tuple[2].ul;

// the dest file path
tb_char_t dpath[8192] = {0};
tb_snprintf(dpath, 8192, "%s\\%s", dest, name[0] == '\\'? name + 1 : name);
Expand All @@ -77,18 +80,33 @@ static tb_long_t tb_directory_walk_copy(tb_char_t const* path, tb_file_info_t co
}

// copy
tb_bool_t ok = tb_true;
tb_bool_t skip_recursion = tb_false;
switch (info->type)
{
case TB_FILE_TYPE_FILE:
if (!tb_file_copy(path, dpath, TB_FILE_COPY_NONE)) tuple[2].b = tb_false;
ok = tb_file_copy(path, dpath, flags);
break;
case TB_FILE_TYPE_DIRECTORY:
if (!tb_directory_create(dpath)) tuple[2].b = tb_false;
{
// reserve symlink?
if ((flags & TB_FILE_COPY_LINK) && (info->flags & TB_FILE_FLAG_LINK))
{
// just copy link and skip recursion
ok = tb_file_copy(path, dpath, TB_FILE_COPY_LINK);
skip_recursion = tb_true;
}
else ok = tb_directory_create(dpath);
}
break;
default:
break;
}
return TB_DIRECTORY_WALK_CODE_CONTINUE;
tuple[3].b = ok;
tb_size_t retcode = TB_DIRECTORY_WALK_CODE_CONTINUE;
if (skip_recursion)
retcode |= TB_DIRECTORY_WALK_CODE_SKIP_RECURSION;
return retcode;
}
static tb_long_t tb_directory_walk_impl(tb_wchar_t const* path, tb_long_t recursion, tb_bool_t prefix, tb_directory_walk_func_t func, tb_cpointer_t priv)
{
Expand Down Expand Up @@ -321,16 +339,13 @@ tb_bool_t tb_directory_copy(tb_char_t const* path, tb_char_t const* dest, tb_siz
tb_value_t tuple[3];
tuple[0].cstr = dest;
tuple[1].ul = tb_strlen(path);
tuple[2].b = tb_true;
tuple[2].ul = flags;
tuple[3].b = tb_true;
tb_directory_walk(path, -1, tb_true, tb_directory_walk_copy, tuple);

// ok?
tb_bool_t ok = tuple[2].b;

// copy empty directory?
tb_bool_t ok = tuple[3].b;
if (ok && !tb_file_info(dest, tb_null))
return tb_directory_create(dest);

// ok?
return ok;
}
29 changes: 25 additions & 4 deletions src/tbox/platform/windows/file.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,10 +442,31 @@ tb_bool_t tb_file_copy(tb_char_t const* path, tb_char_t const* dest, tb_size_t f
tb_file_info_t info = {0};
if (flags & TB_FILE_COPY_LINK && tb_file_info(path, &info) && info.flags & TB_FILE_FLAG_LINK)
{
if (tb_kernel32()->CopyFileExW)
return (tb_bool_t)tb_kernel32()->CopyFileExW(full0, full1, tb_null, tb_null, FALSE, COPY_FILE_COPY_SYMLINK);
// TODO we should read file content to copy it
// ...
tb_file_mkdir(full1);
if (tb_kernel32()->CopyFileExW && tb_kernel32()->CopyFileExW(full0, full1, tb_null, tb_null, FALSE, COPY_FILE_COPY_SYMLINK))
return tb_true;

// we should read file content to copy it
tb_bool_t ok = tb_false;
tb_file_ref_t ifile = tb_file_init(path, TB_FILE_MODE_RW);
tb_file_ref_t ofile = tb_file_init(dest, TB_FILE_MODE_RW | TB_FILE_MODE_CREAT | TB_FILE_MODE_TRUNC);
if (ifile && ofile)
{
tb_hize_t writ = 0;
tb_hize_t size = tb_file_size(ifile);
while (writ < size)
{
tb_long_t real = tb_file_writf(ofile, ifile, writ, size - writ);
if (real > 0) writ += real;
else break;
}
if (writ == size) ok = tb_true;
}

// exit file
if (ifile) tb_file_exit(ifile);
if (ofile) tb_file_exit(ofile);
return ok;
}

// copy it
Expand Down

0 comments on commit 3b4b1d2

Please sign in to comment.