On Fri, 11 Nov 2016 21:14:37 +0000, Jun Wu wrote: > # HG changeset patch > # User Jun Wu <qu...@fb.com> > # Date 1478898677 0 > # Fri Nov 11 21:11:17 2016 +0000 > # Node ID 4ccb6bcaf25a741d3a0d8abd6c674573ef76069a > # Parent 98761d64eaaf67f3bdb99f3f80a57910e2624b78 > # Available At https://bitbucket.org/quark-zju/hg-draft > # hg pull https://bitbucket.org/quark-zju/hg-draft -r > 4ccb6bcaf25a > osutil: implement setprocname to set process title for some platforms
Seems fine. We can't guarantee argv[i] is null terminated for all i, but that seems less dangerous since the last argv[i] always has '\0'. A few nits. > --- a/mercurial/osutil.c > +++ b/mercurial/osutil.c > @@ -728,4 +728,59 @@ bail: > > #endif /* CMSG_LEN */ > + > +/* Check what setprocname method we can use: > + * a. use setproctitle if it's available - works in FreeBSD > + * b. rewrite **argv buffer in place - works in Linux and OS X > + * Note: for "b.", we need Python 2, because Python 3's Py_GetArgcArgv > returns > + * the copied wchar_t **argv, not the original char **argv. */ > +#if defined(HAVE_SETPROCTITLE) > +#define setprocname_method 'a' > +#elif (defined(__linux__) || defined(__APPLE__)) && PY_MAJOR_VERSION == 2 > +#define setprocname_method 'b' > +#else > +#undef setprocname_method > +#endif Lowercase macro name and char-type value seem not common. Can you change them to old-school macros such as SETPROCNAME_USE_SETPROCTITLE? > +#ifdef setprocname_method > +static PyObject *setprocname(PyObject *self, PyObject *args) > +{ > + const char *name = NULL; > + if (!PyArg_ParseTuple(args, "s", &name)) > + return NULL; > + > +#if 'a' == setprocname_method > + setproctitle("%s", name); > +#elif 'b' == setprocname_method > + static char *argvstart = NULL; > + static size_t argvsize = 0; Strictly speaking, these declarations should be moved to the block head. (But almost all modern compilers but for MSVC would allow mixed declarations.) > + if (argvstart == NULL) { > + int argc = 0, i; > + char **argv = NULL; > + extern void Py_GetArgcArgv(int *argc, char ***argv); > + Py_GetArgcArgv(&argc, &argv); > + > + /* Check the memory we can use. Typically, argv[i] and > + * argv[i+1] are separated by a NULL character. */ > + if (argc > 0) { > + argvstart = argv[0]; > + argvsize = strlen(argv[0]) + 1; > + for (i = 1; i < argc; ++i) { > + if (argv[i] == argvstart + argvsize) > + argvsize += strlen(argv[i]) + 1; > + } > + } Perhaps this loop can start with argvstart = argv[0], argvsize = 0, i = 0. > + } > + > + if (argvstart && argvsize > 1) { > + int n = snprintf(argvstart, argvsize - 1, "%s", name); IIRC, snprintf() takes size including the last null byte and null termination is guaranteed. > + if (n >= 0 && (size_t)n < argvsize) > + memset(argvstart + n, 0, argvsize - n); > + } > +#endif _______________________________________________ Mercurial-devel mailing list Mercurial-devel@mercurial-scm.org https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel