mirror of
https://github.com/MidnightCommander/mc
synced 2025-01-03 10:04:32 +03:00
Merge branch '1393_copy_dir_dir_memleak'
* 1393_copy_dir_dir_memleak: Fixed memory leak in copy_dir_dir().
This commit is contained in:
commit
ebf4c000e2
56
src/file.c
56
src/file.c
@ -774,12 +774,14 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *_d, int toplevel,
|
||||
struct dirent *next;
|
||||
struct stat buf, cbuf;
|
||||
DIR *reading;
|
||||
char *path, *mdpath, *dest_file, *dest_dir;
|
||||
char *dest_dir = NULL;
|
||||
FileProgressStatus return_status = FILE_CONT;
|
||||
struct utimbuf utb;
|
||||
struct link *lp;
|
||||
char *d;
|
||||
|
||||
d = strutils_shell_unescape (_d);
|
||||
|
||||
/* First get the mode of the source dir */
|
||||
retry_src_stat:
|
||||
if ((*ctx->stat_func) (s, &cbuf)) {
|
||||
@ -787,18 +789,17 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *_d, int toplevel,
|
||||
file_error (_(" Cannot stat source directory \"%s\" \n %s "), s);
|
||||
if (return_status == FILE_RETRY)
|
||||
goto retry_src_stat;
|
||||
return return_status;
|
||||
goto ret_fast;
|
||||
}
|
||||
|
||||
if (is_in_linklist (dest_dirs, s, &cbuf)) {
|
||||
/* Don't copy a directory we created before (we don't want to copy
|
||||
infinitely if a directory is copied into itself) */
|
||||
/* FIXME: should there be an error message and FILE_SKIP? - Norbert */
|
||||
return FILE_CONT;
|
||||
return_status = FILE_CONT;
|
||||
goto ret_fast;
|
||||
}
|
||||
|
||||
d = strutils_shell_unescape (_d);
|
||||
|
||||
/* Hmm, hardlink to directory??? - Norbert */
|
||||
/* FIXME: In this step we should do something
|
||||
in case the destination already exist */
|
||||
@ -806,8 +807,7 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *_d, int toplevel,
|
||||
if (ctx->preserve && cbuf.st_nlink > 1
|
||||
&& check_hardlinks (s, d, &cbuf) == 1) {
|
||||
/* We have made a hardlink - no more processing is necessary */
|
||||
g_free(d);
|
||||
return return_status;
|
||||
goto ret_fast;
|
||||
}
|
||||
|
||||
if (!S_ISDIR (cbuf.st_mode)) {
|
||||
@ -815,16 +815,15 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *_d, int toplevel,
|
||||
file_error (_(" Source \"%s\" is not a directory \n %s "), s);
|
||||
if (return_status == FILE_RETRY)
|
||||
goto retry_src_stat;
|
||||
g_free(d);
|
||||
return return_status;
|
||||
goto ret_fast;
|
||||
}
|
||||
|
||||
if (is_in_linklist (parent_dirs, s, &cbuf)) {
|
||||
/* we found a cyclic symbolic link */
|
||||
message (D_ERROR, MSG_ERROR,
|
||||
_(" Cannot copy cyclic symbolic link \n `%s' "), s);
|
||||
g_free(d);
|
||||
return FILE_SKIP;
|
||||
return_status = FILE_SKIP;
|
||||
goto ret_fast;
|
||||
}
|
||||
|
||||
lp = g_new (struct link, 1);
|
||||
@ -838,15 +837,14 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *_d, int toplevel,
|
||||
/* Now, check if the dest dir exists, if not, create it. */
|
||||
if (mc_stat (d, &buf)) {
|
||||
/* Here the dir doesn't exist : make it ! */
|
||||
|
||||
if (move_over) {
|
||||
if (mc_rename (s, d) == 0) {
|
||||
g_free (parent_dirs);
|
||||
g_free(d);
|
||||
return FILE_CONT;
|
||||
return_status = FILE_CONT;
|
||||
goto ret;
|
||||
}
|
||||
}
|
||||
dest_dir = g_strdup (d);
|
||||
dest_dir = d;
|
||||
d = NULL;
|
||||
} else {
|
||||
/*
|
||||
* If the destination directory exists, we want to copy the whole
|
||||
@ -861,15 +859,14 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *_d, int toplevel,
|
||||
_(" Destination \"%s\" must be a directory \n %s "), d);
|
||||
if (return_status == FILE_RETRY)
|
||||
goto retry_dst_stat;
|
||||
g_free (parent_dirs);
|
||||
g_free(d);
|
||||
return return_status;
|
||||
goto ret;
|
||||
}
|
||||
/* Dive into subdir if exists */
|
||||
if (toplevel && ctx->dive_into_subdirs) {
|
||||
dest_dir = concat_dir_and_file (d, x_basename (s));
|
||||
} else {
|
||||
dest_dir = g_strdup (d);
|
||||
dest_dir = d;
|
||||
d = NULL;
|
||||
goto dont_mkdir;
|
||||
}
|
||||
}
|
||||
@ -899,11 +896,12 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *_d, int toplevel,
|
||||
|
||||
dont_mkdir:
|
||||
/* open the source dir for reading */
|
||||
if ((reading = mc_opendir (s)) == 0) {
|
||||
reading = mc_opendir (s);
|
||||
if (reading == NULL)
|
||||
goto ret;
|
||||
}
|
||||
|
||||
while ((next = mc_readdir (reading)) && return_status != FILE_ABORT) {
|
||||
char *path;
|
||||
/*
|
||||
* Now, we don't want '.' and '..' to be created / copied at any time
|
||||
*/
|
||||
@ -917,6 +915,8 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *_d, int toplevel,
|
||||
|
||||
(*ctx->stat_func) (path, &buf);
|
||||
if (S_ISDIR (buf.st_mode)) {
|
||||
char *mdpath;
|
||||
|
||||
mdpath = concat_dir_and_file (dest_dir, next->d_name);
|
||||
/*
|
||||
* From here, we just intend to recursively copy subdirs, not
|
||||
@ -928,6 +928,8 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *_d, int toplevel,
|
||||
parent_dirs, progress_count, progress_bytes);
|
||||
g_free (mdpath);
|
||||
} else {
|
||||
char *dest_file;
|
||||
|
||||
dest_file = concat_dir_and_file (dest_dir, x_basename (path));
|
||||
return_status = copy_file_file (ctx, path, dest_file, 1,
|
||||
progress_count, progress_bytes, 0);
|
||||
@ -936,11 +938,12 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *_d, int toplevel,
|
||||
if (delete && return_status == FILE_CONT) {
|
||||
if (ctx->erase_at_end) {
|
||||
static struct link *tail;
|
||||
lp = g_malloc (sizeof (struct link) + strlen (path));
|
||||
strcpy (lp->name, path);
|
||||
size_t len = strlen (path);
|
||||
lp = g_malloc (sizeof (struct link) + len);
|
||||
strncpy (lp->name, path, len + 1);
|
||||
lp->st_mode = buf.st_mode;
|
||||
lp->next = 0;
|
||||
if (erase_list) {
|
||||
lp->next = NULL;
|
||||
if (erase_list != NULL) {
|
||||
tail->next = lp;
|
||||
tail = lp;
|
||||
} else
|
||||
@ -971,6 +974,7 @@ copy_dir_dir (FileOpContext *ctx, const char *s, const char *_d, int toplevel,
|
||||
ret:
|
||||
g_free (dest_dir);
|
||||
g_free (parent_dirs);
|
||||
ret_fast:
|
||||
g_free (d);
|
||||
return return_status;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user