zmena process name (ps)

Karel Zak zakkr na zf.jcu.cz
Úterý Prosinec 2 11:39:31 CET 2003


On Mon, Dec 01, 2003 at 07:57:57PM +0100, Milan Kerslager wrote:
> On Fri, Nov 28, 2003 at 10:57:34AM +0100, Rybarik, Michal wrote:
> > zdravim vsetkych,
> > 
> > mam commandline php skript, a chcel by som, ab sa pri vypise procesov (ps) 
> > zobrazovalo ako nazov procesu nieco ine - teda nazov aplikacie a akcia, ktora 
> > prave prebieha. googlovanim som zistil, ze v perle sa to da zmenit 
> > predefinovanom ARGV[0]. v php to takto nejde. mohol by mi niekto poradit, ake 
> > je univerzalne riesenie na urovni operacneho systemu? ako to nasit do php si uz
> > vymyslim aj sam. dakujem
> 
> V archivu jsem pro jazyk C nasel tohle:

 A nebylo to mysleno jako ukazka toho co se stane kdyz, se jen tak
 zapisuje do argv[0]? 

> void main(int argc,char **argv,char **env)
> {
>   int i=0;
>   while (env[i]) {
>     printf("%s\n",env[i]);
>     i++;
>   }
>   printf("\n *********** Druhy vypis *****************\n");
>   strcpy(argv[0],"Nazdarek, zdravi kasparek");
           ^^^^^^^
      Jak je to argv[0] velke?

 Jinak:

 - novejsich BSD maji setproctitle(const char *, ...)
 - HPUX ma pstat(PSTAT_SETCMD, )
 - nektere BSD maji strukturu PS_STRINGS->ps_argvstr = "string"
 - u nekterych BSD a hurdu lze argv[0] = "string"
 - linux, AIX, sgi, sun, ultrix, ksr, osf, QNX, svr4, svr5, darwin
   (apod. SysV-like) umoznuji urcitym zpusobem prepisovat argv[]
       
 Ta  Milanova vyse  uvdena ukazka  ma nedostatek,  ze pokud  neni argv[]
 dostatecne velke  tak dojde k  prepsani pole environ[],  ktere obsahuje
 veci, ktere  vraci napr. getenv(). Coz muze  byt docela problem. Reseni
 je  tedy (na  linuxu!)  zjistit  si velikost  argv  a  za nim  leziciho
 environ[] prealokovat environ[] a to  stare argv[] a environ[] pouzivat
 jako buffer pro to co chceme v argv[0..n] mit.

 Ukazka pro linux (a spol), inspirovano kodem v PostgreSQL:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

extern char **environ;

void
init_ps(int argc, char **argv, char **ps_buffer, size_t *ps_buffer_size)
{
	char	*end_of_area = NULL;
	char	**new_environ;
	int	i;
	
	*ps_buffer = NULL;
	*ps_buffer_size = 0;

	/*
	 * 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? */
		return;

	/*
	 * 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];
	*ps_buffer_size = end_of_area - argv[0];

	/*
	 * reallocate environ[]
	 */
	new_environ = malloc(sizeof(char *) * (i + 1));
	for (i = 0; environ[i] != NULL; i++)
		new_environ[i] = strdup(environ[i]);
	new_environ[i] = NULL;
	environ = new_environ;
}

void
set_ps(char *str, char *psbuf, size_t psbufsiz)
{
	if (psbuf && str)
	{
		size_t 	len = strlen(str),
			wanted = len > psbufsiz ? psbufsiz : len;

		strncpy(psbuf, str, wanted);
		memset(psbuf+wanted, '\0', psbufsiz-wanted);
	}
}

int
main(int argc, char **argv)
{
	char *psbuf;
	size_t psbufsiz;
	
	init_ps(argc, argv, &psbuf, &psbufsiz);
	set_ps("Nazdarek, zdravi kasparek", psbuf, psbufsiz);

	exit(0);
}

-- 
 Karel Zak  <zakkr na zf.jcu.cz>
 http://home.zf.jcu.cz/~zakkr/


Další informace o konferenci Linux