DataMuseum.dkPresents historical artifacts from the history of: Rational R1000/400 Tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Rational R1000/400 Tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - downloadIndex: ┃ T r ┃
Length: 8499 (0x2133) Types: TextFile Names: »remote_sh.c«
└─⟦8ee07855d⟧ Bits:30000545 8mm tape, Rational 1000, DTIA 2_1_6 └─ ⟦0c25cb74a⟧ »DATA« └─⟦038380b96⟧ └─⟦d0624311f⟧ Bits:30000529 8mm tape, Rational 1000, DTIA 2_1_7 └─ ⟦f494b5154⟧ »DATA« └─⟦038380b96⟧ └─ ⟦this⟧ »remote_sh.c« └─⟦8ee07855d⟧ Bits:30000545 8mm tape, Rational 1000, DTIA 2_1_6 └─ ⟦0c25cb74a⟧ »DATA« └─⟦0732ea0cf⟧ └─⟦d0624311f⟧ Bits:30000529 8mm tape, Rational 1000, DTIA 2_1_7 └─ ⟦f494b5154⟧ »DATA« └─⟦0732ea0cf⟧ └─ ⟦this⟧ »../../dtia/release_apollo_2.1/remote_sh.c« └─⟦8ee07855d⟧ Bits:30000545 8mm tape, Rational 1000, DTIA 2_1_6 └─ ⟦0c25cb74a⟧ »DATA« └─⟦25fab149a⟧ └─⟦d0624311f⟧ Bits:30000529 8mm tape, Rational 1000, DTIA 2_1_7 └─ ⟦f494b5154⟧ »DATA« └─⟦25fab149a⟧ └─ ⟦this⟧ »../../dtia/release_sun_2.1/remote_sh.c« └─⟦8ee07855d⟧ Bits:30000545 8mm tape, Rational 1000, DTIA 2_1_6 └─ ⟦0c25cb74a⟧ »DATA« └─⟦be254d495⟧ └─⟦d0624311f⟧ Bits:30000529 8mm tape, Rational 1000, DTIA 2_1_7 └─ ⟦f494b5154⟧ »DATA« └─⟦be254d495⟧ └─ ⟦this⟧ »../../dtia/release_aix_2.1/remote_sh.c« └─⟦8ee07855d⟧ Bits:30000545 8mm tape, Rational 1000, DTIA 2_1_6 └─ ⟦0c25cb74a⟧ »DATA« └─⟦c67979795⟧ └─⟦d0624311f⟧ Bits:30000529 8mm tape, Rational 1000, DTIA 2_1_7 └─ ⟦f494b5154⟧ »DATA« └─⟦c67979795⟧ └─ ⟦this⟧ »../../dtia/release_hp_2.1/remote_sh.c«
#ifndef lint #ifndef DEBUG static char SCCS_id[] = "@(#)remote_sh.c 2.1 90/08/02 19:04:10 Copyright(c) 1990 by Rational."; #else static char SCCS_id[] = "@(#)remote_sh.c DEBUG 2.1 90/08/02 19:04:10 Copyright(c) 1990 by Rational."; #endif #endif #define REMOTE_SH #include "talk.h" #undef REMOTE_SH typedef int (*PFRI)(); /* Ptr to Fct Returning Integer */ typedef int (*PFRV)(); /* Ptr to Fct Returning Void */ static int shell_pid= -1; /* the pid of the remote shell */ static int pipe_in[2]; /* stdin of the remote shell */ static int pipe_out[2]; /* stdout of the remote shell */ static int pipe_err[2]; /* stderr of the remote shell */ static int eof_out=FALSE; /* Is stdout of RS finished? */ static int eof_err=FALSE; /* Is stderr of RS finished? */ #define NULL_FCT ((PFRI)NULL) int is_eof_reached() { return ( ( shell_pid == -1 ) || ( eof_out && eof_err) ); } static int my_write(fd,s,lg_total) int fd; char *s; int lg_total; { int lg_wrote,lg; lg_wrote=0; while (lg_wrote<lg_total) { lg = write(fd, s, lg_total - lg_wrote); if (lg == -1) { #ifdef DEBUG1 trace_msg("My_Write returns <-1>\n"); #endif return -1; } else { lg_wrote += lg; s += lg; } } #ifdef DEBUG1 trace_msg2("My_Write returns <%d>\n",lg_wrote); #endif return lg_wrote; } static int my_read(fd,s,l) int fd; char *s; int l; { int lg_read; while ((lg_read=read(fd,s,l))==-1) { if (errno==EINTR) continue; } return lg_read; } static void raz_remote_shell() { shell_pid= -1; close(pipe_in[1]); close(pipe_out[0]); close(pipe_err[0]); eof_out=eof_err=FALSE; } int kill_remote_shell() { /* In case of a problem a signal 9 will make sure that */ /* the remote shell is completely dead */ int retour=0; int sh_pid; if (shell_pid!= -1) { sh_pid = shell_pid; raz_remote_shell(); if (killpg(sh_pid,SIGKILL)== -1) retour = -1; else if (wait_pid(sh_pid)== -1) retour = -2; } return retour; } extern char **environ; static int init_remote_shell() { #define MOVE_FD(f1,f2) if(f1-f2){dup2(f1,f2);close(f1);} fd_set mask_w,mask_r; /* Let's open the three pipes */ #ifdef DEBUG1 trace_msg("Entering Init_Remote_Shell\n"); #endif if (pipe(pipe_in)== -1) return -1; if (pipe(pipe_out)== -1) return -1; if (pipe(pipe_err)== -1) return -1; eof_out=eof_err=FALSE; #ifdef DEBUG1 trace_msg("The three pipes are opened\n"); #endif switch (shell_pid=fork()) { case -1: #ifdef DEBUG1 trace_msg("Fork failed\n"); #endif return -1; case 0: /* The son */ /* Let's attach the three pipes to the */ /* stdin, stdout and stderr of the RS */ close(pipe_in[1]); MOVE_FD(pipe_in[0],0); close(pipe_out[0]); MOVE_FD(pipe_out[1],1); close(pipe_err[0]); MOVE_FD(pipe_err[1],2); /* The last six tricky lines are the */ /* "standard idiom" described chapter */ /* "Pipes" of "C Programmer's guide" */ if (setpgrp(0,getpid())== -1) { return -1; } /* Process group set */ execle( get_user_shell(), get_user_shell(), (char *)NULL,environ); /* Should never arrive here but if so ... */ return -1; default: /* The father */ close(pipe_in[0]); close(pipe_out[1]); close(pipe_err[1]); /* Got rid of the pipes used by the son */ #ifdef DEBUG1 trace_msg("Fork Succeeded\n"); #endif return 0; } } static int write_secure(fd,s,l) int fd; char *s; int l; { /* Before writing something, make sure somebody is listening */ int ret_select; fd_set mask_w; struct timeval t; #ifdef DEBUG1 trace_msg("Entering Write_Secure\n"); #endif t.tv_sec=0; t.tv_usec=1000; FD_ZERO(&mask_w); FD_SET(fd,&mask_w); while ((ret_select=select(getdtablesize(),(fd_set *)NULL,&mask_w, (fd_set *)NULL,&t)) == -1) { #ifdef DEBUG1 trace_msg("Select returns -1\n"); #endif if (errno == EINTR) continue; return -1; } #ifdef DEBUG1 trace_msg2("Select returns <%d>\n",ret_select); #endif if (ret_select==0) return -1; return(my_write(fd,s,l)); } static int write_remote(s,l) char *s; int l; { int lg= -1; if (shell_pid!= -1) { if ((lg=write_secure(pipe_in[1],s,l))== -1) { kill_remote_shell(); } } #ifdef DEBUG1 trace_msg2("Write_Remote returns <%d>\n",lg); #endif return lg; } /* To send a signal to the Remote Shell */ int signal_to_remote_shell(sig) int sig; { return (shell_pid == -1)?-2:killpg(shell_pid,sig); } /* To get the masks for expected fd */ /* to be read from the Remote Shell */ /* Useful for a select in the caller */ int set_remote_shell_masks_rw(mask_r,mask_w) fd_set *mask_r; fd_set *mask_w; { if (shell_pid!= -1) { if (mask_r) { if (!eof_out) { FD_SET(pipe_out[0],mask_r); } if (!eof_err) { FD_SET(pipe_err[0],mask_r); } } if (mask_w) { FD_SET(pipe_in[1],mask_w); } } } int is_it_remote_shell_read(mask) fd_set *mask; { if (shell_pid!= -1) return ( FD_ISSET(pipe_out[0],mask) || FD_ISSET(pipe_err[0],mask) ); else return (FALSE); } /* Let's look at the Remote Shell's answer */ int read_remote_shell(mask,out_fct,err_fct,fin,fout) fd_set *mask; PFRI out_fct,err_fct; int fin,fout; { #define MAX_SIZE_BUFFER 1000 static char buffer[MAX_SIZE_BUFFER]; int lg_buffer; PFRI where_to_write; int what_to_read; int *what_eof; #ifdef DEBUG1 trace_msg("Entering Read_Remote_Shell\n"); #endif if (shell_pid!= -1) { /* Is it a stdout or stderr message or an error */ if (FD_ISSET(pipe_err[0],mask)) { /* err */ where_to_write=err_fct; what_to_read=pipe_err[0]; what_eof= &eof_err; } else if (FD_ISSET(pipe_out[0],mask)) { /* out */ where_to_write=out_fct; what_to_read=pipe_out[0]; what_eof= &eof_out; } else { /* ??? */ where_to_write=NULL_FCT; what_to_read= -1; what_eof=(int *)NULL; } if (where_to_write==NULL_FCT) { kill_remote_shell(); return -1; } else { lg_buffer=my_read(what_to_read,buffer,MAX_SIZE_BUFFER); if (lg_buffer== -1) { #ifdef DEBUG1 trace_msg("Read Failed\n"); #endif kill_remote_shell(); return -1; } else if (lg_buffer==0) { /* EOF */ #ifdef DEBUG1 trace_msg("Read EOF\n"); #endif *what_eof=TRUE; return 0; } else { #ifdef DEBUG1 trace_msg2("Read <%d> Characters\n",lg_buffer); #endif (*where_to_write)(fin,fout,buffer,lg_buffer); #ifdef DEBUG1 trace_msg("Where_To_Write Done\n"); #endif return lg_buffer; } } } else { return -1; } #undef MAX_SIZE_BUFFER } static jmp_buf env_sig_pipe; static void fct_sig_pipe() { #ifdef DEBUG1 trace_msg("INTERRUPTED (SIGPIPE)\n"); #endif longjmp(env_sig_pipe,1); } /* To feed the Remote Shell with an input */ int some_input_to_remote_shell(new_command,s,init_done) int new_command; char *s; int *init_done; { PFRV old_fct_sig_pipe; fd_set mask_w; struct timeval t; t.tv_sec=0; t.tv_usec=1000; FD_ZERO(&mask_w); FD_SET(pipe_in[1],&mask_w); if (init_done) *init_done=FALSE; (void)wait_pid(shell_pid); if ((shell_pid != -1) && (new_command)) { /* Is the shell still THERE? */ if (kill(shell_pid,SIGINT) == -1) { kill_remote_shell(); } } if (shell_pid== -1) { if (init_remote_shell()== -1) { raz_remote_shell(); return -1; } else if (init_done) *init_done=TRUE; } if (shell_pid != -1) { if (setjmp(env_sig_pipe)) { #ifdef DEBUG1 trace_msg("Entering SIGPIPE Env\n"); #endif kill_remote_shell(); if (init_remote_shell()==-1) { raz_remote_shell(); return -1; } else if (init_done) *init_done=TRUE; (void)signal(SIGPIPE,old_fct_sig_pipe); } else { #ifdef DEBUG1 trace_msg("Env for SIGPIPE set\n"); #endif old_fct_sig_pipe = (PFRV)signal(SIGPIPE,fct_sig_pipe); } } if (write_remote(s,strlen(s))== -1) { #ifdef DEBUG1 trace_msg2("Write Remote <%s> Failed\n",s); #endif old_fct_sig_pipe = (PFRV)signal(SIGPIPE,fct_sig_pipe); return -1; } else { #ifdef DEBUG1 trace_msg2("Write Remote <%s> Succeeded\n",s); #endif old_fct_sig_pipe = (PFRV)signal(SIGPIPE,fct_sig_pipe); return 0; } } int get_status(status) int *status; { char c; int i,l,res; int minus=FALSE; #define ECHO_STATUS "echo $exit_status\n" #define BUFFER_SIZE 10 char buffer[BUFFER_SIZE]; *status = res = 0; if (is_nilshell()) return (0); if (write_remote(ECHO_STATUS,strlen(ECHO_STATUS)) == -1) return errno; if ((l = read(pipe_out[0],buffer,BUFFER_SIZE)) <= 0) return errno; if (buffer[0]=='-') minus=TRUE; for (i = minus?1:0 ; i < l ; i++) { c = buffer[i]; if (c < '0') break; if (c > '9') break; res *= 10; res += (c - '0'); } *status = minus?-res:res; return (0); }