/* * signal handlers */ static RETSIGTYPE sig_quit(int sig) { close_fifos(); fvwmSetTerminate(sig); SIGNAL_RETURN; }
/* * print error message on stderr */ void err_quit( const char *msg ) { fprintf (stderr, "%s ", strerror(errno)); err_msg(msg); close_fifos(); exit(1); }
/* * read fifo */ int read_f(int fd, char *p, int len) { int i, n; for (i=0; i<len; ) { n = read(fd, &p[i], len-i); if (n<0 && errno!=EAGAIN) { err_quit("reading message"); } if (n==0) { /* eof */ close_fifos(); exit(0); } i += n; } return len; }
/* * * send command to and receive message from the server * */ int main ( int argc, char *argv[]) { char cmd[MAX_MODULE_INPUT_TEXT_LEN + 1]; char *f_stem, *fc_name, *fm_name; char *sf_stem; char *s; int i; int opt; int ncnt; int count; int Rc; struct timeval tv2; extern char *optarg; extern int optind; #ifdef HAVE_SIGACTION { struct sigaction sigact; sigemptyset(&sigact.sa_mask); #ifdef SA_RESTART sigact.sa_flags = SA_RESTART; #else sigact.sa_flags = 0; #endif sigact.sa_handler = sig_ttin; sigaction(SIGTTIN, &sigact, NULL); sigaction(SIGTTOU, &sigact, NULL); sigaddset(&sigact.sa_mask, SIGINT); sigaddset(&sigact.sa_mask, SIGHUP); sigaddset(&sigact.sa_mask, SIGQUIT); sigaddset(&sigact.sa_mask, SIGTERM); #ifdef SA_INTERRUPT sigact.sa_flags = SA_INTERRUPT; #else sigact.sa_flags = 0; #endif sigact.sa_handler = sig_quit; sigaction(SIGINT, &sigact, NULL); sigaction(SIGHUP, &sigact, NULL); sigaction(SIGQUIT, &sigact, NULL); sigaction(SIGTERM, &sigact, NULL); sigaction(SIGPIPE, &sigact, NULL); } #else #ifdef USE_BSD_SIGNALS fvwmSetSignalMask( sigmask(SIGINT) | sigmask(SIGHUP) | sigmask(SIGQUIT) | sigmask(SIGTERM) | sigmask(SIGPIPE)); #endif signal(SIGINT, sig_quit); signal(SIGHUP, sig_quit); signal(SIGQUIT, sig_quit); signal(SIGTERM, sig_quit); signal(SIGPIPE, sig_quit); signal(SIGTTIN, sig_ttin); signal(SIGTTOU, sig_ttin); #ifdef HAVE_SIGINTERRUPT siginterrupt(SIGINT, 1); siginterrupt(SIGHUP, 1); siginterrupt(SIGQUIT, 1); siginterrupt(SIGTERM, 1); siginterrupt(SIGPIPE, 1); siginterrupt(SIGTTIN, 0); siginterrupt(SIGTTOU, 0); #endif #endif Opt_reply = 0; Opt_info = -1; f_stem = NULL; sf_stem = NULL; Opt_monitor = 0; Opt_stdin = 0; Opt_Serv = 0; Opt_flags = 2; Tv.tv_sec = 0; Tv.tv_usec = 500000; Rc = 0; Bg = 0; while( (opt = getopt( argc, argv, "S:hvF:f:w:i:rmc" )) != EOF ) { switch(opt) { case 'h': usage(); exit(0); break; case 'f': f_stem = optarg; break; case 'F': Opt_flags = atoi (optarg); break; case 'S': sf_stem = optarg; Opt_Serv = 1; break; case 'i': Opt_info = atoi( optarg ); break; case 'v': printf("%s %s\n", MYNAME, VERSION ); exit(0); case 'w': Tv.tv_usec = atoi( optarg ) % 1000000; Tv.tv_sec = atoi( optarg ) / 1000000; break; case 'm': Opt_monitor = 1; break; case 'r': Opt_reply = 1; break; case 'c': Opt_stdin = 1; break; case '?': exit(3); } } if( f_stem == NULL ) { if ((f_stem = fifos_get_default_name()) == NULL) { fprintf (stderr, "\n%s can't decide on fifo-name. " "Make sure that $FVWM_USERDIR is set.\n", MYNAME ); exit(1); } } /* create 2 fifos */ fm_name = safemalloc( strlen(f_stem) + 2 ); strcpy(fm_name,f_stem); strcat(fm_name, "M"); fc_name = safemalloc( strlen(f_stem) + 2 ); strcpy(fc_name,f_stem); strcat(fc_name, "C"); s = safemalloc( strlen(f_stem) + 2 ); strcpy(s,f_stem); strcat(s, "R"); Fdrun = open(s, O_WRONLY | O_CREAT | O_EXCL | O_NOFOLLOW, 0600); if (Fdrun < 0) { FILE *f; if ((f = fopen (s,"r" )) != NULL) { char *p; *cmd = 0; p = fgets(cmd, 20, f); (void)p; fclose(f); fprintf (stderr, "\nFvwmCommand lock file %sR is detected. " "This may indicate another FvwmCommand is running. " "It appears to be running under process ID:\n%s\n", f_stem, (*cmd) ? cmd : "(unknown)" ); fprintf (stderr, "You may either kill the process or run FvwmCommand " "with another FIFO set using option -S and -f. " "If the process doesn't exist, simply remove file:\n%sR\n\n", f_stem); exit(1); } else { err_quit ("writing lock file"); } } Fr_name = s; if( Opt_Serv ) { int n; sprintf (cmd,"%s '%sS %s'", argv[0], MYNAME, sf_stem); n = system (cmd); (void)n; } { char buf[64]; int n; sprintf(buf, "%d\n", (int)getpid()); n = write(Fdrun, buf, strlen(buf)); (void)n; close(Fdrun); } Fdr = Fdw = -1; count = 0; while ((Fdr=open (fm_name, O_RDONLY | O_NOFOLLOW)) < 0) { if (count++>5) { err_quit ("opening message fifo"); } sleep(1); } count = 0; while ((Fdw=open (fc_name, O_WRONLY | O_NOFOLLOW)) < 0) { if (count++>2) { err_quit ("opening command fifo"); } sleep(1); } i = optind; if (Opt_stdin) { while (fgets(cmd, MAX_MODULE_INPUT_TEXT_LEN - 1, stdin)) { sendit(cmd); } } else if( Opt_monitor ) { /* test if its stdin is closed for coprocess */ tv2.tv_sec = 0; tv2.tv_usec = 5; FD_ZERO(&fdset); FD_SET(STDIN_FILENO, &fdset); ncnt = fvwmSelect(FD_SETSIZE, &fdset, 0, 0, &tv2); if( ncnt && (fgets( cmd, 1, stdin )==0 || cmd[0] == 0)) { Bg = 1; } /* line buffer stdout for coprocess */ setvbuf( stdout, NULL, _IOLBF, 0); /* send arguments first */ for( ;i < argc; i++ ) { strncpy( cmd, argv[i], MAX_MODULE_INPUT_TEXT_LEN - 1 ); sendit( cmd ); } while( !isTerminated ) { FD_ZERO(&fdset); FD_SET(Fdr, &fdset); if( Bg == 0 ) { FD_SET(STDIN_FILENO, &fdset); } ncnt = fvwmSelect(FD_SETSIZE, &fdset, 0, 0, NULL); /* message from fvwm */ if (FD_ISSET(Fdr, &fdset)) { process_message(); } if( Bg == 0 ) { /* command input */ if( FD_ISSET(STDIN_FILENO, &fdset) ) { if( fgets( cmd, MAX_MODULE_INPUT_TEXT_LEN - 1, stdin ) == 0 ) { if( Bg == 0 ) { /* other than SIGTTIN */ break; } continue; } sendit( cmd ); } } } } else { for( ;i < argc; i++ ) { strncpy( cmd, argv[i], MAX_MODULE_INPUT_TEXT_LEN - 1 ); sendit( cmd ); if (Opt_info >= 0) receive(); } } close_fifos(); return Rc; }
int run_test(int argc, char **argv, unsigned int test_num, Test *test, char **fifos) { char *in_file = NULL; int in_fd = -1; char **out_files = NULL; int *out_fds = NULL; int fifo_fds[MAX_READERS]; pid_t child = 0; int i, res = 0, wres; /* Write some information about the test to the log */ print_test_info(test_num, test); assert(test->npipes <= MAX_READERS); for (i = 0; i < MAX_READERS; i++) fifo_fds[i] = -1; /* Open any output files needed */ if (test->nfiles > 0) { if (0 != get_output_files(test, &out_files, &out_fds)) goto BAIL; } /* Create an input file if the test needs one */ if (test->in_type == IN_FILE) { if (NULL == (in_file = get_input_file(test))) goto BAIL; } /* Start the program under test */ child = start_prog(argc, argv, test, &in_fd, in_file, fifos, out_files); if (child < 0) goto BAIL; /* Open any named pipes required */ if (test->npipes > 0) { if (0 != open_fifos(test->npipes, fifos, fifo_fds)) goto BAIL; } if (test->npipes) { /* reading from pipes, run the full poll loop */ res = run_poll_loop(test, in_fd, fifo_fds, fifos); /* Close any pipes that are still open */ if (0 != close_fifos(test->npipes, fifos, fifo_fds)) { res = -1; } } else if (test->in_type == IN_PIPE || test->in_type == IN_SLOW_PIPE) { /* only sending to a pipe, so just shove the data down it */ size_t offset = 0; if (gen_data("pipe", in_fd, test->in_len, &offset, 0, 0) != test->in_len) { res = -1; } if (0 != close(in_fd)) { perror("Closing pipe"); res = -1; } } /* Wait for the program to finish and check the exit status */ wres = wait_child(child); if (-99 == wres) goto BAIL; if (wres < 0) res = -1; /* Check the contents of any regular files that were created */ if (test->nfiles > 0) { if (0 != check_output_files(test, out_fds, out_files)) res = -1; } /* Clean up */ if (NULL != in_file) remove_files(&in_file, 1); if (test->nfiles > 0) { remove_files(out_files, test->nfiles); } return res; BAIL: /* Something went wrong, clean up and return 99 */ if (NULL != in_file) remove_files(&in_file, 1); if (test->nfiles > 0 && NULL != out_files) { remove_files(out_files, test->nfiles); } if (test->npipes > 0) { close_fifos(test->npipes, fifos, fifo_fds); } return 99; }