[Uim] reliability fix: uim-fep.c
Iwata
iwata at quasiquote.org
Thu Mar 29 09:57:02 EEST 2007
Hi,
I wrote a patch same as r4437 (mkdir ~/.uim.d/fep).
This patch includes replacing atoi -> strtonum.
Thanks.
diff -rN -u old-uim/configure.ac new-uim/configure.ac
--- old-uim/configure.ac Thu Mar 29 15:52:57 2007
+++ new-uim/configure.ac Thu Mar 29 15:52:57 2007
@@ -347,7 +347,7 @@
AC_CHECK_FUNCS([asprintf vasprintf])
# C99 functions
AC_CHECK_FUNCS([snprintf vsnprintf])
-AC_REPLACE_FUNCS([getpeereid strsep setenv unsetenv strlcpy strlcat])
+AC_REPLACE_FUNCS([getpeereid strsep setenv unsetenv strlcpy strlcat strtonum])
AC_CHECK_FUNCS([getpid stat mkdir chmod])
AC_CHECK_FUNCS([execv execvp])
AC_CHECK_FUNCS([isascii])
diff -rN -u old-uim/fep/uim-fep.c new-uim/fep/uim-fep.c
--- old-uim/fep/uim-fep.c Thu Mar 29 15:52:57 2007
+++ new-uim/fep/uim-fep.c Thu Mar 29 15:52:57 2007
@@ -223,6 +223,58 @@
return engine;
}
+static uim_bool
+check_dir(const char *dir)
+{
+ struct stat st;
+
+ if (dir == NULL)
+ return UIM_FALSE;
+
+ if (stat(dir, &st) < 0)
+ return (mkdir(dir, 0700) < 0) ? UIM_FALSE : UIM_TRUE;
+ else {
+ mode_t mode = S_IFDIR | S_IRUSR | S_IWUSR | S_IXUSR;
+ return ((st.st_mode & mode) == mode) ? UIM_TRUE : UIM_FALSE;
+ }
+}
+
+static char *
+get_ud_path(void)
+{
+ char *path, *home = NULL;
+ struct passwd *pw;
+
+ pw = getpwuid(getuid());
+ if (pw)
+ home = pw->pw_dir;
+
+ if (!home && !uim_helper_is_setugid())
+ home = getenv("HOME");
+
+ if (!home)
+ return NULL;
+
+ if (asprintf(&path, "%s/.uim.d", home) == -1)
+ return NULL; /* XXX: fatal */
+
+ if (!check_dir(path)) {
+ free(path);
+ return NULL;
+ }
+ free(path);
+
+ if (asprintf(&path, "%s/.uim.d/fep", home) == -1)
+ return NULL; /* XXX: fatal */
+
+ if (!check_dir(path)) {
+ free(path);
+ return NULL;
+ }
+
+ return path;
+}
+
int main(int argc, char **argv)
{
/* command will be execed on pty */
@@ -230,7 +282,7 @@
char *engine;
char *sock_path = NULL; /* Socket for backtick */
int gnu_screen = FALSE;
- char *env_buf;
+ char pid_str[30];
struct attribute_tag attr_uim = {
FALSE, /* underline */
FALSE, /* standout */
@@ -241,10 +293,11 @@
};
FILE *fp;
const char *suffix = NULL;
- const char *tmp_dir;
+ const char *uim_dir;
const char *sty_str;
const char *win_str;
struct stat stat_buf;
+ const char *errstr;
int op;
@@ -332,7 +385,11 @@
break;
case 'w':
- g_opt.statusline_width = atoi(optarg);
+ g_opt.statusline_width = strtonum(optarg, 1, 10000, &errstr);
+ if (errstr) {
+ printf("'%s': %s", optarg, errstr);
+ return EXIT_FAILURE;
+ }
if (g_opt.statusline_width <= 0) {
usage();
return EXIT_FAILURE;
@@ -408,8 +465,9 @@
tcgetattr(g_win_in, &s_save_tios);
setupterm(NULL, g_win_out, NULL);
- if ((tmp_dir = getenv("TMP")) == NULL) {
- tmp_dir = "/tmp";
+ if ((uim_dir = get_ud_path()) == NULL) {
+ sendline("uim-fep cannot make directory");
+ return EXIT_FAILURE;
}
sty_str = getenv("STY");
@@ -419,65 +477,62 @@
puts("STY and WINDOW are not defined");
return EXIT_FAILURE;
}
- snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/uim-fep-getmode-%s-%s", tmp_dir, sty_str, win_str);
- snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/uim-fep-setmode-%s-%s", tmp_dir, sty_str, win_str);
+ snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/getmode-%s-%s", uim_dir, sty_str, win_str);
+ snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/setmode-%s-%s", uim_dir, sty_str, win_str);
if (stat(s_path_getmode, &stat_buf) == 0 || stat(s_path_setmode, &stat_buf) == 0) {
char msg[100];
- snprintf(msg, 100, "uim-fep is already running on window %s", win_str);
+ snprintf(msg, sizeof(msg), "uim-fep is already running on window %s", win_str);
sendline(msg);
return EXIT_FAILURE;
}
if (suffix != NULL) {
- snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/uim-fep-getmode-%s", tmp_dir, suffix);
- snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/uim-fep-setmode-%s", tmp_dir, suffix);
+ snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/getmode-%s", uim_dir, suffix);
+ snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/setmode-%s", uim_dir, suffix);
} else {
- snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/uim-fep-getmode-%s-%s-screen", tmp_dir, sty_str, win_str);
- snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/uim-fep-setmode-%s-%s-screen", tmp_dir, sty_str, win_str);
+ snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/getmode-%s-%s-screen", uim_dir, sty_str, win_str);
+ snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/setmode-%s-%s-screen", uim_dir, sty_str, win_str);
}
} else {
if (sty_str != NULL && win_str != NULL) {
- snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/uim-fep-getmode-%s-%s-screen", tmp_dir, sty_str, win_str);
- snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/uim-fep-setmode-%s-%s-screen", tmp_dir, sty_str, win_str);
+ snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/getmode-%s-%s-screen", uim_dir, sty_str, win_str);
+ snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/setmode-%s-%s-screen", uim_dir, sty_str, win_str);
if (stat(s_path_getmode, &stat_buf) == 0 || stat(s_path_setmode, &stat_buf) == 0) {
printf("uim-fep is already running on window %s as filter\n", win_str);
return EXIT_FAILURE;
}
if (suffix != NULL) {
- snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/uim-fep-getmode-%s", tmp_dir, suffix);
- snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/uim-fep-setmode-%s", tmp_dir, suffix);
+ snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/getmode-%s", uim_dir, suffix);
+ snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/setmode-%s", uim_dir, suffix);
} else {
- snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/uim-fep-getmode-%s-%s", tmp_dir, sty_str, win_str);
- snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/uim-fep-setmode-%s-%s", tmp_dir, sty_str, win_str);
+ snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/getmode-%s-%s", uim_dir, sty_str, win_str);
+ snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/setmode-%s-%s", uim_dir, sty_str, win_str);
}
} else {
if (suffix != NULL) {
- snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/uim-fep-getmode-%s", tmp_dir, suffix);
- snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/uim-fep-setmode-%s", tmp_dir, suffix);
+ snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/getmode-%s", uim_dir, suffix);
+ snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/setmode-%s", uim_dir, suffix);
} else {
int file_suffix = 1;
int pid = getpid();
- snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/uim-fep-getmode-%d", tmp_dir, pid);
- snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/uim-fep-setmode-%d", tmp_dir, pid);
+ snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/getmode-%d", uim_dir, pid);
+ snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/setmode-%d", uim_dir, pid);
while (stat(s_path_getmode, &stat_buf) == 0 || stat(s_path_setmode, &stat_buf) == 0) {
- snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/uim-fep-getmode-%d-%d", tmp_dir, pid, file_suffix);
- snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/uim-fep-setmode-%d-%d", tmp_dir, pid, file_suffix);
+ snprintf(s_path_getmode, sizeof(s_path_getmode), "%s/getmode-%d-%d", uim_dir, pid, file_suffix);
+ snprintf(s_path_setmode, sizeof(s_path_setmode), "%s/setmode-%d-%d", uim_dir, pid, file_suffix);
file_suffix++;
}
}
}
}
- env_buf = malloc(30);
- snprintf(env_buf, 30, "UIM_FEP_PID=%d", getpid());
- putenv(env_buf);
+ snprintf(pid_str, sizeof(pid_str), "%d", getpid());
+ setenv("UIM_FEP_PID", pid_str, 1);
if ((fp = fopen(s_path_getmode, "wt")) != NULL) {
fclose(fp);
unlink(s_path_getmode);
- env_buf = malloc(strlen("UIM_FEP_GETMODE=") + strlen(s_path_getmode) + 1);
- sprintf(env_buf, "UIM_FEP_GETMODE=%s", s_path_getmode);
- putenv(env_buf);
+ setenv("UIM_FEP_GETMODE", s_path_getmode, 1);
} else {
s_path_getmode[0] = '\0';
}
@@ -485,9 +540,7 @@
unlink(s_path_setmode);
if (mkfifo(s_path_setmode, 0600) != -1) {
unlink(s_path_setmode);
- env_buf = malloc(strlen("UIM_FEP_SETMODE=") + strlen(s_path_setmode) + 1);
- sprintf(env_buf, "UIM_FEP_SETMODE=%s", s_path_setmode);
- putenv(env_buf);
+ setenv("UIM_FEP_SETMODE", s_path_setmode, 1);
} else {
s_path_setmode[0] = '\0';
s_setmode_fd = -1;
@@ -730,6 +783,7 @@
int nfd;
char *_clear_screen = cut_padding(clear_screen);
char *_clr_eos = cut_padding(clr_eos);
+ const char *errstr;
if (g_win_in > s_master) {
if (g_win_in > s_setmode_fd) {
@@ -830,8 +884,10 @@
for (start = end; start > 0 && isdigit((unsigned char)buf[start - 1]); --start);
buf[end + 1] = '\0';
- mode = atoi(&buf[start]);
- if (mode != uim_get_current_mode(g_context)) {
+ mode = strtonum(&buf[start], 0, uim_get_nr_modes(g_context) - 1, &errstr);
+ if (errstr) {
+ debug2(("'%s': %s\n", &buf[start], errstr));
+ } else if (mode != uim_get_current_mode(g_context)) {
debug2(("mode change %d\n", mode));
uim_set_mode(g_context, mode);
/* callbacks_set_mode(uim_get_current_mode(g_context)); */
diff -rN -u old-uim/replace/Makefile.am new-uim/replace/Makefile.am
--- old-uim/replace/Makefile.am Thu Mar 29 15:52:57 2007
+++ new-uim/replace/Makefile.am Thu Mar 29 15:52:57 2007
@@ -1,2 +1,2 @@
noinst_LTLIBRARIES = libreplace.la
-libreplace_la_SOURCES = strsep.c getpeereid.c setenv.c os_dep.h strlcpy.c strlcat.c fake-rfc2553.c fake-rfc2553.h
+libreplace_la_SOURCES = strsep.c getpeereid.c setenv.c os_dep.h strlcpy.c strlcat.c fake-rfc2553.c fake-rfc2553.h bsd-asprintf.c strtonum.c
diff -rN -u old-uim/replace/bsd-asprintf.c new-uim/replace/bsd-asprintf.c
--- old-uim/replace/bsd-asprintf.c Thu Jan 1 09:00:00 1970
+++ new-uim/replace/bsd-asprintf.c Thu Mar 29 15:52:57 2007
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2004 Darren Tucker.
+ *
+ * Based originally on asprintf.c from OpenBSD:
+ * Copyright (c) 1997 Todd C. Miller <Todd.Miller at courtesan.com>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <config.h>
+
+#ifndef HAVE_VASPRINTF
+
+#include <errno.h>
+#include <stdarg.h>
+#include <stdlib.h>
+
+#ifndef VA_COPY
+# ifdef HAVE_VA_COPY
+# define VA_COPY(dest, src) va_copy(dest, src)
+# else
+# ifdef HAVE___VA_COPY
+# define VA_COPY(dest, src) __va_copy(dest, src)
+# else
+# define VA_COPY(dest, src) (dest) = (src)
+# endif
+# endif
+#endif
+
+#define INIT_SZ 128
+
+int vasprintf(char **str, const char *fmt, va_list ap)
+{
+ int ret = -1;
+ va_list ap2;
+ char *string, *newstr;
+ size_t len;
+
+ VA_COPY(ap2, ap);
+ if ((string = malloc(INIT_SZ)) == NULL)
+ goto fail;
+
+ ret = vsnprintf(string, INIT_SZ, fmt, ap2);
+ if (ret >= 0 && ret < INIT_SZ) { /* succeeded with initial alloc */
+ *str = string;
+ } else if (ret == INT_MAX) { /* shouldn't happen */
+ goto fail;
+ } else { /* bigger than initial, realloc allowing for nul */
+ len = (size_t)ret + 1;
+ if ((newstr = realloc(string, len)) == NULL) {
+ free(string);
+ goto fail;
+ } else {
+ va_end(ap2);
+ VA_COPY(ap2, ap);
+ ret = vsnprintf(newstr, len, fmt, ap2);
+ if (ret >= 0 && (size_t)ret < len) {
+ *str = newstr;
+ } else { /* failed with realloc'ed string, give up */
+ free(newstr);
+ goto fail;
+ }
+ }
+ }
+ va_end(ap2);
+ return (ret);
+
+fail:
+ *str = NULL;
+ errno = ENOMEM;
+ va_end(ap2);
+ return (-1);
+}
+#endif
+
+#ifndef HAVE_ASPRINTF
+int asprintf(char **str, const char *fmt, ...)
+{
+ va_list ap;
+ int ret;
+
+ *str = NULL;
+ va_start(ap, fmt);
+ ret = vasprintf(str, fmt, ap);
+ va_end(ap);
+
+ return ret;
+}
+#endif
diff -rN -u old-uim/replace/os_dep.h new-uim/replace/os_dep.h
--- old-uim/replace/os_dep.h Thu Mar 29 15:52:57 2007
+++ new-uim/replace/os_dep.h Thu Mar 29 15:52:57 2007
@@ -47,6 +47,9 @@
#if HAVE_SYS_TYPES_H
#include <sys/types.h>
#endif
+#if HAVE_STDARG_H
+#include <stdarg.h>
+#endif
#include <limits.h>
#ifdef __cplusplus
@@ -85,6 +88,21 @@
#endif
#include "fake-rfc2553.h"
+
+#ifndef HAVE_VASPRINTF
+#define vasprintf uim_vasprintf
+int vasprintf(char **ret, const char *format, va_list ap);
+#endif
+
+#ifndef HAVE_ASPRINTF
+#define asprintf uim_asprintf
+int asprintf(char **ret, const char *format, ...);
+#endif
+
+#ifndef HAVE_STRTONUM
+#define strtonum uim_strtonum
+long long strtonum(const char *numstr, long long minval, long long maxval, const char **errstrp)
+#endif
#ifdef __cplusplus
}
diff -rN -u old-uim/replace/strtonum.c new-uim/replace/strtonum.c
--- old-uim/replace/strtonum.c Thu Jan 1 09:00:00 1970
+++ new-uim/replace/strtonum.c Thu Mar 29 15:52:57 2007
@@ -0,0 +1,72 @@
+/* $OpenBSD: strtonum.c,v 1.6 2004/08/03 19:38:01 millert Exp $ */
+
+/*
+ * Copyright (c) 2004 Ted Unangst and Todd Miller
+ * All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/* OPENBSD ORIGINAL: lib/libc/stdlib/strtonum.c */
+
+#include <config.h>
+
+#ifndef HAVE_STRTONUM
+#include <stdlib.h>
+#include <limits.h>
+#include <errno.h>
+
+#define INVALID 1
+#define TOOSMALL 2
+#define TOOLARGE 3
+
+long long
+strtonum(const char *numstr, long long minval, long long maxval,
+ const char **errstrp)
+{
+ long long ll = 0;
+ char *ep;
+ int error = 0;
+ struct errval {
+ const char *errstr;
+ int err;
+ } ev[4] = {
+ { NULL, 0 },
+ { "invalid", EINVAL },
+ { "too small", ERANGE },
+ { "too large", ERANGE },
+ };
+
+ ev[0].err = errno;
+ errno = 0;
+ if (minval > maxval)
+ error = INVALID;
+ else {
+ ll = strtoll(numstr, &ep, 10);
+ if (numstr == ep || *ep != '\0')
+ error = INVALID;
+ else if ((ll == LLONG_MIN && errno == ERANGE) || ll < minval)
+ error = TOOSMALL;
+ else if ((ll == LLONG_MAX && errno == ERANGE) || ll > maxval)
+ error = TOOLARGE;
+ }
+ if (errstrp != NULL)
+ *errstrp = ev[error].errstr;
+ errno = ev[error].err;
+ if (error)
+ ll = 0;
+
+ return (ll);
+}
+
+#endif /* HAVE_STRTONUM */
More information about the uim
mailing list