The macosxhints Forums

The macosxhints Forums (http://hintsforums.macworld.com/index.php)
-   UNIX - General (http://hintsforums.macworld.com/forumdisplay.php?f=16)
-   -   opening a program with a specific PID (http://hintsforums.macworld.com/showthread.php?t=13235)

atomictuesday 07-07-2003 12:09 PM

opening a program with a specific PID
 
How can I open a program with a specific PID? In other words if I want a program to run with PID 48 instead of one assigned by the kernel, how would I do this? Of course the PID cannot be taken in order to do this. Is there a command line program that does this? Or for that matter does anyone know what C function is used to accomplish this? Maybe in sys/unistd.h? Thanks in advance.
AtomicTuesday

hayne 07-07-2003 12:34 PM

not possible - why?
 
Quote:

Originally posted by atomictuesday
How can I open a program with a specific PID? In other words if I want a program to run with PID 48 instead of one assigned by the kernel, how would I do this?
This is not possible. But why do you want to do this? Normally the PID is not something you care about.

Okay, if you really want to do it, here's how:
Find out what the next available PID is - i.e. the PID that would be assigned to your program if you ran it now. If that PID is lower than your desired PID, start & stop random processes until the next PID is the one you want. If the next available PID is higher than your desired PID, reboot and try again.

mervTormel 07-07-2003 12:45 PM

yes, but, again, for the sake of all that is foul and unholy, why?! what is it you are trying to accomplish?

atomictuesday 07-07-2003 12:48 PM

I'm guessing it can be done but it would need to be done using an internal C function. I'll check unistd.h when I get home since many system functions are defined there. The way you suggest is kind of time consuming and if I am aiming for low PIDs then that won't work. What I am trying to do is the following. When you shutdown the computer and enter into single user mode, for some reason jaguar shuts down mach_init which is need for IPC. I can start mach_init in the background by forking it, but it will have another PID other than 2. This will not work properly.

houchin 07-07-2003 12:53 PM

Ok, so maybe a better question is why are you trying to run Mac OS X in single user mode (other than for disk repair).

If you really don't want the weight of the GUI engine (even if you don't have a user logged in) taking up CPU cycles, then install Darwin on a partition on your system and run from that.

atomictuesday 07-07-2003 01:07 PM

Well, sometimes I just need to run in single user mode. If I have to kill the WM for some reason, usually some programs are left floating around. By shutting down I am eliminating them all easily. Of course there are many other reasons. Please don't ask now why I want to kill my WM; let's stick to the initial problem.

houchin 07-07-2003 01:12 PM

But you've already been given you answer, and that answer was no, this is not something you can do. You just didn't want to believe it.

But to try and discover what you are really trying to accomplish, you might actually get a better solution to your actual problem, rather than just a solution to a problem in one step of the solution that you seem to be set on.

All of us, including me, sometimes get stuck heading down a dead-end path, and it takes others to help get us unstuck from that path by looking at the core problem from a different perspective.

hayne 07-07-2003 03:12 PM

what part of No didn't you understand?
 
Quote:

Originally posted by atomictuesday
I'm guessing it can be done but it would need to be done using an internal C function
I guess my earlier answer was not clear enough.
What you ask is impossible.
There is no "internal C function" to do it.
It is not possible given the current kernel.

So, the easiest way to do what you want would be to get the Darwin sources and compile your own version of the kernel after making the necessary changes.

Of course it would be better to slow down a bit and try to describe more clearly what user-level effect you are trying to achieve.
(Don't just repeat what you have said about wanting to restart Aqua without rebooting after being in single-user mode. Tell us why you want to do this. Including why you might need to kill the Window Manager.)

atomictuesday 07-08-2003 07:51 PM

Thanks houchin, hayne and merv; well essentially I already stated my initial problem: when in single user mode I need to start mach_init. The problem with doing this is that mach_init will be assigned a PID other than 2, which will screw the system up. No offense to anyone, but here is my reasoning: the kernel is the one which assigns a PID to a process when it is starting up. If maybe just maybe one could look into this code and incorporate it somewhere on a program one may have a working model for a so called "PID changing program". That is my opinion. Anyway, the initial reason for which I wanted to even drop into single user is because sometimes my windowmanager would crash. I am working on this program which actually kills the windowmanager automatically when this happens. Now I can always clean up any programs that are left floating around but it is a lot easier to just execute a shutdown and have it kill all of your things. Maybe with Panther, the windowmanager will be a whole lot more stable and I won't have to go through this. Thanks anyway. By the way, I am working on the integration of BSD specific, darwin specific, and linux specific macros and functions into common header files. The purpose of which is to be able to run BSD and linux specific programs on darwin. Let me know if you are interested in this and we can set something up.
AtomicTuesday

hayne 07-08-2003 08:36 PM

Quote:

Originally posted by atomictuesday
the initial reason for which I wanted to even drop into single user is because sometimes my windowmanager would crash. I am working on this program which actually kills the windowmanager automatically when this happens. Now I can always clean up any programs that are left floating around but it is a lot easier to just execute a shutdown and have it kill all of your things. Maybe with Panther, the windowmanager will be a whole lot more stable and I won't have to go through this.
If you are having a lot of crashes of the Window Manager or anything else at system level, there must be something wrong with your system. It is (obviously) not supposed to crash. I don't think I have ever seen the Window Manager crash. And if it did, I would just reboot. So what I don't understand is:
a) why you don't concentrate on figuring out why your WM is crashing
b) why you don't just reboot when this happens - that is the best (the only?) way to be sure to get back to a functioning system after some system-level process crashes.

P.S. when you say "windowmanager", I've been assuming you meant the Window Manager process. Or did you mean something else?

JavaOSX 07-09-2003 11:46 AM

I assume that what you're trying to accomplish is the ability to drop out to single user if/when your system crashes. Based on that I have a few questions.

Quote:

Originally posted by atomictuesday
....
The problem with doing this is that mach_init will be assigned a PID other than 2, which will screw the system up
....
AtomicTuesday
Are you saying that things are hardcoded within the system to a pid of 2 for mach_init?

Quote:

Originally posted by atomictuesday
....
If maybe just maybe one could look into this code and incorporate it somewhere on a program one may have a working model for a so called "PID changing program".
....
AtomicTuesday
The PID is assigned during the fork call in the kernel. Therefore there are a few ways to accomplish what you're asking.

1. Modifying the pid of a running process.

2. Adding a kernel syscall similiar to fork that would also take a pid as an argument. This code would be identical to the current fork implementation except that it would attempt to use the pid specified before trying alternatives. If the pid is already in use it cannot be used.

3. Modifying the pid assignment in the fork call to check the name of the program being forked and if it's a certain name, "mach_init" in this case, attempt a specific pid first.


#1 is dangerous and would probably screw up the system. #2 is doable but much harder to implement and a much bigger change. Not to mention you'd need find the fork to mach_init and pass in a pid, whereever that is. #3 is the simplest solution to implement. I could whip this up in a short amount of time if it was REALLY needed...

J

hayne 07-09-2003 12:38 PM

deep magic
 
Quote:

Originally posted by JavaOSX
Are you saying that things are hardcoded within the system to a pid of 2 for mach_init?
Well, yes, in a sense, but there is much deeper magic here than you realize. 'mach_init' is actually the first process that the system runs at boot. It forks and then execs '/sbin/init' in the parent. That is why 'ps -j -p 2' shows 'init' as 'mach_init''s parent.
For more details, see the Darwin source for 'mach_init':
http://www.opensource.apple.com/darw...oj/bootstrap.c

So, as you can see, it is slightly more involved than merely setting the PID.

JavaOSX 07-09-2003 02:12 PM

Re: deep magic
 
Quote:

Originally posted by hayne
Well, yes, in a sense, but there is much deeper magic here than you realize. 'mach_init' is actually the first process that the system runs at boot. It forks and then execs '/sbin/init' in the parent. That is why 'ps -j -p 2' shows 'init' as 'mach_init''s parent.
For more details, see the Darwin source for 'mach_init':
http://www.opensource.apple.com/darw...oj/bootstrap.c

So, as you can see, it is slightly more involved than merely setting the PID.
isn't mach_init started by the method load_init_program() in xnu\bsd\kern\kern_exec.c? This method is called by init pid 1, and init was called by the kernel pid 0 process.

J

hayne 07-09-2003 04:03 PM

Boot sequence
 
Quote:

Originally posted by JavaOSX
isn't mach_init started by the method load_init_program() in xnu\bsd\kern\kern_exec.c? This method is called by init pid 1, and init was called by the kernel pid 0 process.
I don't yet understand the kernel initialization code -i.e. where does it start when BootX invokes CallKernel()?
But have a look at the Apple document about the boot sequence:
http://developer.apple.com/documenta...gin/index.html
where it says quite clearly that the kernel starts 'mach_init' and 'mach_init' starts 'init'. This latter is what I see in the mach_init source code as I described above.

JavaOSX 07-09-2003 05:51 PM

Re: Boot sequence
 
Quote:

Originally posted by hayne
I don't yet understand the kernel initialization code -i.e. where does it start when BootX invokes CallKernel()?
But have a look at the Apple document about the boot sequence:
http://developer.apple.com/documenta...gin/index.html
where it says quite clearly that the kernel starts 'mach_init' and 'mach_init' starts 'init'. This latter is what I see in the mach_init source code as I described above.
I haven't read that document, but logically, a process cannot execute in any normal way until the kernel has run and setup everything(process tables, virtual memory, etc). This all seems to be done by pid 0 which is located in the file bsd_init.c, checkout this snippet:

Code:

set_bsdtask_info(kernel_task,(void *)p);
p->p_pid = 0;

/* give kernproc a name */
proc_name("kernel_task", p);

later on, this process calls bsd_utaskbootstrap() which sets it up for a manual ast call. This ast call is picked up over in kern_sig.c at the method bsd_ast(). Inside this method is the following code:

Code:

if (!bsd_init_done)
{
  extern void        bsdinit_task(void);
  bsd_init_done = 1;
  bsdinit_task();
}

Which is calling bsdinit_task(), which is back over in bsd_init.c. Within this method current process is named "init" in this code

Code:

struct proc *p = current_proc();
<snip>
proc_name("init", p);
<snip>
load_init_program(p);

a call is made to load_init_program() which is over in kern_exec.c. Within this method you have:

Code:

char                init_program_name[128] = "/sbin/mach_init\0";
<snip>
error = execve(p,&init_exec_args,retval);

which seems to be where the call over to mach_init is happening and where the code you're talking about takes over.

Based on my review of the code this is what I gather on how the boot process is happening. I'll have to check out that document and see if it agrees.

J

JavaOSX 07-09-2003 05:56 PM

and also, I believe BootX calls into the kernel at machine_startup() in xnu/osfmk/ppc/model_dep.c and this method calls setup_main() in xnu/osfmk/kern/startup.c. This method later calls bsd_init() as continued above.

J

hayne 07-09-2003 08:23 PM

by george
 
I think your analysis is correct - good sleuthing!

In summary, here is the trail of processes and function calls:
BootX invokes CallKernel()
which calls machine_startup()
which calls setup_main()
which calls start_kernel_threads()
which calls bsd_init()
which hand-crafts process #0, naming it 'kernel_task'
and then calls bsd_utaskbootstrap()
which creates process #1 (via a call to cloneproc())
and then calls act_set_astbsd() for process #1.
This results in a call to bsd_ast()
which calls bsdinit_task()
which assigns the name 'init' to process #1
and then calls load_init_program()
which does an exec of /sbin/mach_init (without doing a fork).

mach_init forks and then the parent process (#1) does an exec of /sbin/init.
The child process from the fork is process #2 and continues running as mach_init.

So, process #1 is called 'init' for a short time while it is executing kernel code, then it is '/sbin/mach_init', then it is '/sbin/init' after the fork & exec.

Confusing enough for you?
I'm happy to have this all figured out.

JavaOSX 07-09-2003 08:38 PM

Yeah, this is really good to have firmly documented, I need to bookmark this thread :D

Hopefully they don't change it all around for panther so we don't have to go through it all again.

J

JavaOSX 07-09-2003 11:24 PM

Just to nail this thread down 100%, I decided to put some debug messages into the kernel and try it out. I logged all fork's, all process name changes, and all exec's. Here are the relevant results.

Code:

kernel_task(0) forked kernel_task(1)
pid(1) changing name from "kernel_task" to "init"
init(1) exec'ing "mach_init"
mach_init(1) forked mach_init(2)
mach_init(1) exec'ing "init"
init(1) forked init(3)
init(3) exec'ing "sh"

This way it's easy to follow the processes and their name changes.

J

atomictuesday 07-11-2003 12:12 PM

I'm glad we changed topics here somewhat; really good topic by the way. Hayne, when you said "it is slightly more involved than merely setting the PID", did you mean that by just setting the pid of a new mach_init process to 2, that IPC will still not work? Since you are talking about the boot sequence here, I would like to mention that the code for BootX has some interesting things. For one thing it calls the kernel as you all know. But as well it displays the "booting" screen. One thing I have always wanted to change is the boot screen. It's not that I don't like the apple booting screen, it's just that it would be awesome to see some custom set image. Now there is a file within the source for BootX which defines this image. In fact, if you wanted to get the boot image from Mac10.1 back to 10.2, all you have to do is place the old file in the place of the new image file, and compile BootX. Then replace it and off you go, hey I'm going to try this tonight :). Of course having an image is allright, but nothing extraordinary. What I am really aiming at is having something like a movie which plays on startup; something of the like as when the hackers in the movie by the same name ( so it doesn't sound repetitive ) boot their machines. The trick is to have the movie play while the system is booting. We would have to figure out some way to loop the call to the display of the image in a thread, so as to not disturb the actual booting. The only problem with this is that the image seems to be in bitmap format, which I am not adept at. By the way the image information is within a header file. Anyone interested?
AtomicTuesday

hayne 07-11-2003 02:22 PM

MacBoot
 
Quote:

Originally posted by atomictuesday
Hayne, when you said "it is slightly more involved than merely setting the PID", did you mean that by just setting the pid of a new mach_init process to 2, that IPC will still not work?
I meant that it is very complicated and lots of things depend on the exact way that processes are started during the boot sequence and so it is far from being merely a matter of setting the PID.
Quote:

the code for BootX has some interesting things. For one thing it calls the kernel as you all know. But as well it displays the "booting" screen. One thing I have always wanted to change is the boot screen.
That is exactly what the shareware program MacBoot does.
Quote:

What I am really aiming at is having something like a movie which plays on startupfile.
You should try talking to the author(s) of MacBoot - maybe they are interested in collaborating.


All times are GMT -5. The time now is 06:13 PM.

Powered by vBulletin® Version 3.8.7
Copyright ©2000 - 2014, vBulletin Solutions, Inc.
Site design © IDG Consumer & SMB; individuals retain copyright of their postings
but consent to the possible use of their material in other areas of IDG Consumer & SMB.