diff options
author | Ryo Nakamura <upa@haeena.net> | 2024-01-11 21:23:33 +0900 |
---|---|---|
committer | Ryo Nakamura <upa@haeena.net> | 2024-01-18 12:59:49 +0900 |
commit | bba53fab03d49e1330ca1292ed18e84bd5f5b1ef (patch) | |
tree | 0e234c4dbf3452cef4ba84c5b0659d33172c67ce | |
parent | 5cbf3ad6480adb6615a9a80b59d4a9d1ade62431 (diff) |
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).
-rw-r--r-- | src/mscp.c | 21 | ||||
-rw-r--r-- | src/path.c | 29 | ||||
-rw-r--r-- | src/path.h | 11 |
3 files changed, 34 insertions, 27 deletions
@@ -714,7 +714,7 @@ out: /* cleanup-related functions */ -static void free_src(struct list_head *list) +static void list_free_src(struct list_head *list) { struct src *s; s = list_entry(list, typeof(*s), list); @@ -722,21 +722,14 @@ static void free_src(struct list_head *list) free(s); } -static void free_path(struct list_head *list) +static void list_free_path(struct list_head *list) { struct path *p; p = list_entry(list, typeof(*p), list); - free(p); + free_path(p); } -static void free_chunk(struct list_head *list) -{ - struct chunk *c; - c = list_entry(list, typeof(*c), list); - free(c); -} - -static void free_thread(struct list_head *list) +static void list_free_thread(struct list_head *list) { struct mscp_thread *t; t = list_entry(list, typeof(*t), list); @@ -750,17 +743,17 @@ void mscp_cleanup(struct mscp *m) 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); - list_free_f(&m->path_list, free_path); + list_free_f(&m->path_list, list_free_path); INIT_LIST_HEAD(&m->path_list); chunk_pool_release(&m->cp); chunk_pool_init(&m->cp); 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(); } @@ -92,10 +92,9 @@ void chunk_pool_release(struct chunk_pool *cp) } /* paths of copy source resoltion */ -static int resolve_dst_path(const char *src_file_path, char *dst_file_path, - struct path_resolve_args *a) +static char *resolve_dst_path(const char *src_file_path, struct path_resolve_args *a) { - char copy[PATH_MAX + 1]; + char copy[PATH_MAX + 1], dst_file_path[PATH_MAX + 1]; char *prefix; int offset; int ret; @@ -104,7 +103,7 @@ static int resolve_dst_path(const char *src_file_path, char *dst_file_path, prefix = dirname(copy); if (!prefix) { mscp_set_error("dirname: %s", strerrno()); - return -1; + return NULL; } 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) { 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); - return 0; + return strndup(dst_file_path, PATH_MAX); } /* chunk preparation */ @@ -208,6 +207,15 @@ static int resolve_chunk(struct path *p, struct path_resolve_args *a) 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, 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)); 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->mode = st.st_mode; p->state = FILE_STATE_INIT; 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; 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; free_out: - free(p); + free_path(p); return -1; } @@ -14,11 +14,11 @@ struct path { struct list_head list; /* mscp->path_list */ - char path[PATH_MAX]; /* file path */ - size_t size; /* size of file on this path */ - mode_t mode; /* permission */ + char *path; /* file path */ + size_t size; /* size of file on this path */ + mode_t mode; /* permission */ - char dst_path[PATH_MAX]; /* copy dst path */ + char *dst_path; /* copy dst path */ int state; lock lock; @@ -93,6 +93,9 @@ struct path_resolve_args { int walk_src_path(sftp_session src_sftp, const char *src_path, 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 */ int copy_chunk(FILE *msg_fp, struct chunk *c, sftp_session src_sftp, sftp_session dst_sftp, |