⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 p4_sock_cr.c

📁 MPICH是MPI的重要研究,提供了一系列的接口函数,为并行计算的实现提供了编程环境.
💻 C
📖 第 1 页 / 共 2 页
字号:
				{		  int argc = 4;		  char *argv[4];		  static char port_str[6];		  snprintf (port_str, 6, "%d", serv_port);		  argv[1] = myhostname;		  argv[2] = port_str;		  rm_start (&argc, argv);		}		/*ALOG_SETUP(p4_local->my_id,ALOG_TRUNCATE);*/		return -2;	    } else if(rc<0) {		p4_error("net_create_slave: bproc_rfork",rc);	    } else {		p4_dprintfl(20, "bproc: (pid=%d) child pid is %d\n",getpid(),child_pid);	    }#else /* !SCYLD_BEOWULF */#if defined(HAS_RSHCOMMAND)	    strncpy( remote_shell, RSHCOMMAND, P4_MAX_PGM_LEN );	    /* Allow the environment variable "P4RSHCOMMAND" to                override the default choice */	    { char *p = getenv( "P4_RSHCOMMAND" ); 	    if (p && *p) strncpy( remote_shell, p, P4_MAX_PGM_LEN );	    }#endif#if defined(DELTA)	    p4_dprintf("delta cannot create remote processes\n");#else#if defined(P4BSD) && !defined(HAS_RSHCOMMAND)	    strcpy(remote_shell, "rsh");#endif/* RL - added || defined(RS6000) to get around afs problems.  In earlier   versions of AIX we could not use rsh since rsh was the restricted   shell, which has been renamed Rsh  */#if defined(P4SYSV) && !defined(HAS_RSHCOMMAND)#    if defined(TITAN) || defined(SGI) || defined(SUN_SOLARIS) || defined(RS6000)	    strcpy(remote_shell, "rsh");#    else#        if defined(SYMMETRY_PTX)	    strcpy(remote_shell, "resh");#        else	    strcpy(remote_shell, "remsh");#        endif#    endif#endif	    p4_dprintfl(20, "creating remote slave on %s via remote shell %s\n",host, remote_shell);	    sprintf(serv_port_c, "%d", serv_port);	    /* We should remember ALL of the children's pid's so we can 	       forcibly stop them if necessary */	    child_pid = rc = fork_p4();	    if (rc == 0)	    {/* define SHORT_CIRCUIT_LOCALHOST *//* This doesn't work yet.  redirection of stdin/out/error are undoubtedly   part of the problem.  We'll leave this for the next release */#ifdef SHORT_CIRCUIT_LOCALHOST		/* If host is localhost or myhost, then we don't need to run 		   remote shell (do we? what about stdin/out/err?) */		if (strcmp( host, "localhost" ) == 0 ||		    strcmp( myhostname, host ) == 0) { 		    p4_dprintfl( 80, "Not using rsh to localhost\n" );		    rc = execlp(pgm, pgm,			    myhostname, serv_port_c, am_slave_c, 			    "-p4yourname", host, "-p4rmrank", rm_rank_str, 				NULL);		}		else {		    rc = execlp(remote_shell, remote_shell,			    host, #if !defined(RSH_HAS_NO_L)			    "-l", username, #endif			    "-n", pgm,			    myhostname, serv_port_c, am_slave_c, #ifdef HAVE_BROKEN_RSH			    "\\-p4yourname", host, "\\-p4rmrank", rm_rank_str,#else			    "-p4yourname", host, "-p4rmrank", rm_rank_str,#endif				NULL);		}#else#   if defined(HAVE_BROKEN_RSH)		/* This must be in this branch because the backslash 		   is not stripped off if rsh is not used */		/* On some LINUX systems, it was necessary to escape the		   - in -p4amslave.  It is reported that current systems		   do not require this, but it should be safe. */		am_slave_c = "\\-p4amslave";#   endif/* #define RSH_NEEDS_OPTS */#ifdef RSH_NEEDS_OPTS		/* The following code allows the remote shell command string		   to include additional command line options, such as		   ssh -q */		{		    char *argv[64];		    char rshell_string[P4_MAX_PGM_LEN];		    char *next_parm;		    int argcount = 0;		    strcpy( rshell_string, remote_shell );		    /* Find the first blank, set next_parm to the next char,		       and set the blank to null.  If no next_parm, leave		       it pointing at the null */		    next_parm = strchr( rshell_string, ' ' );		    if (next_parm) {			*next_parm++ = 0;		    }		    argv[argcount++] = rshell_string;		    argv[argcount++] = host;#if !defined(RSH_HAS_NO_L)		    argv[argcount++] = "-l";		    argv[argcount++] = username;#endif		    while (next_parm && argcount < 51) {			argv[argcount++] = next_parm;			next_parm = strchr( next_parm, ' ' );			if (next_parm) {			    *next_parm++ = 0;			}		    }		    argv[argcount++] = "-n";		    argv[argcount++] = pgm;		    argv[argcount++] = myhostname;		    argv[argcount++] = serv_port_c;		    argv[argcount++] = am_slave_c;#ifdef HAVE_BROKEN_RSH		    argv[argcount++] = "\\-p4yourname";#else		    argv[argcount++] = "-p4yourname";#endif		    argv[argcount++] = host;#ifdef HAVE_BROKEN_RSH		    argv[argcount++] = "\\-p4rmrank";#else		    argv[argcount++] = "-p4rmrank";#endif		    argv[argcount++] = rm_rank_str;		    argv[argcount++] = 0;		    rc = execvp( rshell_string, argv );		}		    /* ENOEXEC - unrecognized executable,		       ENOENT  - file no found */#else		{ /* Code to pass environment variables for MPICH-G2 (RL) */		    char *p;		    p = getenv( "P4_SETS_ALL_ENVVARS" ); 		    if ( p ) {			/* This code prepends "setenv FOO BAR;setenv FAZZ BAZZ; ..." to			   the program name to be rsh'd */			/* This code needs more stringent attention to string lengths */                        /*                      ^^^^^^                                */			extern char **environ;			int i, pgm_prefix_len;#                       define MAX_PGM_PREFIX_LEN 1024			char pgm_prefix[MAX_PGM_PREFIX_LEN], *c;			char envvar_buf[256], setenv_buf[256], varname[256], varvalue[1024];			p4_dprintfl( 10, "P4_SETS_ALL_ENVVARS is set\n"); 			pgm_prefix_len = 0;			for (i = 0; environ[i] != NULL; i++ ) { 			    p4_dprintfl( 90, "environ[%d]: %s\n", i, environ[i] );			    pgm_prefix_len += strlen(environ[i]);			}			/* prefix will need accumulated length plus room for i			   copies of "setenv ;" where i is the number of env vars */			pgm_prefix_len += i * strlen("setenv ;");			p4_dprintfl( 90, "prefix needs %d characters\n", pgm_prefix_len);			/* 256 seems to be limit of string passed to rsh through execlp *//*			if ( pgm_prefix_len > 256 - strlen(pgm) )			    p4_error( "environment-setting prefix would be too long: ",				      pgm_prefix_len);*/			pgm_prefix[0] = '\0';			for (i = 0; environ[i] != NULL; i++ ) { 			    /* separate name from value; add setenv cmd */			    strcpy(envvar_buf, environ[i] );			    c = strtok( envvar_buf, "=" ); /* get varname */			    strcpy( varname, c );			    /* here is where to exclude some env vars */			    if ( strcmp( varname, "P4_SETS_ALL_ENVVARS" ) == 0 )				continue;			    if ( strcmp( varname, "FOO" ) == 0 )				continue;			    if ( strcmp( varname, "PWD" ) == 0 )				continue;			    if ( strcmp( varname, "MACHTYPE" ) == 0 )				continue;			    if ( strcmp( varname, "SHLVL" ) == 0 )				continue;			    if ( strcmp( varname, "SHELL" ) == 0 )				continue;			    if ( strcmp( varname, "OSTYPE" ) == 0 )				continue;			    if ( strcmp( varname, "HOSTTYPE" ) == 0 )				continue;			    if ( strcmp( varname, "TERM" ) == 0 )				continue;			    if ( strcmp( varname, "PATH" ) == 0 )				continue;			    c = strtok( NULL, "\n" ); /* get varvalue */			    if ( c )				strcpy( varvalue, c );			    else				varvalue[0] = '\0';			    sprintf( setenv_buf, "setenv %s %s;", varname, varvalue);			    p4_dprintfl( 90, "setenv_buf = :%s:\n", setenv_buf );			    strcat( pgm_prefix, setenv_buf );			}			p4_dprintfl( 90, "prefix=:%s:\n", pgm_prefix );			/* now prepend to pgm if not too long */			if (strlen(pgm_prefix) + strlen(pgm) >= P4_MAX_PGM_LEN )			    p4_error("prefix too long", 0 );			else {			    strcat(pgm_prefix, pgm);			    strcpy(pgm, pgm_prefix);			}		    }		    /*		    p4_dprintf( "pgm argument to remote shell = :%s:\n", pgm );		    p4_dprintf( "length of pgm argument to remote shell = %d\n",				strlen(pgm) );		    */		}		rc = execlp(remote_shell, remote_shell,			    host, #if !defined(RSH_HAS_NO_L)			    "-l", username, #endif			    "-n", pgm,			    myhostname, serv_port_c, am_slave_c, #ifdef HAVE_BROKEN_RSH			    "\\-p4yourname", host, "\\-p4rmrank", rm_rank_str,#else			    "-p4yourname", host, "-p4rmrank", rm_rank_str,#endif			    NULL);#endif /* RSH_NEEDS_OPTS */#endif /* Short_circuit_localhost */		/* host,"-n","cluster","5",pgm,myhostname,serv_port_c,0); for butterfly */		if (rc < 0) {		    /* Trap common user errors and generate a more 		       helpful error message */		    char *pmsg = "net_create_slave: execlp";		    char fullmsg[512];		    switch (errno) {			/* noent - component of file doesn't exist */		    case ENOENT: pmsg = "Path to program is invalid"; 			break;			/* notdir - component of file isn't a directory */		    case ENOTDIR: 			pmsg = "A directory in the program path is not a valid directory"; 			break;			/* acces - Search permission denied, file not 			   executable */		    case EACCES: 			pmsg = "Program is not an executable or is not accessible"; break;			/* interrupt received! */		    case EINTR: pmsg = "Interrupt received while starting program"; break;		    default:			;		    }		    strcpy( fullmsg, pmsg );		    strcat( fullmsg, " while starting " );		    strncat( fullmsg, pgm, 511 );		    strncat( fullmsg, " with ", 511 );		    strncat( fullmsg, remote_shell, 511 );		    strncat( fullmsg, " on ", 511 );		    strncat( fullmsg, myhostname, 511 );		    p4_error(fullmsg, rc);		}	    }	    p4_dprintfl(10, "created remote slave on %s via remote shell\n",host);	    p4_dprintfl(90, "remote slave is running program %s as user %s\n",			pgm, username );#endif#endif /* SCYLD_BEOWULF */	}    }    /* WDG - There is a chance that we'll hang here forever.  Thus, we set a        timeout that causes the whole job to fail if we don't get a timely       response from the created process.  See MPIBUGS #989; I got a traceback        showing this exact problem.      */    curhostname = host;    active_fd = serv_fd;    SIGNAL_P4(SIGALRM,p4_accept_timeout);    {#ifndef CRAY    struct itimerval timelimit;    struct timeval tval;    struct timeval tzero;    tval.tv_sec		  = TIMEOUT_VALUE;    tval.tv_usec	  = 0;    tzero.tv_sec	  = 0;    tzero.tv_usec	  = 0;    timelimit.it_interval = tzero;       /* Only one alarm */    timelimit.it_value	  = tval;    setitimer( ITIMER_REAL, &timelimit, 0 );#else    alarm( TIMEOUT_VALUE );#endif    /*        If the user's program never starts and the forked child process       fails, then this step will hang (eventually failing due to the       timeout).  The p4 code in general needs to manage SIGCHLD,        but this gives a simple way to warn of problems.     */#ifndef SIGCHLD#define SIGCHLD SIGCLD#endif    SIGNAL_P4(SIGCHLD,p4_accept_sigchild)    slave_fd		  = net_accept(serv_fd);    /*        Thanks to Laurie Costello (lmc@cray.com) for this fix.  This        helps systems with broken rsh/rexec that don't properly use       fd_set in their code; this closes FDs that would otherwise       be held open when fork/exec is done to start remote jobs.      */    /* Some systems (like NeXT) don't define a name for the bit,        though they accept it */#ifndef FD_CLOEXEC#define FD_CLOEXEC 0x1#endif    fcntl_flags = fcntl(slave_fd, F_GETFD);    if (fcntl_flags == -1) {        p4_dprintfl(10, "fcntl F_GETFD failed for fd %d\n", slave_fd);    } else {        fcntl_flags |= FD_CLOEXEC;        if (fcntl(slave_fd, F_SETFD, fcntl_flags) < 0) {            p4_dprintfl(10, "fcntl for close on exec failed for fd %d\n", 			slave_fd);        }    }    /* Go back to default handling of alarms */    curhostname		  = 0;    child_pid		  = 0;#ifndef CRAY    timelimit.it_value	  = tzero;   /* Turn off timer */    setitimer( ITIMER_REAL, &timelimit, 0 );#else    alarm( 0 );#endif    active_fd             = -1;    SIGNAL_P4(SIGALRM,SIG_DFL);    /* We should be more careful about cigchld */    SIGNAL_P4(SIGCHLD,SIG_DFL);    }    hs.pid = (int) htonl(getpid());    hs.rm_num = 0;   /* To make Insight etc happy */    net_send(slave_fd, &hs, sizeof(hs), P4_FALSE);    net_recv(slave_fd, &hs, sizeof(hs));    return(slave_fd);}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -