In practice, the majority of paths do not have any utf8 character that needs the canonicalization. Lazily call iconv_open() and iconv_close() to avoid unnecessary overhead. Signed-off-by: Junio C Hamano <gitster@xxxxxxxxx> --- * This is not even compile tested, so it needs testing and benchmarking, as I do not even know how costly the calls to open/close are when we do not have to call iconv() itself. This was brought up by Linus (Cc'ed) in http://goo.gl/INWVc compat/precompose_utf8.c | 24 ++++++++++++++++++------ compat/precompose_utf8.h | 1 + 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c index d40d1b3..63ce89f 100644 --- a/compat/precompose_utf8.c +++ b/compat/precompose_utf8.c @@ -67,7 +67,7 @@ void probe_utf8_pathname_composition(char *path, int len) void precompose_argv(int argc, const char **argv) { - int i = 0; + int i; const char *oldarg; char *newarg; iconv_t ic_precompose; @@ -75,11 +75,19 @@ void precompose_argv(int argc, const char **argv) if (precomposed_unicode != 1) return; + /* Avoid iconv_open()/iconv_close() if there is nothing to convert */ + for (i = 0; i < argc; i++) { + if (has_utf8(argv[i], (size_t)-1, NULL)) + break; + } + if (i < argc) + return; + ic_precompose = iconv_open(repo_encoding, path_encoding); if (ic_precompose == (iconv_t) -1) return; - while (i < argc) { + for (i = 0; i < argc; i++) { size_t namelen; oldarg = argv[i]; if (has_utf8(oldarg, (size_t)-1, &namelen)) { @@ -87,7 +95,6 @@ void precompose_argv(int argc, const char **argv) if (newarg) argv[i] = newarg; } - i++; } iconv_close(ic_precompose); } @@ -106,8 +113,7 @@ PREC_DIR *precompose_utf8_opendir(const char *dirname) return NULL; } else { int ret_errno = errno; - prec_dir->ic_precompose = iconv_open(repo_encoding, path_encoding); - /* if iconv_open() fails, die() in readdir() if needed */ + prec_dir->iconv_opened = 0; errno = ret_errno; } @@ -136,6 +142,11 @@ struct dirent_prec_psx *precompose_utf8_readdir(PREC_DIR *prec_dir) prec_dir->dirent_nfc->d_type = res->d_type; if ((precomposed_unicode == 1) && has_utf8(res->d_name, (size_t)-1, NULL)) { + if (!prec_dir->iconv_opened) { + prec_dir->ic_precompose = + iconv_open(repo_encoding, path_encoding); + prec_dir->iconv_opened = 1; + } if (prec_dir->ic_precompose == (iconv_t)-1) { die("iconv_open(%s,%s) failed, but needed:\n" " precomposed unicode is not supported.\n" @@ -181,7 +192,8 @@ int precompose_utf8_closedir(PREC_DIR *prec_dir) int ret_errno; ret_value = closedir(prec_dir->dirp); ret_errno = errno; - if (prec_dir->ic_precompose != (iconv_t)-1) + if (prec->dir->iconv_opened && + (prec_dir->ic_precompose != (iconv_t)-1)) iconv_close(prec_dir->ic_precompose); free(prec_dir->dirent_nfc); free(prec_dir); diff --git a/compat/precompose_utf8.h b/compat/precompose_utf8.h index 3b73585..8de485e 100644 --- a/compat/precompose_utf8.h +++ b/compat/precompose_utf8.h @@ -22,6 +22,7 @@ typedef struct dirent_prec_psx { typedef struct { iconv_t ic_precompose; + int iconv_opened; DIR *dirp; struct dirent_prec_psx *dirent_nfc; } PREC_DIR; -- 1.7.12.rc1.43.g3fa3e7e -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html