Re: Setting process command name in forked process

2024-01-26 Thread Steve Beck via Cygwin
Thanks so much for the reply, Anton!  Really appreciate it.

I tried what you proposed.  Here is the code trying both ways (overwriting what 
is referenced by __argv[0] and then reassigning the reference).  I compile this 
code (foo.c) simply as follows: gcc -o foo foo.c (with no errors or warnings):

#include
#include
#include
#include

extern  pid_t   getpid(void), fork(void);
extern  int sleep(int);

int
main (int argc, char *argv[])
{
printf("%s with pid %d: Entered.  About to fork child ...\n",
argv[0], getpid());

if (fork() == 0)
{
extern  char**__argv;

strcpy(__argv[0], "bar");

printf("Child '%s' (argv[0]) with pid %d: ps ...\n",
argv[0], getpid());
system("ps");

__argv[0] = "bar";

printf("Retry in Child '%s' (argv[0]) with pid %d setting 
__argv[0] = 'bar': ps ...\n", argv[0], getpid());
system("ps");

exit(0);
}

printf("%s parent with pid %d: sleep(5) ...\n", argv[0], getpid());
sleep(5);

exit(0);
}

Here is the output when running foo.exe:

foo with pid 497: Entered.  About to fork child ...
foo parent with pid 497: sleep(5) ...
Child 'bar' (argv[0]) with pid 498: ps ...
  PIDPPIDPGID WINPID   TTY UIDSTIME COMMAND
  446 445 446 108276  pty0 1207519 10:19:37 /usr/bin/bash
  445   1 445 126652  ?1207519 10:19:36 /usr/bin/mintty
  499 498 497 125904  pty0 1207519 10:26:41 /usr/bin/ps
  498 497 497 128424  pty0 1207519 10:26:41 /home/sbeck/foo
  497 446 497 123772  pty0 1207519 10:26:41 /home/sbeck/foo
Retry in Child 'bar' (argv[0]) with pid 498 setting __argv[0] = 'bar': ps ...
  PIDPPIDPGID WINPID   TTY UIDSTIME COMMAND
  446 445 446 108276  pty0 1207519 10:19:37 /usr/bin/bash
  445   1 445 126652  ?1207519 10:19:36 /usr/bin/mintty
  498 497 497 128424  pty0 1207519 10:26:41 /home/sbeck/foo
  497 446 497 123772  pty0 1207519 10:26:41 /home/sbeck/foo
  500 498 497 128948  pty0 1207519 10:26:41 /usr/bin/ps

As you can see, in neither case does the ps command seem to accurately reflect 
the change in __argv[0] (although within the program, the change occurs to 
argv[0]).

Can you see what I'm doing wrong?

Many thanks,
Steve


From: Lavrentiev, Anton (NIH/NLM/NCBI) [C] 
Sent: Friday, January 26, 2024 7:47 AM
To: Steve Beck ; cygwin@cygwin.com 
Subject: RE: Setting process command name in forked process

> (I'm assuming it's too late by the time the /proc entry has been set up).

Actually, it's not.  But beware, the suggested solution is absolutely NOT 
portable:

These are the externals that /proc is referring to...  (Not argc, argv passed 
to main().)

extern char** __argv;
extern int__argc;

So you can change everything that it shows by reassigning __argv(and/or __argc) 
with a totally
different set of arguments, or just modify __argv[0], provided that it fits 
into the space
occupied by the original argument [0].

HTH,

Anton Lavrentiev
Contractor NIH/NLM/NCBI


-- 
Problem reports:  https://cygwin.com/problems.html
FAQ:  https://cygwin.com/faq/
Documentation:https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple


Re: Setting process command name in forked process

2024-01-29 Thread Steve Beck via Cygwin
Thank you, Corinna and Anton for your replies.  I downloaded procps, and it 
worked exactly as you described.  I understand this approach is a non-portable 
hack and to the extent that it matters at all, I'd like to +1 the 
suggestion/request of picking up support for setproctitle(3) in the next 
available release.

Thanks again!

Best,
Steve


From: Corinna Vinschen 
Sent: Monday, January 29, 2024 1:58 AM
To: cygwin@cygwin.com 
Cc: Steve Beck 
Subject: Re: Setting process command name in forked process

On Jan 26 18:35, Steve Beck via Cygwin wrote:
> Thanks so much for the reply, Anton!  Really appreciate it.
>
> I tried what you proposed.  Here is the code trying both ways
> (overwriting what is referenced by __argv[0] and then reassigning the
> reference).  I compile this code (foo.c) simply as follows: gcc -o foo
> foo.c (with no errors or warnings):
>
> [...]
> if (fork() == 0)
> {
> extern  char**__argv;
>
> strcpy(__argv[0], "bar");

Don't do that.  It's much too dangerous.

> __argv[0] = "bar";

That's ok, but see below.

> printf("Retry in Child '%s' (argv[0]) with pid %d setting 
> __argv[0] = 'bar': ps ...\n", argv[0], getpid());
> system("ps");

Make sure to install the procps-ng package, and then call

  system("procps -f");

> Here is the output when running foo.exe:
> [...]
> Retry in Child 'bar' (argv[0]) with pid 498 setting __argv[0] = 'bar': ps ...
>   PIDPPIDPGID WINPID   TTY UIDSTIME COMMAND
>   446 445 446 108276  pty0 1207519 10:19:37 /usr/bin/bash
>   445   1 445 126652  ?1207519 10:19:36 
> /usr/bin/mintty
>   498 497 497 128424  pty0 1207519 10:26:41 
> /home/sbeck/foo
>   497 446 497 123772  pty0 1207519 10:26:41 
> /home/sbeck/foo
>   500 498 497 128948  pty0 1207519 10:26:41 /usr/bin/ps
>
> As you can see, in neither case does the ps command seem to accurately
> reflect the change in __argv[0] (although within the program, the
> change occurs to argv[0]).
>
> Can you see what I'm doing wrong?

Actually, that's not your fault.  ps(1) from the cygwin base package
does not support this kind of faking the process name, because it does
not even get the command line of a process.  The information given to
ps(1) is pretty minimal and doesn't allow for stuff like that.  The
process name is always the real executable path the process has been
started through.

However, there's the ps(1) from the procps-ng package, which is called
procps.exe so as not to collide with the basic Cygwin ps.  This ps
fetches process information from /proc, which *is* updated when you
change __argv[0], because the info is fetched in realtime from the
process itself.

So with `procps -f', the output looks like this:

Retry in Child './foo' (argv[0]) with pid 570 setting __argv[0] = 'bar': ps ...
UIDPID  PPID  C STIME TTY  TIME CMD
corinna569   496 15 10:49 pty0 00:00:00 ./foo
corinna570   569 19 10:49 pty0 00:00:00 bar
corinna571   570 99 10:49 pty0 00:00:00 procps -f
corinna496   495  0 10:18 pty0 00:00:00 -tcsh

Bottom line:

Cygwin does not support this officially.  Changing the global __argv[0]
is a bad hack.  It works, but is non-portable.  In fact, there is no
portable way to do this.  SOme systems have prctl, some have
setproctitle, and some have nothing like this at all, stock Windows for
example.

It's also too late to add something along these lines to Cygwin 3.5,
which is due this week.

What we can do is to support this in the next major version of Cygwin,
in which case I'd prefer to implement this via setproctitle(3), given
this API exists on BSD and Linux.  Whether that implies changing
Cygwin's very simple ps(1) as well, I can't say yet.


HTH,
Corinna

-- 
Problem reports:  https://cygwin.com/problems.html
FAQ:  https://cygwin.com/faq/
Documentation:https://cygwin.com/docs.html
Unsubscribe info: https://cygwin.com/ml/#unsubscribe-simple