mirror of
https://github.com/upa/mscp.git
synced 2026-03-14 04:13:28 +08:00
don't allocate char[PATH_MAX] for each file
This commit makes struct path allocation use strndup(). It reduices the memory footprint for struct path per file (issue #8).
This commit is contained in:
21
src/mscp.c
21
src/mscp.c
@@ -714,7 +714,7 @@ out:
|
|||||||
|
|
||||||
/* cleanup-related functions */
|
/* cleanup-related functions */
|
||||||
|
|
||||||
static void free_src(struct list_head *list)
|
static void list_free_src(struct list_head *list)
|
||||||
{
|
{
|
||||||
struct src *s;
|
struct src *s;
|
||||||
s = list_entry(list, typeof(*s), list);
|
s = list_entry(list, typeof(*s), list);
|
||||||
@@ -722,21 +722,14 @@ static void free_src(struct list_head *list)
|
|||||||
free(s);
|
free(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_path(struct list_head *list)
|
static void list_free_path(struct list_head *list)
|
||||||
{
|
{
|
||||||
struct path *p;
|
struct path *p;
|
||||||
p = list_entry(list, typeof(*p), list);
|
p = list_entry(list, typeof(*p), list);
|
||||||
free(p);
|
free_path(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void free_chunk(struct list_head *list)
|
static void list_free_thread(struct list_head *list)
|
||||||
{
|
|
||||||
struct chunk *c;
|
|
||||||
c = list_entry(list, typeof(*c), list);
|
|
||||||
free(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void free_thread(struct list_head *list)
|
|
||||||
{
|
{
|
||||||
struct mscp_thread *t;
|
struct mscp_thread *t;
|
||||||
t = list_entry(list, typeof(*t), list);
|
t = list_entry(list, typeof(*t), list);
|
||||||
@@ -750,17 +743,17 @@ void mscp_cleanup(struct mscp *m)
|
|||||||
m->first = NULL;
|
m->first = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
list_free_f(&m->src_list, free_src);
|
list_free_f(&m->src_list, list_free_src);
|
||||||
INIT_LIST_HEAD(&m->src_list);
|
INIT_LIST_HEAD(&m->src_list);
|
||||||
|
|
||||||
list_free_f(&m->path_list, free_path);
|
list_free_f(&m->path_list, list_free_path);
|
||||||
INIT_LIST_HEAD(&m->path_list);
|
INIT_LIST_HEAD(&m->path_list);
|
||||||
|
|
||||||
chunk_pool_release(&m->cp);
|
chunk_pool_release(&m->cp);
|
||||||
chunk_pool_init(&m->cp);
|
chunk_pool_init(&m->cp);
|
||||||
|
|
||||||
RWLOCK_WRITE_ACQUIRE(&m->thread_rwlock);
|
RWLOCK_WRITE_ACQUIRE(&m->thread_rwlock);
|
||||||
list_free_f(&m->thread_list, free_thread);
|
list_free_f(&m->thread_list, list_free_thread);
|
||||||
RWLOCK_RELEASE();
|
RWLOCK_RELEASE();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
29
src/path.c
29
src/path.c
@@ -92,10 +92,9 @@ void chunk_pool_release(struct chunk_pool *cp)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* paths of copy source resoltion */
|
/* paths of copy source resoltion */
|
||||||
static int resolve_dst_path(const char *src_file_path, char *dst_file_path,
|
static char *resolve_dst_path(const char *src_file_path, struct path_resolve_args *a)
|
||||||
struct path_resolve_args *a)
|
|
||||||
{
|
{
|
||||||
char copy[PATH_MAX + 1];
|
char copy[PATH_MAX + 1], dst_file_path[PATH_MAX + 1];
|
||||||
char *prefix;
|
char *prefix;
|
||||||
int offset;
|
int offset;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -104,7 +103,7 @@ static int resolve_dst_path(const char *src_file_path, char *dst_file_path,
|
|||||||
prefix = dirname(copy);
|
prefix = dirname(copy);
|
||||||
if (!prefix) {
|
if (!prefix) {
|
||||||
mscp_set_error("dirname: %s", strerrno());
|
mscp_set_error("dirname: %s", strerrno());
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
offset = strlen(prefix) + 1;
|
offset = strlen(prefix) + 1;
|
||||||
@@ -147,12 +146,12 @@ static int resolve_dst_path(const char *src_file_path, char *dst_file_path,
|
|||||||
|
|
||||||
if (ret >= PATH_MAX) {
|
if (ret >= PATH_MAX) {
|
||||||
mpr_warn(a->msg_fp, "Too long path: %s\n", dst_file_path);
|
mpr_warn(a->msg_fp, "Too long path: %s\n", dst_file_path);
|
||||||
return -1;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpr_debug(a->msg_fp, "file: %s -> %s\n", src_file_path, dst_file_path);
|
mpr_debug(a->msg_fp, "file: %s -> %s\n", src_file_path, dst_file_path);
|
||||||
|
|
||||||
return 0;
|
return strndup(dst_file_path, PATH_MAX);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* chunk preparation */
|
/* chunk preparation */
|
||||||
@@ -208,6 +207,15 @@ static int resolve_chunk(struct path *p, struct path_resolve_args *a)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void free_path(struct path *p)
|
||||||
|
{
|
||||||
|
if (p->path)
|
||||||
|
free(p->path);
|
||||||
|
if (p->dst_path)
|
||||||
|
free(p->dst_path);
|
||||||
|
free(p);
|
||||||
|
}
|
||||||
|
|
||||||
static int append_path(sftp_session sftp, const char *path, struct stat st,
|
static int append_path(sftp_session sftp, const char *path, struct stat st,
|
||||||
struct list_head *path_list, struct path_resolve_args *a)
|
struct list_head *path_list, struct path_resolve_args *a)
|
||||||
{
|
{
|
||||||
@@ -220,13 +228,16 @@ static int append_path(sftp_session sftp, const char *path, struct stat st,
|
|||||||
|
|
||||||
memset(p, 0, sizeof(*p));
|
memset(p, 0, sizeof(*p));
|
||||||
INIT_LIST_HEAD(&p->list);
|
INIT_LIST_HEAD(&p->list);
|
||||||
strncpy(p->path, path, PATH_MAX - 1);
|
p->path = strndup(path, PATH_MAX);
|
||||||
|
if (!p->path)
|
||||||
|
goto free_out;
|
||||||
p->size = st.st_size;
|
p->size = st.st_size;
|
||||||
p->mode = st.st_mode;
|
p->mode = st.st_mode;
|
||||||
p->state = FILE_STATE_INIT;
|
p->state = FILE_STATE_INIT;
|
||||||
lock_init(&p->lock);
|
lock_init(&p->lock);
|
||||||
|
|
||||||
if (resolve_dst_path(p->path, p->dst_path, a) < 0)
|
p->dst_path = resolve_dst_path(p->path, a);
|
||||||
|
if (!p->dst_path)
|
||||||
goto free_out;
|
goto free_out;
|
||||||
|
|
||||||
if (resolve_chunk(p, a) < 0)
|
if (resolve_chunk(p, a) < 0)
|
||||||
@@ -239,7 +250,7 @@ static int append_path(sftp_session sftp, const char *path, struct stat st,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
free_out:
|
free_out:
|
||||||
free(p);
|
free_path(p);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
11
src/path.h
11
src/path.h
@@ -14,11 +14,11 @@
|
|||||||
struct path {
|
struct path {
|
||||||
struct list_head list; /* mscp->path_list */
|
struct list_head list; /* mscp->path_list */
|
||||||
|
|
||||||
char path[PATH_MAX]; /* file path */
|
char *path; /* file path */
|
||||||
size_t size; /* size of file on this path */
|
size_t size; /* size of file on this path */
|
||||||
mode_t mode; /* permission */
|
mode_t mode; /* permission */
|
||||||
|
|
||||||
char dst_path[PATH_MAX]; /* copy dst path */
|
char *dst_path; /* copy dst path */
|
||||||
|
|
||||||
int state;
|
int state;
|
||||||
lock lock;
|
lock lock;
|
||||||
@@ -93,6 +93,9 @@ struct path_resolve_args {
|
|||||||
int walk_src_path(sftp_session src_sftp, const char *src_path,
|
int walk_src_path(sftp_session src_sftp, const char *src_path,
|
||||||
struct list_head *path_list, struct path_resolve_args *a);
|
struct list_head *path_list, struct path_resolve_args *a);
|
||||||
|
|
||||||
|
/* free struct path */
|
||||||
|
void free_path(struct path *p);
|
||||||
|
|
||||||
/* copy a chunk. either src_sftp or dst_sftp is not null, and another is null */
|
/* copy a chunk. either src_sftp or dst_sftp is not null, and another is null */
|
||||||
int copy_chunk(FILE *msg_fp, struct chunk *c,
|
int copy_chunk(FILE *msg_fp, struct chunk *c,
|
||||||
sftp_session src_sftp, sftp_session dst_sftp,
|
sftp_session src_sftp, sftp_session dst_sftp,
|
||||||
|
|||||||
Reference in New Issue
Block a user