📄 p4_sock_cr.c
字号:
{ 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 + -