How do I get the job object (if any) for my current process? - c++

In the context of Windows Job Objects, how can I get the job object for the current process (in case it is in a job object)? The IsProcessInJob function lets me test whether a given process (e.g. the current one) is in a given (or any) job - but it doesn't yield the handle of the matching job.

If you just want to find out what quotas/limits you are running under, or enumerate all the other processes in the job, you don't need to get the Job object for the current process.
You can call QueryInformationJobObject with NULL, which will be the Job object of the current process.
QueryInformationJobObject: http://msdn.microsoft.com/en-us/library/ms684925(VS.85).aspx
Job Objects: http://msdn.microsoft.com/en-us/library/ms684161(VS.85).aspx
Set job attributes using SetInformationJobObject
To answer the specific question, call IsProcessInJob find out if you are in a job.
You can find out everything about the Job by passing NULL to QueryInformationJobObject
Your child processes will inherit your job automatically, unless you pass CREATE_BREAKAWAY_FROM_JOB and the job has JOB_OBJECT_LIMIT_BREAKAWAY_OK or JOB_OBJECT_LIMIT_SILENT_BREAKAWAY_OK is set. In these cases you can assign the process to a new job if you wish.
So without knowing the handle, you can find out all about your current Job, and assign child processes within the current job, or if you have permission, without the current job. I.e. you can do almost everything the handle would allow you to do.
The only exception is duplicate it to another sibling process. If you need to do that you will have to have the parent process communicate the handle value to you somehow.

Related

How can I pass value through process variable in Camunda to subflow from main flow

Colleagues,
Can you please advise me a bit about the following.
I cannot figure out how to pass value through process variable from main flow to its subflow in Camunda. I am putting value to process variable in one task in main flow via execution.setVariable("toolId", toolId);
where execution is an instance of DelegateExecution. I am trying to retrieve in another task of subflow via
Long toolId = (Long) execution.getVariable("toolId");
However I am getting null.
By subflow I assume you mean a call activity (otherwise the data would be available).
A call activity references a technically independent process instance with its own data. Therefore you have to explicitly map the in data, which should be copied from the source (parent) to the target (sub process) and also the out data in the other direction.
Please see: https://docs.camunda.io/docs/components/modeler/bpmn/call-activities/#variable-mappings and https://docs.camunda.io/docs/components/concepts/variables/#inputoutput-variable-mappings

How can I reliably check whether one Windows process is the parent of another in C++?

