Call each program with a parameter, in each program set the parameter to indicate whether the program is successful or not, check the parameter after the program has run, if it’s successful proceed to the next program, otherwise stop or send a message etc.
Or a data area. Job1 clears the data area when it starts, when it ends successfully it writes it’s name into the data area. Job2 checks to see that just the name of job1 is in the data area. When it ends it writes it’s name into position 11 of the data area. etc.
If you’ve got a process that’s sitting, waiting for previous, submitted-to-batch, processes to complete, I’d suggest a data queue instead. That way, your waiting process can suspend on the queue, awaiting word from the batch jobs & once it collects successful outcomes from them, it proceeds to do its thing.
Let me know if you help with the data queue puts and gets – very easy to set up & quite efficient.
If this is just about a few programs that need to run sequentially (one after another), then the simplest way is still going to be to have one CL program which calls program A with a parameter, then checks the parameter before calling program B with the same parameter, then checks the parameter before calling program C with the same parameter, etc.