pax_global_header00006660000000000000000000000064114027166660014523gustar00rootroot0000000000000052 comment=421389632bb4f1f7ac28c0b08b715210b2d57a61 python-setproctitle-1.0.1/000077500000000000000000000000001140271666600155625ustar00rootroot00000000000000python-setproctitle-1.0.1/COPYRIGHT000066400000000000000000000027141140271666600170610ustar00rootroot00000000000000Copyright (c) 2009-2010, Daniele Varrazzo All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. * The name of Daniele Varrazzo may not be used to endorse or promote products derived from this software without specific prior written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. python-setproctitle-1.0.1/HISTORY000066400000000000000000000016641140271666600166550ustar00rootroot00000000000000Releases history ---------------- Version 1.0.1 ~~~~~~~~~~~~~ - ``setproctitle()`` works even when Python messes up with argv, e.g. when run with the -m option. Version 1.0 ~~~~~~~~~~~ No major change since the previous version. The module has been heavily used in production environment without any problem reported, so it's time to declare it stable. Version 0.4 ~~~~~~~~~~~ - Module works on BSD (tested on FreeBSD 7.2). - Module works on Windows. Many thanks to `Develer`_ for providing a neat `GCC package for Windows with Python integration`__ that made the Windows porting painless. .. _Develer: http://www.develer.com/ .. __: http://www.develer.com/oss/GccWinBinaries Version 0.3 ~~~~~~~~~~~ - Module works on Mac OS X 10.2. Reported working on OS X 10.6 too. Version 0.2 ~~~~~~~~~~~ - Added ``prctl()`` call on Linux >= 2.6.9 to update ``/proc/self/status``. Version 0.1 ~~~~~~~~~~~ - Initial public release. python-setproctitle-1.0.1/PKG-INFO000066400000000000000000000124211140271666600166570ustar00rootroot00000000000000Metadata-Version: 1.0 Name: setproctitle Version: 1.0.1 Summary: Allow customization of the process title. Home-page: http://code.google.com/p/py-setproctitle/ Author: Daniele Varrazzo Author-email: daniele.varrazzo@gmail.com License: BSD Download-URL: http://pypi.python.org/pypi/setproctitle/ Description: A ``setproctitle`` implementation for Python ============================================ :author: Daniele Varrazzo The library allows a process to change its title (as displayed by system tools such as ``ps`` and ``top``). Changing the title is mostly useful in multi-process systems, for example when a master process is forked: changing the children's title allows to identify the task each process is busy with. The technique is used by PostgreSQL_ and the `OpenSSH Server`_ for example. The procedure is hardly portable across different systems. PostgreSQL provides a good `multi-platform implementation`__: this module is a Python wrapper around PostgreSQL code. .. _PostgreSQL: http://www.postgresql.org .. _OpenSSH Server: http://www.openssh.com/ .. __: http://doxygen.postgresql.org/ps__status_8c-source.html Installation ------------ You can use ``easy_install`` to install the module: to perform a system-wide installation use:: sudo easy_install setproctitle If you are an unprivileged user or you want to limit installation to a local environment, you can use the command:: easy_install -d /target/path setproctitle Notice that ``easy_install`` requires ``/target/path`` to be in your ``PYTHONPATH``. Module content -------------- The module exports the following functions: ``setproctitle(title)`` Set *title* as the title for the current process. ``getproctitle()`` Return the current process title. Module status ------------- The module can be currently compiled and effectively used on the following platforms: - GNU/Linux - BSD - MacOS X - Windows Notice that on Windows there is no way to change the process string: what the module does is to create a *Named Object* whose value can be read using a tool such as `Process Explorer`_ (contribution of a more useful tool to be used together with ``setproctitle`` would be well accepted). The module can probably work on HP-UX, but I haven't found any to test with. It is unlikely that it can work on Solaris instead. .. _Process Explorer: http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx Other known implementations and discussions ------------------------------------------- - `procname`_: a module exposing the same functionality, but less portable and not well packaged. - `Issue 5672`_: where the introduction of such functionality into the stdlib is being discussed. .. _procname: http://code.google.com/p/procname/ .. _Issue 5672: http://bugs.python.org/issue5672 .. vim: set filetype=rst: Releases history ---------------- Version 1.0.1 ~~~~~~~~~~~~~ - ``setproctitle()`` works even when Python messes up with argv, e.g. when run with the -m option. Version 1.0 ~~~~~~~~~~~ No major change since the previous version. The module has been heavily used in production environment without any problem reported, so it's time to declare it stable. Version 0.4 ~~~~~~~~~~~ - Module works on BSD (tested on FreeBSD 7.2). - Module works on Windows. Many thanks to `Develer`_ for providing a neat `GCC package for Windows with Python integration`__ that made the Windows porting painless. .. _Develer: http://www.develer.com/ .. __: http://www.develer.com/oss/GccWinBinaries Version 0.3 ~~~~~~~~~~~ - Module works on Mac OS X 10.2. Reported working on OS X 10.6 too. Version 0.2 ~~~~~~~~~~~ - Added ``prctl()`` call on Linux >= 2.6.9 to update ``/proc/self/status``. Version 0.1 ~~~~~~~~~~~ - Initial public release. Platform: GNU/Linux Platform: BSD Platform: MacOS X Platform: Windows Classifier: Development Status :: 5 - Production/Stable Classifier: Intended Audience :: Developers Classifier: License :: OSI Approved :: BSD License Classifier: Programming Language :: C Classifier: Programming Language :: Python Classifier: Operating System :: POSIX :: Linux Classifier: Operating System :: POSIX :: BSD Classifier: Operating System :: MacOS :: MacOS X Classifier: Operating System :: Microsoft :: Windows Classifier: Topic :: Software Development python-setproctitle-1.0.1/README000066400000000000000000000047511140271666600164510ustar00rootroot00000000000000A ``setproctitle`` implementation for Python ============================================ :author: Daniele Varrazzo The library allows a process to change its title (as displayed by system tools such as ``ps`` and ``top``). Changing the title is mostly useful in multi-process systems, for example when a master process is forked: changing the children's title allows to identify the task each process is busy with. The technique is used by PostgreSQL_ and the `OpenSSH Server`_ for example. The procedure is hardly portable across different systems. PostgreSQL provides a good `multi-platform implementation`__: this module is a Python wrapper around PostgreSQL code. .. _PostgreSQL: http://www.postgresql.org .. _OpenSSH Server: http://www.openssh.com/ .. __: http://doxygen.postgresql.org/ps__status_8c-source.html Installation ------------ You can use ``easy_install`` to install the module: to perform a system-wide installation use:: sudo easy_install setproctitle If you are an unprivileged user or you want to limit installation to a local environment, you can use the command:: easy_install -d /target/path setproctitle Notice that ``easy_install`` requires ``/target/path`` to be in your ``PYTHONPATH``. Module content -------------- The module exports the following functions: ``setproctitle(title)`` Set *title* as the title for the current process. ``getproctitle()`` Return the current process title. Module status ------------- The module can be currently compiled and effectively used on the following platforms: - GNU/Linux - BSD - MacOS X - Windows Notice that on Windows there is no way to change the process string: what the module does is to create a *Named Object* whose value can be read using a tool such as `Process Explorer`_ (contribution of a more useful tool to be used together with ``setproctitle`` would be well accepted). The module can probably work on HP-UX, but I haven't found any to test with. It is unlikely that it can work on Solaris instead. .. _Process Explorer: http://technet.microsoft.com/en-us/sysinternals/bb896653.aspx Other known implementations and discussions ------------------------------------------- - `procname`_: a module exposing the same functionality, but less portable and not well packaged. - `Issue 5672`_: where the introduction of such functionality into the stdlib is being discussed. .. _procname: http://code.google.com/p/procname/ .. _Issue 5672: http://bugs.python.org/issue5672 .. vim: set filetype=rst: python-setproctitle-1.0.1/setup.py000066400000000000000000000055121140271666600172770ustar00rootroot00000000000000#!/usr/bin/env python """ setproctitle setup script. Copyright (c) 2009-2010 Daniele Varrazzo """ VERSION = '1.0.1' import os import re import sys from distutils.core import setup, Extension define_macros={} define_macros['SPT_VERSION'] = VERSION if sys.platform == 'linux2': try: linux_version = map(int, re.search("[.0-9]+", os.popen("uname -r").read()) .group().split(".")[:3]) except: pass else: if linux_version >= [2, 6, 9]: define_macros['HAVE_SYS_PRCTL_H'] = 1 elif sys.platform == 'darwin': # __darwin__ symbol is not defined; __APPLE__ is instead. define_macros['__darwin__'] = 1 elif 'bsd' in sys.platform: # OMG, how many of them are? # Old BSD versions don't have setproctitle # TODO: not tested on an "old BSD" if 0 == os.spawnlp(os.P_WAIT, 'grep', 'grep', '-q', 'setproctitle', '/usr/include/unistd.h'): define_macros['HAVE_SETPROCTITLE'] = 1 else: define_macros['HAVE_PS_STRING'] = 1 # NOTE: the library may work on HP-UX using pstat # thus setting define_macros['HAVE_SYS_PSTAT_H'] # see http://www.noc.utoronto.ca/~mikep/unix/HPTRICKS # But I have none handy to test with. mod_spt = Extension('setproctitle', define_macros=define_macros.items(), sources = [ 'src/setproctitle.c', 'src/spt_status.c', 'src/strlcpy.c', # TODO: not needed on some platform ]) # patch distutils if it can't cope with the "classifiers" or # "download_url" keywords if sys.version < '2.2.3': from distutils.dist import DistributionMetadata DistributionMetadata.classifiers = None DistributionMetadata.download_url = None # Try to include the long description in the setup kwargs = {} try: kwargs['long_description'] = ( open('README').read() + '\n' +open('HISTORY').read()) except: pass setup( name = 'setproctitle', description = 'Allow customization of the process title.', version = VERSION, author = 'Daniele Varrazzo', author_email = 'daniele.varrazzo@gmail.com', url = 'http://code.google.com/p/py-setproctitle/', download_url = 'http://pypi.python.org/pypi/setproctitle/', license = 'BSD', platforms = ['GNU/Linux', 'BSD', 'MacOS X', 'Windows'], classifiers = filter(None, map(str.strip, """ Development Status :: 5 - Production/Stable Intended Audience :: Developers License :: OSI Approved :: BSD License Programming Language :: C Programming Language :: Python Operating System :: POSIX :: Linux Operating System :: POSIX :: BSD Operating System :: MacOS :: MacOS X Operating System :: Microsoft :: Windows Topic :: Software Development """.splitlines())), ext_modules = [mod_spt], **kwargs) python-setproctitle-1.0.1/src/000077500000000000000000000000001140271666600163515ustar00rootroot00000000000000python-setproctitle-1.0.1/src/c.h000066400000000000000000000012211140271666600167400ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * c.h * A few fundamental C definitions. * * Copyright (c) 2009-2010 Daniele Varrazzo *------------------------------------------------------------------------- */ #ifndef C_H #define C_H #ifndef __cplusplus #ifndef bool typedef char bool; #endif #ifndef true #define true ((bool) 1) #endif #ifndef false #define false ((bool) 0) #endif #endif /* not C++ */ #include #if !HAVE_DECL_STRLCPY extern size_t strlcpy(char *dst, const char *src, size_t siz); #endif #ifdef WIN32 #include #endif #endif /* C_H */ python-setproctitle-1.0.1/src/setproctitle.c000066400000000000000000000105541140271666600212430ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * setproctitle.c * Python extension module to update and read the process title. * * Copyright (c) 2009-2010 Daniele Varrazzo * * The module allows Python code to access the functions get_ps_display() * and set_ps_display(). The process title initialization (functions * save_ps_display_args() and init_ps_display()) are called at module * initialization. *------------------------------------------------------------------------- */ #include "Python.h" #include "spt_status.h" #ifndef SPT_VERSION #define SPT_VERSION unknown #endif /* defined in Modules/main.c but not publically declared */ void Py_GetArgcArgv(int *argc, char ***argv); /* macro trick to stringify a macro expansion */ #define xstr(s) str(s) #define str(s) #s /* ----------------------------------------------------- */ static PyObject *spt_version; static char spt_setproctitle__doc__[] = "Change the process title." ; static PyObject * spt_setproctitle(PyObject *self /* Not used */, PyObject *args) { const char *title; if (!PyArg_ParseTuple(args, "s", &title)) return NULL; set_ps_display(title, true); Py_INCREF(Py_None); return Py_None; } static char spt_getproctitle__doc__[] = "Get the current process title." ; static PyObject * spt_getproctitle(PyObject *self /* Not used */, PyObject *args) { if (!PyArg_ParseTuple(args, "")) return NULL; int tlen; const char *title; title = get_ps_display(&tlen); return Py_BuildValue("s#", title, tlen); } /* List of methods defined in the module */ static struct PyMethodDef spt_methods[] = { {"setproctitle", (PyCFunction)spt_setproctitle, METH_VARARGS, spt_setproctitle__doc__}, {"getproctitle", (PyCFunction)spt_getproctitle, METH_VARARGS, spt_getproctitle__doc__}, {NULL, (PyCFunction)NULL, 0, NULL} /* sentinel */ }; /* return a concatenated version of a strings vector * * Return newly allocated heap space: clean it up with free() */ static char * join_argv(int argc, char **argv) { /* Calculate the final string length */ int i; size_t len = 0; for (i = 0; i < argc; i++) { len += strlen(argv[i]) + 1; } char *buf = (char *)malloc(len); /* Copy the strings in the buffer joining with spaces */ char *dest = buf; char *src; for (i = 0; i < argc; i++) { src = argv[i]; while (*src) { *dest++ = *src++; } *dest++ = ' '; } *--dest = '\x00'; return buf; } /* Return a copy of argv referring to the original arg area. * * python -m messes up with arg (issue #8): ensure to have a vector to the * original args or save_ps_display_args() will stop processing too soon. * * Return a buffer allocated with malloc: should be cleaned up with free() * (it is never released though). */ static char ** fix_argv(int argc, char **argv) { char **buf = (char **)malloc(argc * sizeof(char *)); int i; char *ptr = argv[0]; for (i = 0; i < argc; ++i) { buf[i] = ptr; ptr += strlen(ptr) + 1; } return buf; } /* Initialization function for the module (*must* be called initsetproctitle) */ static char setproctitle_module_documentation[] = "Allow customization of the process title." ; void initsetproctitle(void) { PyObject *m, *d; /* Create the module and add the functions */ m = Py_InitModule3("setproctitle", spt_methods, setproctitle_module_documentation); /* Add version string to the module*/ d = PyModule_GetDict(m); spt_version = PyString_FromString(xstr(SPT_VERSION)); PyDict_SetItemString(d, "__version__", spt_version); /* Initialize the process title */ #ifndef WIN32 int argc; char **argv; Py_GetArgcArgv(&argc, &argv); argv = fix_argv(argc, argv); save_ps_display_args(argc, argv); /* Set up the first title to fully initialize the code */ char *init_title = join_argv(argc, argv); init_ps_display(init_title); free(init_title); #else /* On Windows save_ps_display_args is a no-op * This is a good news, because Py_GetArgcArgv seems not usable. */ LPTSTR init_title = GetCommandLine(); init_ps_display(init_title); #endif /* Check for errors */ if (PyErr_Occurred()) Py_FatalError("can't initialize module setproctitle"); } python-setproctitle-1.0.1/src/spt_config.h000066400000000000000000000011251140271666600206540ustar00rootroot00000000000000/* Stub file: should be created in configuration phase */ /* This configuration was taken from an Ubuntu i386 installation. */ /* Define to 1 if you have the `setproctitle' function. */ /* #undef HAVE_SETPROCTITLE */ /* Define to 1 if the PS_STRINGS thing exists. */ /* #undef HAVE_PS_STRINGS */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_PSTAT_H */ /* Define to 1 if you have the header file. */ /* #undef HAVE_SYS_PRCTL_H */ /* Define to 1 if you have the declaration of `strlcpy', and to 0 if you don't. */ #define HAVE_DECL_STRLCPY 0 python-setproctitle-1.0.1/src/spt_status.c000066400000000000000000000275271140271666600207430ustar00rootroot00000000000000/*-------------------------------------------------------------------- * spt_status.c * * Routines to support changing the ps display of a process. * Mechanism differs wildly across platforms. * * Copyright (c) 2000-2009, PostgreSQL Global Development Group * various details abducted from various places * * This file was taken from PostgreSQL. The PostgreSQL copyright terms follow. *-------------------------------------------------------------------- */ /* * PostgreSQL Database Management System * (formerly known as Postgres, then as Postgres95) * * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * * Portions Copyright (c) 1994, The Regents of the University of California * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose, without fee, and without a written agreement * is hereby granted, provided that the above copyright notice and this * paragraph and the following two paragraphs appear in all copies. * * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING * LOST PROFITS, ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS * DOCUMENTATION, EVEN IF THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. * * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATIONS TO * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. */ #include "spt_config.h" #include #ifdef HAVE_SYS_PSTAT_H #include /* for HP-UX */ #endif #ifdef HAVE_PS_STRINGS #include /* for old BSD */ #include #endif #ifdef HAVE_SYS_PRCTL_H #include /* for Linux >= 2.6.9 */ #include #endif #if defined(__darwin__) #include #endif #include "spt_status.h" #include #include #include /* Darwin doesn't export environ */ #if defined(__darwin__) #define environ (*_NSGetEnviron()) #else extern char **environ; #endif bool update_process_title = true; /* * Alternative ways of updating ps display: * * PS_USE_SETPROCTITLE * use the function setproctitle(const char *, ...) * (newer BSD systems) * PS_USE_PSTAT * use the pstat(PSTAT_SETCMD, ) * (HPUX) * PS_USE_PS_STRINGS * assign PS_STRINGS->ps_argvstr = "string" * (some BSD systems) * PS_USE_CHANGE_ARGV * assign argv[0] = "string" * (some other BSD systems) * PS_USE_PRCTL * use prctl(PR_SET_NAME, ) * (Linux >= 2.6.9) * PS_USE_CLOBBER_ARGV * write over the argv and environment area * (most SysV-like systems) * PS_USE_WIN32 * push the string out as the name of a Windows event * PS_USE_NONE * don't update ps display * (This is the default, as it is safest.) */ #if defined(HAVE_SETPROCTITLE) #define PS_USE_SETPROCTITLE #elif defined(HAVE_PSTAT) && defined(PSTAT_SETCMD) #define PS_USE_PSTAT #elif defined(HAVE_PS_STRINGS) #define PS_USE_PS_STRINGS #elif (defined(BSD) || defined(__bsdi__) || defined(__hurd__)) && !defined(__darwin__) #define PS_USE_CHANGE_ARGV #elif defined(__linux__) || defined(_AIX) || defined(__sgi) || (defined(sun) && !defined(BSD)) || defined(ultrix) || defined(__ksr__) || defined(__osf__) || defined(__svr4__) || defined(__svr5__) || defined(__darwin__) #define PS_USE_CLOBBER_ARGV #elif defined(WIN32) #define PS_USE_WIN32 #else #define PS_USE_NONE #endif /* we use this strategy together with another one (probably PS_USE_CLOBBER_ARGV) */ #if defined(HAVE_SYS_PRCTL_H) && !defined(PS_USE_NONE) #define PS_USE_PRCTL #endif /* Different systems want the buffer padded differently */ #if defined(_AIX) || defined(__linux__) || defined(__svr4__) || defined(__darwin__) #define PS_PADDING '\0' #else #define PS_PADDING ' ' #endif #ifndef PS_USE_CLOBBER_ARGV /* all but one options need a buffer to write their ps line in */ #define PS_BUFFER_SIZE 256 static char ps_buffer[PS_BUFFER_SIZE]; static const size_t ps_buffer_size = PS_BUFFER_SIZE; #else /* PS_USE_CLOBBER_ARGV */ static char *ps_buffer; /* will point to argv area */ static size_t ps_buffer_size; /* space determined at run time */ static size_t last_status_len; /* use to minimize length of clobber */ #endif /* PS_USE_CLOBBER_ARGV */ static size_t ps_buffer_fixed_size; /* size of the constant prefix */ /* save the original argv[] location here */ static int save_argc; static char **save_argv; /* * Call this early in startup to save the original argc/argv values. * If needed, we make a copy of the original argv[] array to preserve it * from being clobbered by subsequent ps_display actions. * * (The original argv[] will not be overwritten by this routine, but may be * overwritten during init_ps_display. Also, the physical location of the * environment strings may be moved, so this should be called before any code * that might try to hang onto a getenv() result.) */ char ** save_ps_display_args(int argc, char **argv) { save_argc = argc; save_argv = argv; #if defined(PS_USE_CLOBBER_ARGV) /* * If we're going to overwrite the argv area, count the available space. * Also move the environment to make additional room. */ { char *end_of_area = NULL; char **new_environ; int i; /* * check for contiguous argv strings */ for (i = 0; i < argc; i++) { if (i == 0 || end_of_area + 1 == argv[i]) end_of_area = argv[i] + strlen(argv[i]); } if (end_of_area == NULL) /* probably can't happen? */ { ps_buffer = NULL; ps_buffer_size = 0; return argv; } /* * check for contiguous environ strings following argv */ for (i = 0; environ[i] != NULL; i++) { if (end_of_area + 1 == environ[i]) end_of_area = environ[i] + strlen(environ[i]); } ps_buffer = argv[0]; last_status_len = ps_buffer_size = end_of_area - argv[0]; /* * move the environment out of the way */ new_environ = (char **) malloc((i + 1) * sizeof(char *)); for (i = 0; environ[i] != NULL; i++) new_environ[i] = strdup(environ[i]); new_environ[i] = NULL; environ = new_environ; } #endif /* PS_USE_CLOBBER_ARGV */ #if defined(PS_USE_CHANGE_ARGV) || defined(PS_USE_CLOBBER_ARGV) /* * If we're going to change the original argv[] then make a copy for * argument parsing purposes. * * (NB: do NOT think to remove the copying of argv[], even though * postmaster.c finishes looking at argv[] long before we ever consider * changing the ps display. On some platforms, getopt() keeps pointers * into the argv array, and will get horribly confused when it is * re-called to analyze a subprocess' argument string if the argv storage * has been clobbered meanwhile. Other platforms have other dependencies * on argv[]. */ { char **new_argv; int i; new_argv = (char **) malloc((argc + 1) * sizeof(char *)); for (i = 0; i < argc; i++) new_argv[i] = strdup(argv[i]); new_argv[argc] = NULL; #if defined(__darwin__) /* * Darwin (and perhaps other NeXT-derived platforms?) has a static * copy of the argv pointer, which we may fix like so: */ *_NSGetArgv() = new_argv; #endif argv = new_argv; } #endif /* PS_USE_CHANGE_ARGV or PS_USE_CLOBBER_ARGV */ return argv; } /* * Call this once during subprocess startup to set the identification * values. At this point, the original argv[] array may be overwritten. */ void init_ps_display(const char *initial_str) { #ifndef PS_USE_NONE /* no ps display if you didn't call save_ps_display_args() */ if (!save_argv) return; #ifdef PS_USE_CLOBBER_ARGV /* If ps_buffer is a pointer, it might still be null */ if (!ps_buffer) return; #endif /* * Overwrite argv[] to point at appropriate space, if needed */ #ifdef PS_USE_CHANGE_ARGV save_argv[0] = ps_buffer; save_argv[1] = NULL; #endif /* PS_USE_CHANGE_ARGV */ #ifdef PS_USE_CLOBBER_ARGV { int i; /* make extra argv slots point at end_of_area (a NUL) */ for (i = 1; i < save_argc; i++) save_argv[i] = ps_buffer + ps_buffer_size; } #endif /* PS_USE_CLOBBER_ARGV */ /* * Make fixed prefix of ps display. */ ps_buffer[0] = '\0'; ps_buffer_fixed_size = strlen(ps_buffer); set_ps_display(initial_str, true); #endif /* not PS_USE_NONE */ } /* * Call this to update the ps status display to a fixed prefix plus an * indication of what you're currently doing passed in the argument. */ void set_ps_display(const char *activity, bool force) { if (!force && !update_process_title) return; #ifndef PS_USE_NONE #ifdef PS_USE_CLOBBER_ARGV /* If ps_buffer is a pointer, it might still be null */ if (!ps_buffer) return; #endif /* Update ps_buffer to contain both fixed part and activity */ strlcpy(ps_buffer + ps_buffer_fixed_size, activity, ps_buffer_size - ps_buffer_fixed_size); /* Transmit new setting to kernel, if necessary */ #ifdef PS_USE_SETPROCTITLE setproctitle("%s", ps_buffer); #endif #ifdef PS_USE_PSTAT { union pstun pst; pst.pst_command = ps_buffer; pstat(PSTAT_SETCMD, pst, strlen(ps_buffer), 0, 0); } #endif /* PS_USE_PSTAT */ #ifdef PS_USE_PS_STRINGS PS_STRINGS->ps_nargvstr = 1; PS_STRINGS->ps_argvstr = ps_buffer; #endif /* PS_USE_PS_STRINGS */ #ifdef PS_USE_CLOBBER_ARGV { int buflen; /* pad unused memory */ buflen = strlen(ps_buffer); /* clobber remainder of old status string */ if (last_status_len > buflen) memset(ps_buffer + buflen, PS_PADDING, last_status_len - buflen); last_status_len = buflen; } #endif /* PS_USE_CLOBBER_ARGV */ #ifdef PS_USE_PRCTL prctl(PR_SET_NAME, ps_buffer); #endif #ifdef PS_USE_WIN32 { /* * Win32 does not support showing any changed arguments. To make it at * all possible to track which backend is doing what, we create a * named object that can be viewed with for example Process Explorer. */ static HANDLE ident_handle = INVALID_HANDLE_VALUE; char name[PS_BUFFER_SIZE + 32]; if (ident_handle != INVALID_HANDLE_VALUE) CloseHandle(ident_handle); sprintf(name, "python(%d): %s", _getpid(), ps_buffer); ident_handle = CreateEvent(NULL, TRUE, FALSE, name); } #endif /* PS_USE_WIN32 */ #endif /* not PS_USE_NONE */ } /* * Returns what's currently in the ps display, in case someone needs * it. Note that only the activity part is returned. On some platforms * the string will not be null-terminated, so return the effective * length into *displen. */ const char * get_ps_display(int *displen) { #ifdef PS_USE_CLOBBER_ARGV size_t offset; /* If ps_buffer is a pointer, it might still be null */ if (!ps_buffer) { *displen = 0; return ""; } /* Remove any trailing spaces to offset the effect of PS_PADDING */ offset = ps_buffer_size; while (offset > ps_buffer_fixed_size && ps_buffer[offset - 1] == PS_PADDING) offset--; *displen = offset - ps_buffer_fixed_size; #else *displen = strlen(ps_buffer + ps_buffer_fixed_size); #endif return ps_buffer + ps_buffer_fixed_size; } python-setproctitle-1.0.1/src/spt_status.h000066400000000000000000000010661140271666600207360ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * spt_status.h * * Declarations for spt_status.c * *------------------------------------------------------------------------- */ #ifndef SPT_STATUS_H #define SPT_STATUS_H #include "c.h" extern bool update_process_title; extern char **save_ps_display_args(int argc, char **argv); extern void init_ps_display(const char *initial_str); extern void set_ps_display(const char *activity, bool force); extern const char *get_ps_display(int *displen); #endif /* SPT_STATUS_H */ python-setproctitle-1.0.1/src/strlcpy.c000066400000000000000000000041311140271666600202140ustar00rootroot00000000000000/*------------------------------------------------------------------------- * * strlcpy.c * strncpy done right * * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * * * IDENTIFICATION * $PostgreSQL: pgsql/src/port/strlcpy.c,v 1.4 2007/01/05 22:20:03 momjian Exp $ * * This file was taken from OpenBSD and is used on platforms that don't * provide strlcpy(). The OpenBSD copyright terms follow. *------------------------------------------------------------------------- */ /* $OpenBSD: strlcpy.c,v 1.11 2006/05/05 15:27:38 millert Exp $ */ /* * Copyright (c) 1998 Todd C. Miller * * 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 "c.h" /* * Copy src to string dst of size siz. At most siz-1 characters * will be copied. Always NUL terminates (unless siz == 0). * Returns strlen(src); if retval >= siz, truncation occurred. * Function creation history: http://www.gratisoft.us/todd/papers/strlcpy.html */ size_t strlcpy(char *dst, const char *src, size_t siz) { char *d = dst; const char *s = src; size_t n = siz; /* Copy as many bytes as will fit */ if (n != 0) { while (--n != 0) { if ((*d++ = *s++) == '\0') break; } } /* Not enough room in dst, add NUL and traverse rest of src */ if (n == 0) { if (siz != 0) *d = '\0'; /* NUL-terminate dst */ while (*s++) ; } return (s - src - 1); /* count does not include NUL */ } python-setproctitle-1.0.1/tests/000077500000000000000000000000001140271666600167245ustar00rootroot00000000000000python-setproctitle-1.0.1/tests/setproctitle_test.py000066400000000000000000000155751140271666600230730ustar00rootroot00000000000000"""setproctitle module unit test. Use nosetests to run this test suite. Copyright (c) 2009-2010 Daniele Varrazzo """ import os import re import sys import shutil import tempfile import unittest from subprocess import Popen, PIPE, STDOUT from nose.plugins.skip import SkipTest class SetproctitleTestCase(unittest.TestCase): def test_runner(self): """Test the script execution method.""" rv = self.run_script(""" print 10 + 20 """) self.assertEqual(rv, "30\n") def test_init_getproctitle(self): """getproctitle() returns a sensible value at initial call.""" rv = self.run_script(""" import setproctitle print setproctitle.getproctitle() """, args="-u") self.assertEqual(rv, sys.executable + " -u\n") def test_setproctitle(self): """setproctitle() can set the process title, duh.""" rv = self.run_script(r""" import setproctitle setproctitle.setproctitle('Hello, world!') import os print os.getpid() # ps can fail on kfreebsd arch # (http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=460331) print os.popen("ps -o pid,command 2> /dev/null").read() """) lines = filter(None, rv.splitlines()) pid = lines.pop(0) pids = dict([r.strip().split(None, 1) for r in lines]) title = self._clean_up_title(pids[pid]) self.assertEqual(title, "Hello, world!") def test_prctl(self): """Check that prctl is called on supported platforms.""" linux_version = [] if sys.platform == 'linux2': try: linux_version = map(int, re.search("[.0-9]+", os.popen("uname -r").read()) .group().split(".")[:3]) except: pass if linux_version < [2,6,9]: raise SkipTest rv = self.run_script(r""" import setproctitle setproctitle.setproctitle('Hello, prctl!') print open('/proc/self/status').read() """) status = dict([r.split(':', 1) for r in rv.splitlines() if ':' in r]) self.assertEqual(status['Name'].strip(), "Hello, prctl!") def test_getproctitle(self): """getproctitle() can read the process title back.""" rv = self.run_script(r""" import setproctitle setproctitle.setproctitle('Hello, world!') print setproctitle.getproctitle() """) self.assertEqual(rv, "Hello, world!\n") def test_environ(self): """Check that clobbering environ didn't break env.""" rv = self.run_script(r""" import setproctitle setproctitle.setproctitle('Hello, world! ' + 'X' * 1024) # set a new env variable, update another one import os os.environ['TEST_SETENV'] = "setenv-value" os.environ['PATH'] = os.environ.get('PATH', '') \ + os.pathsep + "fakepath" # read the environment from a spawned process inheriting the # updated env newenv = dict([r.split("=",1) for r in os.popen("env").read().splitlines() if '=' in r]) print setproctitle.getproctitle() print newenv['TEST_SETENV'] print newenv['PATH'] """) title, test, path = rv.splitlines() self.assert_(title.startswith("Hello, world! XXXXX"), title) self.assertEqual(test, 'setenv-value') self.assert_(path.endswith('fakepath'), path) def test_issue_8(self): """Test that the module works with 'python -m'.""" module = 'spt_issue_8' pypath = os.environ.get('PYTHONPATH', None) dir = tempfile.mkdtemp() os.environ['PYTHONPATH'] = dir + os.pathsep + (pypath or '') try: open(dir + '/' + module + '.py', 'w').write( self._clean_whitespaces(r""" import setproctitle setproctitle.setproctitle("Hello, module!") import os print os.getpid() print os.popen("ps -o pid,command 2> /dev/null").read() """)) rv = self.run_script(args="-m " + module) lines = filter(None, rv.splitlines()) pid = lines.pop(0) pids = dict([r.strip().split(None, 1) for r in lines]) title = self._clean_up_title(pids[pid]) self.assertEqual(title, "Hello, module!") finally: shutil.rmtree(dir, ignore_errors=True) if pypath is not None: os.environ['PYTHONPATH'] = pypath else: del os.environ['PYTHONPATH'] def run_script(self, script=None, args=None): """run a script in a separate process. if the script completes successfully, return the concatenation of ``stdout`` and ``stderr``. else fail. """ cmdline = sys.executable if args: cmdline = cmdline + " " + args proc = Popen(cmdline, stdin=PIPE, stdout=PIPE, stderr=STDOUT, shell=True, close_fds=True) if script is not None: script = self._clean_whitespaces(script) out = proc.communicate(script)[0] if 0 != proc.returncode: print out self.fail("test script failed") return out def _clean_whitespaces(self, script): """clean up a script in a string Remove the amount of whitelines found in the first nonblank line """ script = script.splitlines(True) while script and script[0].isspace(): script.pop(0) if not script: raise ValueError("empty script") line1 = script[0] spaces = script[0][:-len(script[0].lstrip())] assert spaces.isspace() for i, line in enumerate(script): if line.isspace(): continue if line.find(spaces) != 0: raise ValueError("inconsistent spaces at line %d (%s)" % (i + 1, line.strip())) script[i] = line[len(spaces):] # drop final blank lines: they produce import errors while script and script[-1].isspace(): del script[-1] assert not script[0][0].isspace(), script[0] return ''.join(script) def _clean_up_title(self, title): """Clean up a string from the prefix added by the platform. """ # BSD's setproctitle decorates the title with the process name. if 'bsd' in sys.platform: procname = os.path.basename(sys.executable) title = ' '.join([t for t in title.split(' ') if procname not in t]) return title if __name__ == '__main__': unittest.main()