ProgrammingThis forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.
Notices
Welcome to LinuxQuestions.org, a friendly and active Linux Community.
You are currently viewing LQ as a guest. By joining our community you will have the ability to post topics, receive our newsletter, use the advanced search, subscribe to threads and access many other special features. Registration is quick, simple and absolutely free. Join our community today!
Note that registered members see fewer ads, and ContentLink is completely disabled once you log in.
If you have any problems with the registration process or your account login, please contact us. If you need to reset your password, click here.
Having a problem logging in? Please visit this page to clear all LQ-related cookies.
Get a virtual cloud desktop with the Linux distro that you want in less than five minutes with Shells! With over 10 pre-installed distros to choose from, the worry-free installation life is here! Whether you are a digital nomad or just looking for flexibility, Shells can put your Linux machine on the device that you want to use.
Exclusive for LQ members, get up to 45% off per month. Click here for more info.
Hi i have some code for creating a process that runs to the background
pid=fork();
if (pid<0){
printf("Error creating child process ");
}
if (pid >0){
exit(0);
}
sid=setsid();
if (sid<0){
perror("Problem with the child process");
}
The problem is that when i execute my small programme
./3threads
then in the ps -aux
i can see an entry that includes
./3threads as the process name
Is it possible to change this? and if it is possible how?
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
pid_t pid;
pid = fork();
if (pid < 0) {
printf("Error creating child process ");
exit(1);
}
if (pid > 0) {
exit(0);
}
setsid();
/* You can safely leave this part out,
* the error will never happen (in this case).
if (sid < 0) {
perror("Problem with the child process");
}
*/
/* Change the name as shown by "ps ax" */
sprintf(argv[0], "Hi there! (was 3threads)");
sleep(20); /* Time to inspect with: ps ax */
return 0;
}
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789
Rep:
Quote:
sprintf(argv[0], "Hi there! (was 3threads)");
Beware overwriting argv[0] will likely shift remaining arguments offset, and argv[1] content.
Not a big deal as you probably have processed your arguments before the fork, but if some of these need to be used after the fork, you should copy them to a safer area before it.
Beware overwriting argv[0] will likely shift remaining arguments offset, and argv[1] content.
I'd have thought this unlikely as argv is simply an array of pointers, not the pointed-to content, so replacing one pointer with another shouldn't affect the other pointers at all.
Distribution: Solaris 11.4, Oracle Linux, Mint, Debian/WSL
Posts: 9,789
Rep:
You do not replace one pointer with another, you replace data pointed to by data being of a likely different size.
Actually I was wrong about the argument shift, but if you new argv[0] name is longer than the old one, argv[1] will be trashed, and possibly argv[2] and so on depending on how much of the environment you overwrite.
Originally posted by jlliagre You do not replace one pointer with another, you replace data pointed to by data being of a likely different size.
Actually I was wrong about the argument shift, but if you new argv[0] name is longer than the old one, argv[1] will be trashed, and possibly argv[2] and so on depending on how much of the environment you overwrite.
Yes, you're right, you should assign the pointer to the string to argv[0] instead. You may run into scoping issues, of course.
Originally posted by jlliagre
You cannot change argv[0], it is not a pointer.
That's not correct. argv is of type pointer-to-pointer-to-char and argv[0] is of type pointer-to-char.
Here's what the C standard says about changing the strings in the argv array of strings:
The parameters argc and argv and the strings pointed to by the argv
array shall be modifiable by the program, and retain their last-stored
values between program startup and program termination.
So changing the strings is ok, just don't try to write past the end. But modifying the actual pointers
invokes undefined behaviour.
Will NOT work. It updates the local copy of argv, not the one being used by the system. In other words, the system has its own copy of argv that you must update. So the new name of the executable must be no longer than the old one.
So the new name of the executable must be no longer than the old one.
Not correct. The buffer size for argv[0] is fixed, as defined in /usr/include/bits/posix1_lim.h. On debian sarge (and most other posix OS's) it is:
Code:
#define _POSIX_PATH_MAX 256
So, no need (nor possible) to get a new pointer for argv[0]. If you keep it within 256, no shifting/overwriting/thrashing of argv[1] , argv[2],... argv[n], nor segfaults will occur either.
Just stay within 255 bytes (leave 1 byte room for '\0') and you can write whatever you want in the buffer pointed to by argv[0].
Originally posted by jlliagre This is perhaps cool, but wrong ...
A maximum size defined somewhere doesn't imply a fixed size is used.
Hmm... It appears that you're right.
I've read about this while ago on usenet (comp.unix.programmer). Now I've actually tried it, and it's quite clear that it's wrong:.
Code:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
int i;
/* Change the name as shown by "ps ax" to "abcdef...zabcdef...". */
for (i = 0; i < 22; ++i) {
argv[0][i] = (i % 26) + 'a';
}
argv[0][i] = '\0'; /* terminate string */
sleep(20); /* Time to inspect with: ps ax */
return 0;
}
LinuxQuestions.org is looking for people interested in writing
Editorials, Articles, Reviews, and more. If you'd like to contribute
content, let us know.