Path: blob/master/debugtools/DDR_VM/zos_address_space_packer/multi_as.c
5991 views
/*******************************************************************************1* Copyright (c) 2009, 2014 IBM Corp. and others2*3* This program and the accompanying materials are made available under4* the terms of the Eclipse Public License 2.0 which accompanies this5* distribution and is available at https://www.eclipse.org/legal/epl-2.0/6* or the Apache License, Version 2.0 which accompanies this distribution and7* is available at https://www.apache.org/licenses/LICENSE-2.0.8*9* This Source Code may also be made available under the following10* Secondary Licenses when the conditions for such availability set11* forth in the Eclipse Public License, v. 2.0 are satisfied: GNU12* General Public License, version 2 with the GNU Classpath13* Exception [1] and GNU General Public License, version 2 with the14* OpenJDK Assembly Exception [2].15*16* [1] https://www.gnu.org/software/classpath/license.html17* [2] http://openjdk.java.net/legal/assembly-exception.html18*19* SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 OR GPL-2.0 WITH Classpath-exception-2.0 OR LicenseRef-GPL-2.0 WITH Assembly-exception20*******************************************************************************/212223#define _XOPEN_SOURCE_EXTENDED 124#include <unistd.h>25#include <spawn.h>26#include <stdio.h>27#include <errno.h>28#include <sys/types.h>29#include <assert.h>30#include <string.h>3132/*33* Test prog to pack multiple VMs into an address space34*35* This involves messing with environment variables that affect the spawn() call36* and can't easily be done from the USS command line (it's easy enough to put Java37* into the address space of the shell, seemingly impossible to put two Javas into38* the address space of the shell).39*/4041extern char **environ;4243struct ToSpawn44{45char * line;46char * execname;47char ** argv;48pid_t pid;49struct ToSpawn * next;50};5152#define MAX_BUFFER 102453#define MAX_ARGS 1005455static struct ToSpawn * parseInputFile(FILE * inputFile)56{57char buffer[MAX_BUFFER];58struct ToSpawn * head = NULL;59struct ToSpawn * tail = NULL;6061while (NULL != fgets(buffer,MAX_BUFFER,inputFile)) {62struct ToSpawn * allocated;63char * p;64char * localArgv[MAX_ARGS];65unsigned int i;66unsigned int argContext = 0;6768if (buffer[0] == '\0') {69continue;70}7172/* Strip out any funny characters */73p = buffer;7475while(*p) {76if (*p == '\n' || *p == '\r') {77*p = ' ';78}79p++;80}8182allocated = (struct toSpawn *)malloc(sizeof (struct ToSpawn));83assert(allocated != NULL);8485memset(allocated, 0x00, sizeof(struct ToSpawn));8687allocated->line = strdup(buffer);88assert(allocated->line != NULL);8990p = strtok(buffer," ");9192allocated->execname = strdup(p);93assert(allocated->execname != NULL);9495while ( (p = strtok(NULL," ")) != NULL) {96localArgv[argContext] = strdup(p);97assert(localArgv[argContext] != NULL);98argContext++;99}100101allocated->argv = (char **) malloc((argContext + 2) * sizeof(char**));102assert(allocated->argv != NULL);103104allocated->argv[0] = allocated->execname;105for (i=0;i!=argContext;i++) {106allocated->argv[i + 1] = localArgv[i];107}108allocated->argv[argContext + 1] = NULL;109110if (NULL == head) {111head = allocated;112tail = head;113} else {114tail->next = allocated;115tail = allocated;116}117}118119return head;120}121122static void spawnAndWait (struct ToSpawn * spawnList){123struct ToSpawn * current = spawnList;124125while(current != NULL) {126#define SP_FD_NUM 3127#define MAX_ARGS 100128int sp_fd_cnt;129int sp_fd_map[SP_FD_NUM];130struct inheritance sp_inherit;131pid_t resultPid;132133134/* Map file descriptors for child. This enables the child to use */135/* the literal values (0, 1, 2) as file descriptors. */136sp_fd_cnt = SP_FD_NUM;137sp_fd_map[0] = 0;138sp_fd_map[1] = 1;139sp_fd_map[2] = 2;140141memset(&sp_inherit, 0x00, sizeof(sp_inherit));142143144fprintf(stderr,"Spawning %s\n",current->line);145146fprintf(stderr,"execname is %s\n",current->execname);147148149{150int i=0;151for(i=0;current->argv[i] != NULL;i++) {152fprintf(stderr,"arg[%d] = %p, %s, %d\n",i,current->argv[i],current->argv[i],strlen(current->argv[i]));153}154}155156157/* Spawn child process */158{159resultPid = spawn(current->execname,160sp_fd_cnt, sp_fd_map, &sp_inherit, current->argv, environ);161}162if (resultPid < 0) {163perror("spawn()");164exit(1);165}166167fprintf(stderr,"Started PID was %d\n",resultPid);168current->pid = resultPid;169170current = current->next;171}172173current = spawnList;174175while(current != NULL) {176int childExitCode;177pid_t waitResult;178179waitResult = waitpid(current->pid,&childExitCode,0);180181if (waitResult != current->pid) {182perror("waitpid()");183}184current = current->next;185}186}187188/*189* One argument expected - list of commands to run190*/191int main(int argc, char * argv[])192{193FILE * inputFile;194struct ToSpawn * spawnChain = NULL;195196if (argc != 2) {197fprintf(stderr,"Expected 1 argument, got %d\n",argc-1);198return 1;199}200201inputFile = fopen(argv[1],"r");202203if (NULL == inputFile) {204perror("Opening input file");205return 2;206}207208/* Set the environment variable to push spawns into the same AS*/209putenv("_BPX_SHAREAS=MUST");210211spawnChain = parseInputFile(inputFile);212213fclose(inputFile);214215spawnAndWait(spawnChain);216217/*Deliberately end without freeing up*/218}219220221