I'm working on a function which gets me the PID of the parent process for a given PID. The prototype of the function is
DWORD getParentPid( DWORD pid );
To do so, I'm using the CreateToolhelp32Snapshot function (and related functions) to get the PROCESSENTRY32 structure for my given PID pid. I can then use the th32ParentProcessId field of the structure to get the PID of the process which created my given process.
However, since the parent process might have been destroyed already (and it's PID might have been reused by Windows), I'm using the GetProcessTimes function to get the creation times of the supposed parent and the child process and then compare those using CompareFileTime.
If CompareFileTime returns -1, I know that the process with the parent ID was created before my child process, so it's indeed the parent. Otherwise, it's apparently a re-used ID - and the parent PID is invalid (it doesn't reference the original parent anymore).
The issue with this is that it very much relies on a strictly monotonous system clock and the granularity of GetProcessTimes. I did experience cases in which CompareFileTime returned 0 (which means "equal time") even though the process being considered were indeed in a parent-child relationship. I could change my check so that a CompareFileTime result value <= 0 would be considered to indicate a parent, but then I would break the (theoretical) case where a parent created a child process, then the parent was destroyed, and then Windows re-used the PID - all within 100ns (which is the resolution of GetProcessTimes).
I wonder - is there a different, more reliably, mechanism to verify that some process is indeed the parent of another process in C++?
Edit: I need this function in order to determine all child processes (this means including grand-child processes). The CreateToolhelp32Snapshot lets me iterate over all processes but I need to look at the parent PID of each of them to tell whether it's a child of my process at hand.
If the process(es) have been created whilst your app is running, you could just iterate over it repeatedly over time and catch PID re-use.
The sample here:
http://msdn.microsoft.com/en-us/library/ms686701(v=vs.85).aspx
Shows calling CreateToolhelp32Snapshot with a parameter of 0 for the processId and it uses the option TH32CS_SNAPPROCESS which says it captures all processes. Then, once you've got the snapshot, as in the sample you can walk the processes as they existed in the snapshot. The parent id's should be valid within the snapshot because you're looking at the state of all the processes as they existed in the single moment when the snapshot was taken. You don't have to bother with your process start time comparison stuff.

How to wait for a cloned child process of an invoked process to exit?

I have a program which needs to invoke a process to perform an operation and wait for it to complete the operation. The problem is that the invoked process clones itself and exits, which causes the wait api to return when the process exits. How can I wait for the cloned process to finish execution and return?
I am using the windows JOB object as mentioned in http://www.microsoft.com/msj/0399/jobkernelobj/jobkernelobj.aspx, But I am not sure if this is the best way.
umm, I'm pretty sure you can can the spawner process id from any process. I'd iterate through all the processes, find the one's who's parent id matches the one of the process you spawned, and wait for it to die.
alternatively (I mean, thats pretty hack) what is the child child process doing? is there some other way you could detect when it has finished doing what it is meant to do?
a hack way to get a process's parent id
http://www.codeguru.com/cpp/w-p/win32/article.php/c1437
takes a handle, and using the method in the code above, returns the parent id.
http://msdn.microsoft.com/en-us/library/ms684280(VS.85).aspx
OpenProcess takes an id, gets a handle to it (if you're lucky)
http://msdn.microsoft.com/en-us/library/ms684320(VS.85).aspx
GetProcessId takes a handle, gets it's id.
http://msdn.microsoft.com/en-us/library/ms683215(VS.85).aspx
GetExitCodeProcess takes a handle, returns whether the process is done or not.
http://msdn.microsoft.com/en-us/library/ms683189(VS.85).aspx
so appart from using hidden nt calls that it expressly tells you not to, you would basically have to create your process, get it's id, then spam all the process, opening them and checking their parent ids against the id of the process you created, if you didn't find one, then it's done, if you do, spam it with GetExitCodeProcess until its done.
I haven't tested any of this, but it looks like A way to do it. though if it's THE BEST way to do it I might just have to loose all faith in windows...
+1 for using job objects ;)
Assuming the process that you're running isn't spawning the cloned version of itself in such a way that it breaks out of the job...
You should be able to simply monitor the job events and act on JOB_OBJECT_MSG_ACTIVE_PROCESS_ZERO (see JOBOBJECT_ASSOCIATE_COMPLETION_PORT and SetInformationJobObject()). Monitoring the job in this way will also give you notifications of the processId's of new processes created within the job and details of when they exit.
If you have control over the source of invoked process, one possible solution would be to make it wait for the process it spawns by cloning itself.

How to restrict proccess to create new processes?

How to restrict proccess to create new processes?
You could assign the process to a job object. Use SetInformationJobObject with the JOB_OBJECT_LIMIT_ACTIVE_PROCESS flag to limit the number of processes in that job object to one. Do NOT set the JOB_OBJECT_LIMIT_BREAKAWAY_OK (which would allow the process to create processes that were not part of the job object).
The process could still work around that, such as by starting a new process via the task scheduler or WMI. If you're trying to do something like create a sandbox to run code you really don't trust, this won't adequate. If you have a program that you trust, but just want to place a few limits on what it does, this should be more than adequate.
To put that slightly differently, this is equivalent to locking your car. Somebody can break in (or out, in this case), but at least they have to do a bit more than just walk in unhindered.
On Windows, there isn't a way to stop a processing from spawning other processes. Nor is there on any operating system I know of.
The CreateProcess() system call is available to all processes, thus any process can create a child process.
You could run the process in a sandbox which restricts process creation, but the overhead for this is probably more than you want.
Can I ask why you want to do such a thing?
Use NT Job objects
JOBOBJECT_BASIC_LIMIT_INFORMATION can limit the number of active processes, or use JOBOBJECT_ASSOCIATE_COMPLETION_PORT and kill the new process (If you only need to kill a subset of all new processes)

getrusage() get system time, user time. Unix programming help

I am writing a shell where I need to launch several child processes at once and record the system time and user time.
So far I am able to do it. The only problem is that I am using wait4 to grab the system resources used by the child program and put it in my rusage structure called usage.
How can I launch all the processes at the same time and keep track of the user and system times? I can remove the wait4() system call and use it outside to loop so I can make the parent wait, but if I do that then I can only record the times for the last process and not all of them.
Do you have any idea how I can fix this?
execute(commandPipev,"STANDARD",0);
wait4(pid,&status,0,&usage);
printf("Child process: %s\t PID:%d\n", commandPipev[0], pid);
printf("System time: %ld.%06ld sec\n",usage.ru_stime.tv_sec, usage.ru_stime.tv_usec);
printf("User time: %ld.%06ld sec\n\n",usage.ru_utime.tv_sec, usage.ru_utime.tv_usec);
A convoluted answer.
In a POSIX environment, launch the children, then use waitid() with the WNOWAIT option to tell you that some child has exited. The option leaves the child in a waitable state - that is, you can use another wait-family call to garner the information you need. You can then use the non-POSIX wait4() system call to garner the usage information for the just exited child, and deal with the accounting you need to do. Note that you might find a different process has terminated between the waitid() and wait4() calls; you need to use a loop and appropriate flags and tests to collect all the available corpses (dead child processes) before going back to the waitid() call to find out about the other previously incomplete child processes. You also have to worry about any of the wait-family of functions returning the information for a process that was previously started in the background and has now finished.
The Linux man page for wait4(2) suggests that WNOWAIT might work directly with wait4(2), so you may be able to do it all more cleanly - if, indeed, you need the option at all.
Consider whether you can use process groups to group the child processes together, to make waiting for the members of the process group easier.