コード例 #1
0
ファイル: 4-1.c プロジェクト: shubmit/shub-ltp
int main()
{
	int pid, i;
	union sigval value;
	struct sigaction act;

	act.sa_flags = SA_SIGINFO;
	act.sa_sigaction = myhandler;
	sigemptyset(&act.sa_mask);
	sigaction(SIGTOTEST, &act, 0);

	pid = getpid();

	sighold(SIGTOTEST);

	for (i=0; i<NUMCALLS; i++) {
		value.sival_int = i;	/* i is just an arbitrary value */
		if (sigqueue(pid, SIGTOTEST, value) != 0) {
			printf("Test UNRESOLVED: call to sigqueue did not return success\n");
			return PTS_UNRESOLVED;
		}
	}

	if (0 != counter) {
		printf("Test UNRESOLVED: handler called even though %d has not been removed from the signal mask\n", SIGTOTEST);
		return PTS_UNRESOLVED;
	}

	sigrelse(SIGTOTEST);

	if (NUMCALLS != counter) {
		printf("Test FAILED: %d was queued %d time(s) even though sigqueue was called %d time(s) for %d\n", SIGTOTEST, counter, NUMCALLS, SIGTOTEST);
		return PTS_FAIL;
	}
	return PTS_PASS;
}
コード例 #2
0
void
pause_on_sigusr( int which )
{
#if defined(HAVE_SIGPROCMASK) && defined(HAVE_SIGSET_T)
    sigset_t mask, oldmask;

    assert( which == 1 );
    sigemptyset( &mask );
    sigaddset( &mask, SIGUSR1 );

    sigprocmask( SIG_BLOCK, &mask, &oldmask );
    while( !caught_sigusr1 )
	sigsuspend( &oldmask );
    caught_sigusr1 = 0;
    sigprocmask( SIG_UNBLOCK, &mask, NULL );
#else 
     assert (which == 1);
     sighold (SIGUSR1);
     while (!caught_sigusr1)
         sigpause(SIGUSR1);
     caught_sigusr1 = 0;
     sigrelse(SIGUSR1);
#endif /*! HAVE_SIGPROCMASK && HAVE_SIGSET_T */
}
コード例 #3
0
ファイル: main.c プロジェクト: danielsson/turtle-shell
/**
 * execute the checkEnv command.
 */
void cmd_check_env(char *args[ARGS_SIZE]) {
    int fd_descriptor_env_sort[2];
    int fd_descriptor_sort_pager[2];
    int fd_descriptor_grep_sort[2];
    pid_t env_child, sort_child, grep_child, pager_child;
    int grep = FALSE;
    int return_value;

    sighold(SIGCHLD);

    create_pipe(fd_descriptor_env_sort);
    create_pipe(fd_descriptor_sort_pager);
    create_pipe(fd_descriptor_grep_sort);
    env_child = fork();

    if (env_child == 0) {
        return_value = dup2(fd_descriptor_env_sort[PIPE_WRITE], STDOUT_FILENO);
        check_return_value(return_value, "Error: cannot dup2 1");

        close_all_pipes(fd_descriptor_env_sort, fd_descriptor_sort_pager, fd_descriptor_grep_sort);

        print_environment();
        exit(EXIT_SUCCESS);

    } else if (env_child == -1) {
        perror("Error forking.");
        exit(EXIT_FAILURE);
    }

    if(args[1] != NULL) {
        grep = TRUE;
        grep_child = fork();

        if(grep_child == 0) {
            return_value = dup2(fd_descriptor_env_sort[PIPE_READ], STDIN_FILENO);
            check_return_value(return_value, "Error: cannot dup2 2");

            return_value = dup2(fd_descriptor_grep_sort[PIPE_WRITE], STDOUT_FILENO);
            check_return_value(return_value, "Error: cannot dup2 3");

            close_all_pipes(fd_descriptor_env_sort, fd_descriptor_sort_pager, fd_descriptor_grep_sort);

            args[0] = "grep";

            return_value = execvp(args[0], args);
            check_return_value(return_value, "Error: execution failed.");
        } else if(grep_child == -1){
            perror("Error forking.");
            exit(EXIT_FAILURE);
        }
    }

    sort_child = fork();

    if (sort_child == 0) {
        char * argp[] = {"sort", NULL};

        if(grep == TRUE) {
            return_value = dup2(fd_descriptor_grep_sort[PIPE_READ], STDIN_FILENO);
            check_return_value(return_value, "Error: cannot dup2 3");
        } else {
            return_value = dup2(fd_descriptor_env_sort[PIPE_READ], STDIN_FILENO);
            check_return_value(return_value, "Error: cannot dup2 4");
        }
        return_value = dup2(fd_descriptor_sort_pager[PIPE_WRITE], STDOUT_FILENO);
        check_return_value(return_value, "Error: cannot dup2 5");

        close_all_pipes(fd_descriptor_env_sort, fd_descriptor_sort_pager, fd_descriptor_grep_sort);

        args[0] = "sort";

        return_value = execvp(args[0], argp);
        check_return_value(return_value, "Error: execution failed.");

    } else if (sort_child == -1) {
        perror("Error forking.");
        exit(EXIT_FAILURE);
    }

    pager_child = fork();

    if (pager_child == 0) {
        char * argp[] = {"less", NULL};
        return_value = dup2(fd_descriptor_sort_pager[PIPE_READ], STDIN_FILENO);
        check_return_value(return_value, "Error: cannot dup2 6");

        close_all_pipes(fd_descriptor_env_sort, fd_descriptor_sort_pager, fd_descriptor_grep_sort);

        if(getenv("PAGER") != NULL) {
            argp[0] = getenv("PAGER");
        }

        return_value = execvp(argp[0], argp);
        check_return_value(return_value, "Error: execution failed.");

    } else if (pager_child == -1) {
        perror("Error forking.");
        exit(EXIT_FAILURE);
    }

    close_all_pipes(fd_descriptor_env_sort, fd_descriptor_sort_pager, fd_descriptor_grep_sort);

    wait_for_child();
    wait_for_child();
    wait_for_child();
    if(grep == TRUE) wait_for_child();

    sigrelse(SIGCHLD);
}
コード例 #4
0
ファイル: mmapstress09.c プロジェクト: CSU-GH/okl4_3.0
int
main(int argc, char *argv[])
{
    char *progname;
    unsigned c;
    extern char *optarg;
    unsigned nprocs = 0;
    unsigned procno;
    pid_t *pidarray=NULL;
    pid_t pid;
    uchar_t *buf, *ptr;
    unsigned int seed;
    int alarmtime = 0;
    struct sigaction sa;
    unsigned i, j;
    uchar_t data;
    int no_prob = 0;
    time_t t;
    int wait_stat;

    progname = *argv;
    pagesize = sysconf(_SC_PAGE_SIZE);

    if (argc < 2) {
        (void)fprintf(stderr, "usage: %s %s\n", progname, usage);
        anyfail();
    }

    while ((c = getopt(argc, argv, "mdrp:t:s:")) != -1) {
        switch (c) {
        case 'd':
            debug = 1;
            break;
        case 't':
            alarmtime = atoi(optarg) * 60;
            break;
        case 'p':
            nprocs = atoi(optarg);
            break;
        case 'm':
            dosync = 1;
            break;
        case 's':
            mapsize = atoi(optarg);
            if (mapsize < 0) {
                (void)fprintf(stderr, "error: negative "
                              "mapsize\n");
                anyfail();
            }
            break;
        case 'r':
            randloops = 1;
            break;
        default:
            (void)fprintf(stderr, "usage: %s %s\n", progname,
                          usage);
            anyfail();
        }
    }

    /* nprocs is unsigned */
    if (nprocs > 255) {
        (void)fprintf(stderr, "invalid nprocs %d - (range 0-255)\n",
                      nprocs);
        anyfail();
    }
    (void)time(&t);
//	(void)printf("%s: Started %s", argv[0], ctime(&t)); LTP Port

    seed = initrand();
    pattern = seed & 0xff;

    if (debug) {
        (void)printf("%s mapsize %d bytes, pattern %d\n",
                     progname, mapsize, pattern);
        if (alarmtime)
            (void)printf("running for %d minutes\n", alarmtime/60);
        else
            (void)printf("running with no time limit\n");
    }

    if ((mapaddr = mmap(0, mapsize, PROT_READ|PROT_WRITE,
                        MAP_ANONYMOUS|MAP_SHARED, 0, 0))
            == (caddr_t)-1) {
        perror("mmap error");
        anyfail();
    }

    if ((buf = (uchar_t *)malloc(pagesize)) == NULL
            || (pidarray = (pid_t *)malloc(nprocs*sizeof(pid_t))) == NULL) {
        perror("malloc error");
        anyfail();
    }

    for (i = 0; i < nprocs; i++)
        *(pidarray+i) = 0;

    /*
     * Initialize page compare buffer, then initialize map.
     */

    for (i = 0, data = 0; i < pagesize; i++) {
        *(buf+i) = (data + pattern) & 0xff;
        if (++data == nprocs)
            data = 0;
    }

    mappages = roundup(mapsize, pagesize)/pagesize;
    ptr = (uchar_t *)mapaddr;

    for (i = 0; i < mappages; i++) {
        for (j = 0; j < pagesize; j++)
            *ptr++ = *(buf+j);
    }

    /*
     *  Fork off mmap children.
     */
    for (procno = 0; procno < nprocs; procno++) {
        switch (pid = fork()) {

        case -1:
            perror("fork error");
            goto cleanup;

        case 0:
            child_mapper(procno, nprocs);
            exit(0);

        default:
            pidarray[procno] = pid;
        }
    }

    /*
     *  Plan for death by signal.  User may have specified
     *  a time limit, in which set an alarm and catch SIGALRM.
     *  Also catch and cleanup with SIGINT.
     */
    sa.sa_handler = finish;
    sa.sa_flags = 0;
    if (sigemptyset(&sa.sa_mask)) {
        perror("sigemptyset error");
        goto cleanup;
    }

    if (sigaction(SIGINT, &sa, 0) == -1) {
        perror("sigaction error");
        goto cleanup;
    }

    if (alarmtime) {
        if (sigaction(SIGALRM, &sa, 0) == -1) {
            perror("sigaction error");
            goto cleanup;
        }
        (void)alarm(alarmtime);
    }

    /*
     *  Now wait for children and refork them as needed.
     */

    while (!finished) {
        do {
            pid = wait(&wait_stat);
        } while (pid == -1 && errno == EINTR);
        /*
         *  Block signals while processing child exit.
         */

        if (sighold(SIGALRM) || sighold(SIGINT)) {
            perror("sighold error");
            goto cleanup;
        }

        if (pid != -1) {
            /*
             *  Check exit status, then refork with the
             *  appropriate procno.
             */
            if (!WIFEXITED(wait_stat)
                    || WEXITSTATUS(wait_stat) != 0) {
                (void)fprintf(stderr, "child exit with err "
                              "<x%x>\n", wait_stat);
                goto cleanup;
            }
            for (i = 0; i < nprocs; i++)
                if (pid == pidarray[i])
                    break;
            if (i == nprocs) {
                (void)fprintf(stderr,
                              "unknown child pid %d, <x%x>\n",
                              pid, wait_stat);
                goto cleanup;
            }

            if ((pid = fork()) == -1) {
                perror("fork error");
                pidarray[i] = 0;
                goto cleanup;
            } else if (pid == 0) {		/* child */
                child_mapper(i, nprocs);
                exit(0);
            } else
                pidarray[i] = pid;
        } else {
            /*
             *  wait returned an error.  If EINTR, then
             *  normal finish, else it's an unexpected
             *  error...
             */
            if (errno != EINTR || !finished) {
                perror("unexpected wait error");
                goto cleanup;
            }
        }
        if (sigrelse(SIGALRM) || sigrelse(SIGINT)) {
            perror("sigrelse error");
            goto cleanup;
        }
    }

    /*
     *  Finished!  Check the map for sanity, then kill all
     *  the children and done!.
     */

    if (sighold(SIGALRM)) {
        perror("sighold error");
        goto cleanup;
    }
    (void)alarm(0);
    no_prob = 1;

cleanup:
    for (i = 0; i < nprocs; i++)
        (void)kill(pidarray[i], SIGKILL);	/* failure? oh well. */

    while (wait(&wait_stat) != -1 || errno != ECHILD)
        continue;

    if (no_prob) {		/* only check file if no errors */
        if (!mapokay(buf)) {
            (void)fprintf(stderr, "map data incorrect!\n");
            anyfail();
        }
        else
            (void)printf("map data okay\n");
    }

    (void)time(&t);
//	(void)printf("%s: Finished %s", argv[0], ctime(&t)); LTP POrt
    ok_exit();
    return(0);
}
コード例 #5
0
ファイル: pkgtrans.c プロジェクト: apprisi/illumos-gate
int
pkgtrans(char *device1, char *device2, char **pkg, int options,
    keystore_handle_t keystore, char *keystore_alias)
{
	int			r;
	struct sigaction	nact;
	struct sigaction	oact;

	/*
	 * setup signal handlers for SIGINT and SIGHUP and release hold
	 */

	/* hold SIGINT/SIGHUP interrupts */

	(void) sighold(SIGHUP);
	(void) sighold(SIGINT);

	/* hook SIGINT to sigtrap */

	nact.sa_handler = sigtrap;
	nact.sa_flags = SA_RESTART;
	(void) sigemptyset(&nact.sa_mask);

	if (sigaction(SIGINT, &nact, &oact) < 0) {
		sigintHandler = SIG_DFL;
	} else {
		sigintHandler = oact.sa_handler;
	}

	/* hook SIGHUP to sigtrap */

	nact.sa_handler = sigtrap;
	nact.sa_flags = SA_RESTART;
	(void) sigemptyset(&nact.sa_mask);

	if (sigaction(SIGHUP, &nact, &oact) < 0) {
		sighupHandler = SIG_DFL;
	} else {
		sighupHandler = oact.sa_handler;
	}

	/* reset signal received count */

	signal_received = 0;

	/* release hold on signals */

	(void) sigrelse(SIGHUP);
	(void) sigrelse(SIGINT);

	/*
	 * perform the package translation
	 */

	r = _pkgtrans(device1, device2, pkg, options, keystore, keystore_alias);

	/*
	 * reset signal handlers
	 */

	/* hold SIGINT/SIGHUP interrupts */

	(void) sighold(SIGHUP);
	(void) sighold(SIGINT);

	/* reset SIGINT */

	nact.sa_handler = sigintHandler;
	nact.sa_flags = SA_RESTART;
	(void) sigemptyset(&nact.sa_mask);

	(void) sigaction(SIGINT, &nact, (struct sigaction *)NULL);

	/* reset SIGHUP */

	nact.sa_handler = sighupHandler;
	nact.sa_flags = SA_RESTART;
	(void) sigemptyset(&nact.sa_mask);

	(void) sigaction(SIGHUP, &nact, (struct sigaction *)NULL);

	/* if signal received and pkgtrans returned error, call cleanup */

	if (signal_received > 0) {
		if (r != 0) {
			cleanup();
		}
		(void) kill(getpid(), SIGINT);
	}

	/* release hold on signals */

	(void) sigrelse(SIGHUP);
	(void) sigrelse(SIGINT);

	return (r);
}
コード例 #6
0
ファイル: mmapstress10.c プロジェクト: CSU-GH/okl4_3.0
int
main(int argc, char *argv[])
{
	char *progname;
	int fd;
	int c;
	extern char *optarg;
	unsigned nprocs = 0;
	unsigned procno;
	pid_t *pidarray=NULL;
	pid_t pid;
	pid_t wr_pid = 0;
	uchar_t *buf=NULL;
	unsigned int seed;
	int pagesize = sysconf(_SC_PAGE_SIZE);
	int alarmtime = 0;
	struct sigaction sa;
	unsigned i;
	int write_cnt;
	uchar_t data;
	int no_prob = 0;
	int wait_stat;
	time_t t;
#ifdef LARGE_FILE
	off64_t bytes_left;
#else /* LARGE_FILE */
	off_t bytes_left;
#endif /* LARGE_FILE */

	progname = *argv;
	tst_tmpdir();
	if (argc < 2) {
		(void)fprintf(stderr, "usage: %s %s\n", progname, usage);
		exit(1);
	}

	while ((c = getopt(argc, argv, "S:omdlrf:p:t:w:s:")) != -1) {
		switch (c) {
		case 'd':
			debug = 1;
			break;
		case 't':
			alarmtime = atoi(optarg) * 60;
			break;
		case 'p':
			nprocs = atoi(optarg);
			break;
		case 'l':
			leavefile = 1;
			break;
		case 's':
			sleeptime = atoi(optarg);
			if (sleeptime < 0) {
				(void)fprintf(stderr, "error: negative "
					"sleeptime\n");
                	        anyfail();
			}
			break;
		case 'w':
			growsize = atoi(optarg);
			if (growsize < 0) {
				(void)fprintf(stderr, "error: negative write "
					"size\n");
        	                anyfail();
			}
			break;
		case 'f':
#ifdef LARGE_FILE
			filesize = atoll(optarg);
#else /* LARGE_FILE */
			filesize = atoi(optarg);
#endif /* LARGE_FILE */
			if (filesize < 0) {
				(void)fprintf(stderr, "error: negative "
					"filesize\n");
                	        anyfail();
			}
			break;
		case 'r':
			randloops = 1;
			break;
		case 'm':
			dosync = 1;
			break;
		case 'o':
			do_offset = 1;
			break;
		case 'S':
#ifdef LARGE_FILE
			sparseoffset = atoll(optarg);
#else /* LARGE_FILE */
			sparseoffset = atoi(optarg);
#endif /* LARGE_FILE */
			if (sparseoffset % pagesize != 0) {
				fprintf(stderr, 
				   "sparseoffset must be pagesize multiple\n");
        	                anyfail();
			}
			break;
		default:
			(void)fprintf(stderr, "usage: %s %s\n", progname,
				usage);
			anyfail();
		}
	}

	if (nprocs > 255) {
		(void)fprintf(stderr, "invalid nprocs %d - (range 0-255)\n",
			nprocs);
                anyfail();
	}
	(void)time(&t);
	//(void)printf("%s: Started %s", argv[0], ctime(&t)); LTP Port

	(void)sprintf(filename, "%sout.%d", progname, getpid());
	seed = initrand();
	pattern = seed & 0xff;

	if (debug) {
#ifdef LARGE_FILE
		(void)printf("creating file <%s> with %Ld bytes, pattern %d\n", 
			filename, filesize, pattern);
#else /* LARGE_FILE */
		(void)printf("creating file <%s> with %ld bytes, pattern %d\n", 
			filename, filesize, pattern);
#endif /* LARGE_FILE */
		if (alarmtime)
			(void)printf("running for %d minutes\n", alarmtime/60);
		else
			(void)printf("running with no time limit\n");
	}

	/*
	 *  Plan for death by signal.  User may have specified
	 *  a time limit, in which case set an alarm and catch SIGALRM.
	 *  Also catch and cleanup with SIGINT, SIGQUIT, and SIGTERM.
	 */
	sa.sa_handler = finish;
	sa.sa_flags = 0;
	if (sigemptyset(&sa.sa_mask)) {
		perror("sigempty error");
		goto cleanup;
	}

	if (sigaction(SIGINT, &sa, 0) == -1) {
		perror("sigaction error SIGINT");
		goto cleanup;
	}
	if (alarmtime) {
		if (sigaction(SIGALRM, &sa, 0) == -1) {
			perror("sigaction error");
			goto cleanup;
		}
		(void)alarm(alarmtime);
	}
	/* If we get a SIGQUIT or SIGTERM, clean up and exit immediately. */
	sa.sa_handler = clean_up_file;
	if (sigaction(SIGQUIT, &sa, 0) == -1) {
		perror("sigaction error SIGQUIT");
		goto cleanup;
	}
	if (sigaction(SIGTERM, &sa, 0) == -1) {
		perror("sigaction error SIGTERM");
		goto cleanup;
	}

#ifdef LARGE_FILE
	if ((fd = open64(filename, O_CREAT|O_TRUNC|O_RDWR, 0664)) == -1) {
#else /* LARGE_FILE */
	if ((fd = open(filename, O_CREAT|O_TRUNC|O_RDWR, 0664)) == -1) {
#endif /* LARGE_FILE */
		perror("open error");
                anyfail();
	}

	if ((buf = (uchar_t *)malloc(pagesize+growsize)) == NULL
	    || (pidarray = (pid_t *)malloc(nprocs*sizeof(pid_t))) == NULL) {
		perror("malloc error");
                anyfail();
	}

	for (i = 0; i < nprocs; i++)
		*(pidarray+i) = 0;

	for (i = 0, data = 0; i < pagesize; i++) {
		*(buf+i) = (data + pattern) & 0xff;
		if (++data == nprocs)
			data = 0;
	}
	for (data = 0; i < pagesize+growsize; i++) {
		*(buf+i) = (data + pattern) & 0xff;
		if (++data == nprocs)
			data = 0;
	}

#ifdef LARGE_FILE
	if (lseek64(fd, sparseoffset, SEEK_SET) < 0) {
#else /* LARGE_FILE */
	if (lseek(fd, sparseoffset, SEEK_SET) < 0) {
#endif /* LARGE_FILE */
		perror("lseek");
               anyfail();
	}

	for (bytes_left = filesize; bytes_left; bytes_left -= c) {
		write_cnt = min(pagesize, bytes_left);
		if ((c = write(fd, (char *)buf, write_cnt)) != write_cnt) {
			if (c == -1) {
				perror("write error");
			} else {
				(void)fprintf(stderr, "write: wrote %d of %d "
					"bytes\n", c, write_cnt);
			}
			(void)close(fd);
			(void)unlink(filename);
			anyfail();
		}
	}

	(void)close(fd);

	/*
	 *  Fork off mmap children.
	 */
	for (procno = 0; procno < nprocs; procno++) {
		switch (pid = fork()) {

		case -1:
			perror("fork error");
			goto cleanup;

		case 0:
			child_mapper(filename, procno, nprocs);
			exit(0);

		default:
			pidarray[procno] = pid;
		}
	}

	/*
	 *  Now fork off an additional process to continually
	 *  write to (and grow) the file.
	 */
	if ((wr_pid = fork()) == -1) {
		perror("fork error");
		goto cleanup;
	} else if (wr_pid == 0) {	/* child */
		child_writer(filename, buf);
		exit(0);
	}

	/*
	 *  Now wait for children and refork them as needed.
	 */
	
	while (!finished) {
		pid = wait(&wait_stat);
		/*
		 *  Block signals while processing child exit.
		 */

		if (sighold(SIGALRM) || sighold(SIGINT)) {
			perror("sighold error");
			goto cleanup;
		}

		if (pid != -1) {
			/*
			 *  Check exit status, then refork with the
			 *  appropriate procno.
			 */
			if (!WIFEXITED(wait_stat) 
			    || WEXITSTATUS(wait_stat) != 0) {
				(void)fprintf(stderr, "child exit with err "
					"<x%x>\n", wait_stat);
				goto cleanup;
			}
			for (i = 0; i < nprocs; i++)
				if (pid == pidarray[i])
					break;
			if (i == nprocs) {
				if (pid == wr_pid) {
					(void)fprintf(stderr, 
					"writer child unexpected exit <x%x>\n",
						wait_stat);
					wr_pid = 0;
				} else
					(void)fprintf(stderr, "unknown child "
						"pid %d, <x%x>\n",
						pid, wait_stat);
				goto cleanup;
			}

			if ((pid = fork()) == -1) {
				perror("fork error");
				pidarray[i] = 0;
				goto cleanup;
			} else if (pid == 0) {		/* child */
				child_mapper(filename, i, nprocs);
				exit(0);
			} else
				pidarray[i] = pid;
		} else {
			/*
			 *  wait returned an error.  If EINTR, then
			 *  normal finish, else it's an unexpected
			 *  error...
			 */
			if (errno != EINTR || !finished) {
				perror("unexpected wait error");
				goto cleanup;
			}
		}
		if (sigrelse(SIGALRM) || sigrelse(SIGINT)) {
			perror("sigrelse error");
			goto cleanup;
		}
	}
	
	/*
	 *  Finished!  Check the file for sanity, then kill all
	 *  the children and done!.
	 */

	(void)alarm(0);
	no_prob = 1;

cleanup:
	for (i = 0; i < nprocs; i++)
		(void)kill(pidarray[i], SIGKILL);
	(void)kill(wr_pid, SIGKILL);

	while (wait(&wait_stat) != -1 || errno != ECHILD)
		continue;

	if (no_prob) {		/* only check file if no errors */
		if (!fileokay(filename, buf)) {
			(void)fprintf(stderr, "file data incorrect!\n");
			(void)printf("  leaving file <%s>\n", filename);
                        anyfail();

		} else {
			(void)printf("file data okay\n");
			if (!leavefile)
				(void)unlink(filename);
		}
	} else
		(void)printf("  leaving file <%s>\n", filename);
	
	(void)time(&t);
//	(void)printf("%s: Finished %s", argv[0], ctime(&t)); LTP Port
	ok_exit();
	return 0;
}


/*
 *  Child process that reads/writes map.  The child stats the file
 *  to determine the size, maps the size of the file, then reads/writes
 *  its own locations on random pages of the map (its locations being
 *  determined based on nprocs & procno).  After a specific number of
 *  iterations, it exits.
 */
void
child_mapper(char *file, unsigned procno, unsigned nprocs)
{
#ifdef LARGE_FILE
	struct stat64 statbuf;
	off64_t filesize;
	off64_t offset;
#else /* LARGE_FILE */
	struct stat statbuf;
	off_t filesize;
	off_t offset;
#endif /* LARGE_FILE */
	size_t validsize;
	size_t mapsize;
	caddr_t maddr, paddr;
	int fd;
	int pagesize = sysconf(_SC_PAGE_SIZE);
	unsigned randpage;
	unsigned int seed;
	unsigned loopcnt;
	unsigned nloops;
	unsigned mappages; 
	unsigned mapflags;
	unsigned i;

	mapflags = MAP_SHARED;

	seed = initrand();		/* initialize random seed */


#ifdef LARGE_FILE
	if ((fd = open64(file, O_RDWR)) == -1) {
#else /* LARGE_FILE */
	if ((fd = open(file, O_RDWR)) == -1) {
#endif /* LARGE_FILE */
		perror("open error");
                anyfail();
	}

#ifdef LARGE_FILE
	if (fstat64(fd, &statbuf) == -1) {
#else /* LARGE_FILE */
	if (fstat(fd, &statbuf) == -1) {
#endif /* LARGE_FILE */
		perror("stat error");
                anyfail();
	}
	filesize = statbuf.st_size;

	if (statbuf.st_size - sparseoffset > SIZE_MAX) {
		fprintf(stderr, "size_t overflow when setting up map\n");
                anyfail();
	}
	mapsize = (size_t)(statbuf.st_size - sparseoffset);
	mappages = roundup(mapsize, pagesize) / pagesize;
	offset = sparseoffset;
	if (do_offset) {
		int pageoffset = lrand48() % mappages;
		int byteoffset = pageoffset * pagesize;
		offset += byteoffset;
		mapsize -= byteoffset;
		mappages -= pageoffset;
	}

#ifdef LARGE_FILE
	if ((maddr = mmap64(0, mapsize, PROT_READ|PROT_WRITE, 
			mapflags, fd, offset)) == (caddr_t)-1) {
#else /* LARGE_FILE */
	if ((maddr = mmap(0, mapsize, PROT_READ|PROT_WRITE, 
			mapflags, fd, offset)) == (caddr_t)-1) {
#endif /* LARGE_FILE */
		perror("mmap error");
                anyfail();
	}

	(void)close(fd);

	nloops = (randloops) ? (lrand48() % MAXLOOPS) : MAXLOOPS;

	if (debug) {
#ifdef LARGE_FILE
		(void)printf("child %d (pid %ld): seed %d, fsize %Ld, "
			"mapsize %d, off %Ld, loop %d\n",
			procno, getpid(), seed, filesize, mapsize,
			offset/pagesize, nloops);
#else /* LARGE_FILE */
		(void)printf("child %d (pid %d): seed %d, fsize %ld, "
			"mapsize %ld, off %ld, loop %d\n",
			procno, getpid(), seed, filesize, (long)mapsize,
			offset/pagesize, nloops);
#endif /* LARGE_FILE */
	}

	/*
	 *  Now loop read/writing random pages.
	 */
	for (loopcnt = 0; loopcnt < nloops; loopcnt++) {
		randpage = lrand48() % mappages;
		paddr = maddr + (randpage * pagesize);	 /* page address */

		if (randpage < mappages - 1
		    || !(mapsize % pagesize))
			validsize = pagesize;
		else
			validsize = mapsize % pagesize;

		/*
		 * Because one child is mapping file in extend mode,
		 * it may be padded with zeros at end.  So we can't
		 * do an exact check -- accept known pattern OR zeros.
		 */
		for (i = procno; i < validsize; i += nprocs) {
			if (*((unsigned char *)(paddr+i)) 
			    != ((procno + pattern) & 0xff)
			    && *((unsigned char *)(paddr+i)) != 0) {
				(void)fprintf(stderr, "child %d: invalid data "
				"<x%x>", procno, *((unsigned char *)(paddr+i)));
				(void)fprintf(stderr, " at pg %d off %d, exp "
					"<x%x>\n", randpage, i,
					(procno+pattern)&0xff);
                        anyfail();
			}
			/*
			 *  Now write it.
			 */

			*(paddr+i) = (procno + pattern) & 0xff;
		}
	}
	if (dosync) {
		/*
		 * Exercise msync() as well!
		 */
		randpage = lrand48() % mappages;
		paddr = maddr + (randpage * pagesize);	 /* page address */
		if (msync(paddr, (mappages - randpage)*pagesize, 
		    MS_SYNC) == -1) {
			perror("msync error");
                        anyfail();
		}
	}

	exit(0);
}

/*
 *  child_writer
 * 	The child process that continually (and slowly!!) grows
 *	the file.  The purpose of this is to exercise the code
 *	supporting mapping of fragments.  The map children are 
 *	constantly reforking and will pick up the map changes, etc.
 *	This process executes until signalled (i.e. has no exit!)
 *	unless error.	
 */
void
child_writer(char *file, uchar_t *buf)	/* buf already set up in main */
{
	int fd;
#ifdef LARGE_FILE
	struct stat64 statbuf;
	off64_t off;
#else /* LARGE_FILE */
	struct stat statbuf;
	off_t off;
#endif /* LARGE_FILE */
	int pagesize = sysconf(_SC_PAGE_SIZE);
	uchar_t *p;
	int cnt;

#ifdef LARGE_FILE
	if ((fd = open64(file, O_RDWR)) == -1) {
#else /* LARGE_FILE */
	if ((fd = open(file, O_RDWR)) == -1) {
#endif /* LARGE_FILE */
		perror("open error");
                anyfail();
	}

#ifdef LARGE_FILE
	if ((off = lseek64(fd, 0, SEEK_END)) == -1) {
#else /* LARGE_FILE */
	if ((off = lseek(fd, 0, SEEK_END)) == -1) {
#endif /* LARGE_FILE */
		perror("lseek error");
                anyfail();
	}


	for (;;) {
#ifdef LARGE_FILE
		if (fstat64(fd, &statbuf) == -1) {
#else /* LARGE_FILE */
		if (fstat(fd, &statbuf) == -1) {
#endif /* LARGE_FILE */
			perror("fstat error");
                        anyfail();
		}
#ifdef LARGE_FILE
		if (debug)
			(void)printf("writer %d bytes at off %Ld, size %Ld\n", 
				growsize, off, statbuf.st_size); 
#else /* LARGE_FILE */
		if (debug)
			(void)printf("writer %d bytes at off %ld, size %ld\n", 
				growsize, off, statbuf.st_size); 
#endif /* LARGE_FILE */

		/*
		 *  Write some number of bytes, then sleep some
		 *  number of seconds...
		 *  Need to keep track of our offset so write the
		 *  right bytes.
		 */

		p = buf + (off % pagesize);

		if ((cnt = write(fd, p, growsize)) != growsize) {
			if (cnt == -1)
				perror("write error");
			else
				(void)fprintf(stderr, "wrote %d of %d bytes\n",
					cnt, growsize);
                        anyfail();
		}

		off += growsize;

		(void)sleep(sleeptime);
		if (dosync) {
			if (fsync(fd) == -1) {
				perror("fsync error");
                                anyfail();
			}
		}
	}
}


/*
 *  Make sure file has all the correct data.

 */
int
fileokay(char *file, uchar_t *expbuf)
{
#ifdef LARGE_FILE
	struct stat64 statbuf;
#else /* LARGE_FILE */
	struct stat statbuf;
#endif /* LARGE_FILE */
	size_t mapsize;
	uchar_t *readbuf;
	unsigned mappages;
	unsigned pagesize = sysconf(_SC_PAGE_SIZE);
	int fd;
	int cnt;
	unsigned i, j;

#ifdef LARGE_FILE
	if ((fd = open64(file, O_RDONLY)) == -1) {
#else /* LARGE_FILE */
	if ((fd = open(file, O_RDONLY)) == -1) {
#endif /* LARGE_FILE */
		perror("open error");
                anyfail();
	}
#ifdef LARGE_FILE
	if (fstat64(fd, &statbuf) == -1) {
#else /* LARGE_FILE */
	if (fstat(fd, &statbuf) == -1) {
#endif /* LARGE_FILE */
		perror("stat error");
                anyfail();
	}
#ifdef LARGE_FILE
	if (lseek64(fd, sparseoffset, SEEK_SET) < 0) {
#else /* LARGE_FILE */
	if (lseek(fd, sparseoffset, SEEK_SET) < 0) {
#endif /* LARGE_FILE */
		perror("lseek");
		exit(1);
	}

	readbuf = (uchar_t *)malloc(pagesize);

	if (statbuf.st_size - sparseoffset > SIZE_MAX) {
		fprintf(stderr, "size_t overflow when setting up map\n");
		exit(1);
	}
	mapsize = (size_t)(statbuf.st_size - sparseoffset);
	mappages = roundup(mapsize, pagesize) / pagesize;

	for (i = 0; i < mappages; i++) {
		cnt = read(fd, (char *)readbuf, pagesize);
		if (cnt == -1) {
			perror("read error");
			return(0);	
		} else if (cnt != pagesize) {
			/*
			 *  Okay if at last page in file... 
			 */
			if ((i * pagesize) + cnt != mapsize) {
				(void)fprintf(stderr, "read %d of %ld bytes\n",
					(i*pagesize)+cnt, (long)mapsize);
				return(0);
			}
		}
		/*
		 *  Compare read bytes of data.
		 *  May have zeros from map extend...
		 */
		for (j = 0; j < cnt; j++) {
			if (expbuf[j] != readbuf[j] && readbuf[j] != 0) {
				(void)fprintf(stderr, 
					"read bad data: exp %c got %c",
					expbuf[j], readbuf[j]);
#ifdef LARGE_FILE
				(void)fprintf(stderr, ", pg %d off %d, "
					"(fsize %Ld)\n", i, j, statbuf.st_size);
#else /* LARGE_FILE */
				(void)fprintf(stderr, ", pg %d off %d, "
					"(fsize %ld)\n", i, j, statbuf.st_size);
#endif /* LARGE_FILE */
				return(0);
			}
		}
	}
					
	return(1);
}

/*ARGSUSED*/
void
finish(int sig)
{
	finished++;
	/* finish nicely and check the file contents */
}

/*ARGSUSED*/
void
clean_up_file(int sig)
{
	if (!leavefile)
		(void)unlink(filename);
	exit(1);
}

unsigned int
initrand(void)
{
	unsigned int seed;

	/*
	 *  Initialize random seed...  Got this from a test written
	 *  by scooter:
	 *	Use srand/rand to diffuse the information from the
	 *	time and pid.  If you start several processes, then
	 *	the time and pid information don't provide much
	 *	variation.
	 */
	srand((unsigned int)getpid());
	seed = rand();
	srand((unsigned int)time((time_t *)0));
	seed = (seed ^ rand()) % 100000;
	srand48((long int)seed);
	return (seed);
}


/*****  LTP Port        *****/
void ok_exit()
{
        tst_resm(TPASS, "Test passed\n");
	tst_rmdir();
	tst_exit();
}


int anyfail()
{
  tst_resm(TFAIL, "Test failed\n");
  tst_rmdir();
  tst_exit();
  return(0);
}
コード例 #7
0
ファイル: main.c プロジェクト: AhmadTux/DragonFlyBSD
void
playinit(void)
{
	/* catch/ingnore signals */

#ifdef	BSD41
	sigignore(SIGQUIT);
	sigignore(SIGALRM);
	sigignore(SIGTERM);
	sigignore(SIGTSTP);
	sigignore(SIGTTIN);
	sigignore(SIGTTOU);
	sighold(SIGINT);
	sigset(SIGHUP, ill_sig);
	sigset(SIGTRAP, ill_sig);
	sigset(SIGIOT, ill_sig);
	sigset(SIGEMT, ill_sig);
	sigset(SIGFPE, ill_sig);
	sigset(SIGBUS, ill_sig);
	sigset(SIGSEGV, ill_sig);
	sigset(SIGSYS, ill_sig);
	sigset(SIGPIPE, ill_sig);
#endif
#ifdef	BSD42
	signal(SIGQUIT, ill_sig);
	signal(SIGALRM, SIG_IGN);
	signal(SIGTERM, SIG_IGN);
	signal(SIGTSTP, SIG_IGN);
	signal(SIGTTIN, SIG_IGN);
	signal(SIGTTOU, SIG_IGN);
	signal(SIGINT, ill_sig);
	signal(SIGHUP, SIG_DFL);
	signal(SIGTRAP, ill_sig);
	signal(SIGIOT, ill_sig);
	signal(SIGEMT, ill_sig);
	signal(SIGFPE, ill_sig);
	signal(SIGBUS, ill_sig);
	signal(SIGSEGV, ill_sig);
	signal(SIGSYS, ill_sig);
	signal(SIGPIPE, ill_sig);
#endif
#ifdef	SYS3
	signal(SIGINT, SIG_IGN);
	signal(SIGQUIT, SIG_IGN);
	signal(SIGTERM, SIG_IGN);
	signal(SIGALRM, SIG_IGN);
	signal(SIGHUP, ill_sig);
	signal(SIGTRAP, ill_sig);
	signal(SIGIOT, ill_sig);
	signal(SIGEMT, ill_sig);
	signal(SIGFPE, ill_sig);
	signal(SIGBUS, ill_sig);
	signal(SIGSEGV, ill_sig);
	signal(SIGSYS, ill_sig);
	signal(SIGPIPE, ill_sig);
#endif
#ifdef	SYS5
	signal(SIGINT, SIG_IGN);
	signal(SIGQUIT, SIG_IGN);
	signal(SIGTERM, SIG_IGN);
	signal(SIGALRM, SIG_IGN);
	signal(SIGHUP, ill_sig);
	signal(SIGTRAP, ill_sig);
	signal(SIGIOT, ill_sig);
	signal(SIGEMT, ill_sig);
	signal(SIGFPE, ill_sig);
	signal(SIGBUS, ill_sig);
	signal(SIGSEGV, ill_sig);
	signal(SIGSYS, ill_sig);
	signal(SIGPIPE, ill_sig);
#endif

	initscr();		/* turn on curses */
	noecho();		/* do not echo input */
	cbreak();		/* do not process erase, kill */
	clear();
	refresh();
	Windows = TRUE;		/* mark the state */
}
コード例 #8
0
ファイル: pkgexecv.c プロジェクト: Sunshine-OS/pkg-gate
int
pkgexecv(char *filein, char *fileout, char *uname, char *gname, char *arg[])
{
	int			exit_no;
	int			n;
	int			status;
	pid_t			pid;
	pid_t			waitstat;
	struct group		*grp;
	struct passwd		*pwp;
	struct sigaction	nact;
	struct sigaction	oact;
	void			(*funcSighup)(int);
	void			(*funcSigint)(int);

	/* flush standard i/o before creating new process */

	(void) fflush(stdout);
	(void) fflush(stderr);

	/*
	 * hold SIGINT/SIGHUP signals and reset signal received counter;
	 * after the vfork() the parent and child need to setup their respective
	 * interrupt handling and release the hold on the signals
	 */

	(void) sighold(SIGINT);
	(void) sighold(SIGHUP);

	sig_received = 0;

	/*
	 * create new process to execute command in;
	 * vfork() is being used to avoid duplicating the parents
	 * memory space - this means that the child process may
	 * not modify any of the parents memory including the
	 * standard i/o descriptors - all the child can do is
	 * adjust interrupts and open files as a prelude to a
	 * call to exec().
	 */

	pid = vfork();

	if (pid < 0) {
		/*
		 * *************************************************************
		 * fork failed!
		 * *************************************************************
		 */

		progerr(pkg_gt(ERR_FORK_FAILED), errno, strerror(errno));

		/* release hold on signals */

		(void) sigrelse(SIGHUP);
		(void) sigrelse(SIGINT);

		return (-1);
	}

	if (pid > 0) {
		/*
		 * *************************************************************
		 * This is the forking (parent) process
		 * *************************************************************
		 */

		/* close datastream if any portion read */

		if (ds_curpartcnt >= 0) {
			if (ds_close(0) != 0) {
				/* kill child process */

				(void) sigsend(P_PID, pid, SIGKILL);

				/* release hold on signals */

				(void) sigrelse(SIGHUP);
				(void) sigrelse(SIGINT);

				return (-1);
			}
		}

		/*
		 * setup signal handlers for SIGINT and SIGHUP and release hold
		 */

		/* hook SIGINT to sig_trap() */

		nact.sa_handler = sig_trap;
		nact.sa_flags = SA_RESTART;
		(void) sigemptyset(&nact.sa_mask);

		if (sigaction(SIGINT, &nact, &oact) < 0) {
			funcSigint = SIG_DFL;
		} else {
			funcSigint = oact.sa_handler;
		}

		/* hook SIGHUP to sig_trap() */

		nact.sa_handler = sig_trap;
		nact.sa_flags = SA_RESTART;
		(void) sigemptyset(&nact.sa_mask);

		if (sigaction(SIGHUP, &nact, &oact) < 0) {
			funcSighup = SIG_DFL;
		} else {
			funcSighup = oact.sa_handler;
		}

		/* release hold on signals */

		(void) sigrelse(SIGHUP);
		(void) sigrelse(SIGINT);

		/*
		 * wait for the process to exit, reap child exit status
		 */

		for (;;) {
			status = 0;
			waitstat = waitpid(pid, (int *)&status, 0);
			if (waitstat < 0) {
				/* waitpid returned error */
				if (errno == EAGAIN) {
					/* try again */
					continue;
				}
				if (errno == EINTR) {
					continue;
				}
				/* error from waitpid: bail */
				break;
			} else if (waitstat == pid) {
				/* child exit status available */
				break;
			}
		}

		/*
		 * reset signal handlers
		 */

		/* reset SIGINT */

		nact.sa_handler = funcSigint;
		nact.sa_flags = SA_RESTART;
		(void) sigemptyset(&nact.sa_mask);

		(void) sigaction(SIGINT, &nact, (struct sigaction *)NULL);

		/* reset SIGHUP */

		nact.sa_handler = funcSighup;
		nact.sa_flags = SA_RESTART;
		(void) sigemptyset(&nact.sa_mask);

		(void) sigaction(SIGHUP, &nact, (struct sigaction *)NULL);

		/* error if child process does not match */

		if (waitstat != pid) {
			progerr(pkg_gt(ERR_WAIT_FAILED), pid, waitstat, status,
				errno, strerror(errno));
			return (-1);
		}

		/*
		 * determine final exit code:
		 * - if signal received, then return interrupted (3)
		 * - if child exit status is available, return exit child status
		 * - otherwise return error (-1)
		 */

		if (sig_received != 0) {
			exit_no = 3;	/* interrupted */
		} else if (WIFEXITED(status)) {
			exit_no = WEXITSTATUS(status);
		} else {
			exit_no = -1;	/* exec() or other process error */
		}

		return (exit_no);
	}

	/*
	 * *********************************************************************
	 * This is the forked (child) process
	 * *********************************************************************
	 */

	/* reset all signals to default */

	for (n = 0; n < NSIG; n++) {
		(void) sigset(n, SIG_DFL);
	}

	/* release hold on signals held by parent before fork() */

	(void) sigrelse(SIGHUP);
	(void) sigrelse(SIGINT);

	/*
	 * The caller wants to have stdin connected to filein.
	 */

	if (filein && *filein) {
		/*
		 * If input is supposed to be connected to /dev/tty
		 */
		if (strncmp(filein, "/dev/tty", 8) == 0) {
			/*
			 * If stdin is connected to a tty device.
			 */
			if (isatty(STDIN_FILENO)) {
				/*
				 * Reopen it to /dev/tty.
				 */
				n = open(filein, O_RDONLY);
				if (n >= 0) {
					(void) dup2(n, STDIN_FILENO);
				}
			}
		} else {
			/*
			 * If we did not want to be connected to /dev/tty, we
			 * connect input to the requested file no questions.
			 */
			n = open(filein, O_RDONLY);
			if (n >= 0) {
				(void) dup2(n, STDIN_FILENO);
			}
		}
	}

	/*
	 * The caller wants to have stdout and stderr connected to fileout.
	 * If "fileout" is "/dev/tty" then reconnect stdout to "/dev/tty"
	 * only if /dev/tty is not already associated with "a tty".
	 */

	if (fileout && *fileout) {
		/*
		 * If output is supposed to be connected to /dev/tty
		 */
		if (strncmp(fileout, "/dev/tty", 8) == 0) {
			/*
			 * If stdout is connected to a tty device.
			 */
			if (isatty(STDOUT_FILENO)) {
				/*
				 * Reopen it to /dev/tty if /dev/tty available.
				 */
				n = open(fileout, O_WRONLY);
				if (n >= 0) {
					/*
					 * /dev/tty is available - close the
					 * current standard output stream, and
					 * reopen it on /dev/tty
					 */
					(void) dup2(n, STDOUT_FILENO);
				}
			}
			/*
			 * not connected to tty device - probably redirect to
			 * file - preserve existing output device
			 */
		} else {
			/*
			 * If we did not want to be connected to /dev/tty, we
			 * connect output to the requested file no questions.
			 */
			/* LINTED O_CREAT without O_EXCL specified in call to */
			n = open(fileout, O_WRONLY|O_CREAT|O_APPEND, 0666);
			if (n >= 0) {
				(void) dup2(n, STDOUT_FILENO);
			}
		}

		/*
		 * Dup stderr from stdout.
		 */

		(void) dup2(STDOUT_FILENO, STDERR_FILENO);
	}

	/*
	 * do NOT close all file descriptors except stdio
	 * file descriptors are passed in to some subcommands
	 * (see dstream:ds_getinfo() and dstream:ds_putinfo())
	 */

	/* set group/user i.d. if requested */

	if (gname && *gname && (grp = cgrnam(gname)) != NULL) {
		if (setgid(grp->gr_gid) == -1) {
			progerr(pkg_gt(ERR_SETGID), grp->gr_gid);
		}
	}
	if (uname && *uname && (pwp = cpwnam(uname)) != NULL) {
		if (setuid(pwp->pw_uid) == -1) {
			progerr(pkg_gt(ERR_SETUID), pwp->pw_uid);
		}
	}

	/* execute target executable */

	(void) execve(arg[0], arg, environ);
	progerr(pkg_gt(ERR_EX_FAIL), arg[0], errno);
	_exit(99);
	/*NOTREACHED*/
}
コード例 #9
0
ファイル: zones_exec.c プロジェクト: apprisi/illumos-gate
int
_z_zone_exec(int *r_status, char **r_results, char *a_inputFile,
	char *a_path, char *a_argv[], const char *a_zoneName, int *a_fds)
{
	struct sigaction	nact;
	struct sigaction	oact;
	char			*buffer;
	char			*thisZoneName;
	int			bufferIndex;
	int			bufferSize;
	int			exit_no;
	int			ipipe[2] = {0, 0};
	int			lerrno;
	int			n;
	int			status;
	int			stdinfile = -1;
	int			tmpl_fd;
	pid_t			child_pid;
	pid_t			result_pid;
	void			(*funcSighup)();
	void			(*funcSigint)();

	/* entry assertions */

	assert(a_path != (char *)NULL);
	assert(*a_path != '\0');
	assert(a_argv != (char **)NULL);
	assert(a_argv[0] != (char *)NULL);
	assert(*a_argv[0] != '\0');
	assert(a_zoneName != (char *)NULL);

	/*
	 * if requested to execute in current zone name, directly execute
	 */

	thisZoneName = z_get_zonename();
	status = (strcmp(a_zoneName, thisZoneName) == 0);

	/* entry debugging info */

	_z_echoDebug(DBG_ZONE_EXEC_CMD_ENTER, a_path, a_zoneName, thisZoneName);
	(void) free(thisZoneName);
	for (n = 0; a_argv[n]; n++) {
		_z_echoDebug(DBG_ARG, n, a_argv[n]);
	}

	/* if this zone, just exec the command directly */

	if (status != 0) {
		return (z_ExecCmdArray(r_status, r_results, a_inputFile,
		    a_path, a_argv));
	}

	/* reset return results buffer pointer */

	if (r_results != (char **)NULL) {
		*r_results = (char *)NULL;
	}

	*r_status = -1;	/* -1 : failure to exec process */

	/* if zones are not implemented, return TRUE */

	if (!z_zones_are_implemented()) {
		return (-6);	/* -6 : zones are not supported */
	}

	if ((tmpl_fd = _zexec_init_template()) == -1) {
		_z_program_error(ERR_CANNOT_CREATE_CONTRACT, strerror(errno));
		return (-2);	/* -2 : cannot create greenline contract */
	}

	/*
	 * See if input file exists
	 */

	if (a_inputFile != (char *)NULL) {
		stdinfile = open(a_inputFile, O_RDONLY);
	} else {
		stdinfile = open("/dev/null", O_RDONLY); /* stdin = /dev/null */
	}

	if (stdinfile < 0) {
		return (-4);	/* -4 : could not open stdin source file */
	}

	/*
	 * Create a pipe to be used to capture the command output
	 */

	if (pipe(ipipe) != 0) {
		(void) close(stdinfile);
		return (-1);
	}

	bufferSize = PIPE_BUFFER_INCREMENT;
	bufferIndex = 0;
	buffer = calloc(1, bufferSize);
	if (buffer == (char *)NULL) {
		(void) close(stdinfile);
		return (-1);
	}

	/* flush standard i/o before creating new process */

	(void) fflush(stderr);
	(void) fflush(stdout);

	/*
	 * hold SIGINT/SIGHUP signals and reset signal received counter;
	 * after the fork1() the parent and child need to setup their respective
	 * interrupt handling and release the hold on the signals
	 */

	(void) sighold(SIGINT);
	(void) sighold(SIGHUP);

	_z_global_data._z_SigReceived = 0;	/* no signals received */

	/*
	 * fork off a new process to execute command in;
	 * fork1() is used instead of vfork() so the child process can
	 * perform operations that would modify the parent process if
	 * vfork() were used
	 */

	child_pid = fork1();

	if (child_pid < 0) {
		/*
		 * *************************************************************
		 * fork failed!
		 * *************************************************************
		 */

		(void) ct_tmpl_clear(tmpl_fd);
		(void) close(tmpl_fd);
		(void) free(buffer);
		_z_program_error(ERR_FORK, strerror(errno));

		/* release hold on signals */
		(void) sigrelse(SIGHUP);
		(void) sigrelse(SIGINT);

		return (-3);	/* -3 : fork() failed */
	}

	if (child_pid == 0) {
		int	i;

		/*
		 * *************************************************************
		 * This is the forked (child) process
		 * *************************************************************
		 */

		(void) ct_tmpl_clear(tmpl_fd);
		(void) close(tmpl_fd);

		/* reset any signals to default */

		for (i = 0; i < NSIG; i++) {
			(void) sigset(i, SIG_DFL);
		}

		/* assign stdin, stdout, stderr as appropriate */

		(void) dup2(stdinfile, STDIN_FILENO);
		(void) close(ipipe[0]);		/* close out pipe reader side */
		(void) dup2(ipipe[1], STDOUT_FILENO);
		(void) dup2(ipipe[1], STDERR_FILENO);

		/*
		 * close all file descriptors not in the a_fds list
		 */

		(void) fdwalk(&_z_close_file_descriptors, (void *)a_fds);

		/* release all held signals */

		(void) sigrelse(SIGHUP);
		(void) sigrelse(SIGINT);

		/* execute command in the specified non-global zone */

		_exit(_zexec(a_zoneName, a_path, a_argv));
	}

	/*
	 * *********************************************************************
	 * This is the forking (parent) process
	 * *********************************************************************
	 */

	/* register child process i.d. so signal handlers can pass signal on */

	_z_global_data._z_ChildProcessId = child_pid;

	/*
	 * setup signal handlers for SIGINT and SIGHUP and release hold
	 */

	/* hook SIGINT to _z_sig_trap() */

	nact.sa_handler = _z_sig_trap;
	nact.sa_flags = SA_RESTART;
	(void) sigemptyset(&nact.sa_mask);

	if (sigaction(SIGINT, &nact, &oact) < 0) {
		funcSigint = SIG_DFL;
	} else {
		funcSigint = oact.sa_handler;
	}

	/* hook SIGHUP to _z_sig_trap() */

	nact.sa_handler = _z_sig_trap;
	nact.sa_flags = SA_RESTART;
	(void) sigemptyset(&nact.sa_mask);

	if (sigaction(SIGHUP, &nact, &oact) < 0) {
		funcSighup = SIG_DFL;
	} else {
		funcSighup = oact.sa_handler;
	}

	/* release hold on signals */

	(void) sigrelse(SIGHUP);
	(void) sigrelse(SIGINT);

	(void) ct_tmpl_clear(tmpl_fd);
	(void) close(tmpl_fd);

	(void) close(stdinfile);
	(void) close(ipipe[1]);		/* Close write side of pipe */

	/*
	 * Spin reading data from the child into the buffer - when the read eofs
	 * the child has exited
	 */

	for (;;) {
		ssize_t	bytesRead;

		/* read as much child data as there is available buffer space */

		bytesRead = read(ipipe[0], buffer + bufferIndex,
		    bufferSize - bufferIndex);

		/* break out of read loop if end-of-file encountered */

		if (bytesRead == 0) {
			break;
		}

		/* if error, continue if recoverable, else break out of loop */

		if (bytesRead == -1) {
			/* try again: EAGAIN - insufficient resources */

			if (errno == EAGAIN) {
				continue;
			}

			/* try again: EINTR - interrupted system call */

			if (errno == EINTR) {
				continue;
			}

			/* break out of loop - error not recoverable */
			break;
		}

		/* at least 1 byte read: expand buffer if at end */

		bufferIndex += bytesRead;
		if (bufferIndex >= bufferSize) {
			buffer = realloc(buffer,
			    bufferSize += PIPE_BUFFER_INCREMENT);
			(void) memset(buffer + bufferIndex, 0,
			    bufferSize - bufferIndex);
		}
	}

	(void) close(ipipe[0]);		/* Close read side of pipe */

	/*
	 * wait for the process to exit, reap child exit status
	 */

	for (;;) {
		result_pid = waitpid(child_pid, &status, 0L);
		lerrno = (result_pid == -1 ? errno : 0);

		/* break loop if child process status reaped */

		if (result_pid != -1) {
			break;
		}

		/* break loop if not interrupted out of waitpid */

		if (errno != EINTR) {
			break;
		}
	}

	/* reset child process i.d. so signal handlers do not pass signals on */

	_z_global_data._z_ChildProcessId = -1;

	/*
	 * If the child process terminated due to a call to exit(), then
	 * set results equal to the 8-bit exit status of the child process;
	 * otherwise, set the exit status to "-1" indicating that the child
	 * exited via a signal.
	 */

	if (WIFEXITED(status)) {
		*r_status = WEXITSTATUS(status);
		if ((_z_global_data._z_SigReceived != 0) && (*r_status == 0)) {
			*r_status = 1;
		}
	} else {
		*r_status = -1;	/* -1 : failure to exec process */
	}

	/* determine proper exit code */

	if (result_pid == -1) {
		exit_no = -5;	/* -5 : error from 'waitpid' other than EINTR */
	} else if (_z_global_data._z_SigReceived != 0) {
		exit_no = -7;	/* -7 : interrupt received */
	} else {
		exit_no = 0;
	}

	/* return appropriate output */

	if (!*buffer) {
		/* No contents in output buffer - discard */
		free(buffer);
	} else if (r_results == (char **)NULL) {
		/* Not requested to return results - discard */
		free(buffer);
	} else {
		/* have output and request to return: pass to calling method */
		*r_results = buffer;
	}

	/*
	 * reset signal handlers
	 */

	/* reset SIGINT */

	nact.sa_handler = funcSigint;
	nact.sa_flags = SA_RESTART;
	(void) sigemptyset(&nact.sa_mask);

	(void) sigaction(SIGINT, &nact, (struct sigaction *)NULL);

	/* reset SIGHUP */

	nact.sa_handler = funcSighup;
	nact.sa_flags = SA_RESTART;
	(void) sigemptyset(&nact.sa_mask);

	(void) sigaction(SIGHUP, &nact, (struct sigaction *)NULL);

	/*
	 * if signal received during command execution, interrupt
	 * this process now.
	 */

	if (_z_global_data._z_SigReceived != 0) {
		(void) kill(getpid(), SIGINT);
	}

	/* set errno and return */

	errno = lerrno;

	return (exit_no);
}
コード例 #10
0
ファイル: ping_aux.c プロジェクト: andreiw/polaris
/*
 * Check out the packet to see if it came from us.  This logic is necessary
 * because ALL readers of the ICMP socket get a copy of ALL ICMP packets
 * which arrive ('tis only fair).  This permits multiple copies of this
 * program to be run without having intermingled output (or statistics!).
 */
void
check_reply(struct addrinfo *ai_dst, struct msghdr *msg, int cc,
    ushort_t udp_src_port)
{
	struct ip *ip;
	struct icmp *icp;
	struct udphdr *up;
	union any_in_addr dst_addr;
	uchar_t *buf;
	int32_t *intp;
	struct sockaddr_in *from;
	struct timeval *tp;
	struct timeval tv;
	int hlen, hlen1;
	int64_t triptime;
	boolean_t valid_reply = _B_FALSE;
	boolean_t reply_matched_current_target;	/* Is the source address of */
						/* this reply same as where */
						/* we're sending currently? */
	boolean_t last_reply_from_targetaddr = _B_FALSE; /* Is this stats, */
						/* probe all with npackets>0 */
						/* and we received reply for */
						/* the last probe sent to */
						/* targetaddr */
	int cc_left;
	char tmp_buf[INET6_ADDRSTRLEN];
	static char *unreach[] = {
	    "Net Unreachable",
	    "Host Unreachable",
	    "Protocol Unreachable",
	    "Port Unreachable",
	    "Fragmentation needed and DF set",
	    "Source Route Failed",
	    /* The following are from RFC1700 */
	    "Net Unknown",
	    "Host Unknown",
	    "Source Host Isolated",
	    "Dest Net Prohibited",
	    "Dest Host Prohibited",
	    "Net Unreachable for TOS",
	    "Host Unreachable for TOS",
	    "Communication Administratively Prohibited",
	    "Host Precedence Violation",
	    "Precedence Cutoff in Effect"
	};
	static char *redirect[] = {
	    "Net",
	    "Host",
	    "TOS Net",
	    "TOS Host"
	};
	static char *timexceed[] = {
	    "Time exceeded in transit",
	    "Time exceeded during reassembly"
	};
	boolean_t print_newline = _B_FALSE;
	int i;

	/* decompose msghdr into useful pieces */
	buf = (uchar_t *)msg->msg_iov->iov_base;
	from = (struct sockaddr_in *)msg->msg_name;

	/* LINTED */
	intp = (int32_t *)buf;

	(void) gettimeofday(&tv, (struct timezone *)NULL);

	/* LINTED */
	ip = (struct ip *)buf;
	hlen = ip->ip_hl << 2;

	if ((cc < sizeof (struct ip)) || (cc < hlen + ICMP_MINLEN)) {
		if (verbose) {
			Printf("packet too short (%d bytes) from %s\n", cc,
			    pr_name((char *)&from->sin_addr, AF_INET));
		}
		return;
	}

	cc -= hlen;
	/* LINTED */
	icp = (struct icmp *)(buf + hlen);

	if (ip->ip_p == 0) {
		/*
		 * Assume that we are running on a pre-4.3BSD system
		 * such as SunOS before 4.0
		 */
		/* LINTED */
		icp = (struct icmp *)buf;
	}
	cc_left = cc - ICMP_MINLEN;

	switch (icp->icmp_type) {
	case ICMP_UNREACH:
		ip = &icp->icmp_ip;
		hlen1 = ip->ip_hl << 2;

		/* check if we have enough of the packet to work on */
		if ((cc_left < sizeof (struct ip)) ||
		    (cc_left < hlen1 + sizeof (struct udphdr))) {
			if (verbose) {
				Printf("packet too short (%d bytes) from %s\n",
				    cc, pr_name((char *)&from->sin_addr,
				    AF_INET));
			}
			return;
		}

		/* get the UDP packet */
		cc_left -= hlen1 + sizeof (struct udphdr);
		/* LINTED */
		up = (struct udphdr *)((uchar_t *)ip + hlen1);

		/* check to see if this is what we sent */
		if (icp->icmp_code == ICMP_UNREACH_PORT &&
		    ip->ip_p == IPPROTO_UDP &&
		    udp_src_port == up->uh_sport &&
		    use_udp) {
			valid_reply = _B_TRUE;
		} else {
			valid_reply = _B_FALSE;
		}

		if (valid_reply) {
			/*
			 * For this valid reply, if we are still sending to
			 * this target IP address, we'd like to do some
			 * updates to targetaddr, so hold SIGALRMs.
			 */
			(void) sighold(SIGALRM);
			is_alive = _B_TRUE;
			nreceived++;
			reply_matched_current_target =
			    seq_match(current_targetaddr->starting_seq_num,
				current_targetaddr->num_sent,
				ntohs(up->uh_dport));
			if (reply_matched_current_target) {
				current_targetaddr->got_reply = _B_TRUE;
				nreceived_last_target++;
				/*
				 * Determine if stats, probe-all, and
				 * npackets != 0, and this is the reply for
				 * the last probe we sent to current target
				 * address.
				 */
				if (stats && probe_all && npackets > 0 &&
				    ((current_targetaddr->starting_seq_num +
				    current_targetaddr->num_probes - 1) %
				    (MAX_PORT + 1) == ntohs(up->uh_dport)) &&
				    (current_targetaddr->num_probes ==
				    current_targetaddr->num_sent))
					last_reply_from_targetaddr = _B_TRUE;
			} else {
				/*
				 * If it's just probe_all and we just received
				 * a reply from a target address we were
				 * probing and had timed out (now we are probing
				 * some other target address), we ignore
				 * this reply.
				 */
				if (probe_all && !stats) {
					valid_reply = _B_FALSE;
					/*
					 * Only if it's verbose, we get a
					 * message regarding this reply,
					 * otherwise we are done here.
					 */
					if (!verbose) {
						(void) sigrelse(SIGALRM);
						return;
					}
				}
			}
		}

		/* stats mode doesn't print 'alive' messages */
		if (valid_reply && !stats) {
			/*
			 * if we are still sending to the same target address,
			 * then stop it, because we know it's alive.
			 */
			if (reply_matched_current_target) {
				(void) alarm(0);	/* cancel alarm */
				(void) sigset(SIGALRM, SIG_IGN);
				current_targetaddr->probing_done = _B_TRUE;
			}
			(void) sigrelse(SIGALRM);

			if (!probe_all) {
				Printf("%s is alive\n", targethost);
			} else {
				(void) inet_ntop(AF_INET, (void *)&ip->ip_dst,
				    tmp_buf, sizeof (tmp_buf));

				if (nflag) {
					Printf("%s is alive\n", tmp_buf);
				} else {
					Printf("%s (%s) is alive\n",
					    targethost, tmp_buf);
				}
			}
			if (reply_matched_current_target) {
				/*
				 * Let's get things going again, but now
				 * ping will start sending to next target IP
				 * address.
				 */
				send_scheduled_probe();
				(void) sigset(SIGALRM, sigalrm_handler);
				schedule_sigalrm();
			}
			return;
		} else {
			/*
			 * If we are not moving to next targetaddr, let's
			 * release the SIGALRM now. We don't want to stall in
			 * the middle of probing a targetaddr if the pr_name()
			 * call (see below) takes longer.
			 */
			if (!last_reply_from_targetaddr)
				(void) sigrelse(SIGALRM);
			/* else, we'll release it later */
		}

		dst_addr.addr = ip->ip_dst;
		if (valid_reply) {
			Printf("%d bytes from %s: ", cc,
			    pr_name((char *)&from->sin_addr, AF_INET));
			Printf("udp_port=%d. ", ntohs(up->uh_dport));
			print_newline = _B_TRUE;
		} else if (is_a_target(ai_dst, &dst_addr) || verbose) {
			if (icp->icmp_code >= A_CNT(unreach)) {
				Printf("ICMP %d Unreachable from gateway %s\n",
				    icp->icmp_code,
				    pr_name((char *)&from->sin_addr, AF_INET));
			} else {
				Printf("ICMP %s from gateway %s\n",
				    unreach[icp->icmp_code],
				    pr_name((char *)&from->sin_addr, AF_INET));
			}
			Printf(" for %s from %s", pr_protocol(ip->ip_p),
			    pr_name((char *)&ip->ip_src, AF_INET));
			Printf(" to %s", pr_name((char *)&ip->ip_dst, AF_INET));
			if (ip->ip_p == IPPROTO_TCP ||
			    ip->ip_p == IPPROTO_UDP) {
				Printf(" port %d ", ntohs(up->uh_dport));
			}
			print_newline = _B_TRUE;
		}

		/* if we are timing and the reply has a timeval */
		if (valid_reply && datalen >= sizeof (struct timeval) &&
		    cc_left >= sizeof (struct timeval)) {
			/* LINTED */
			tp = (struct timeval *)((char *)up +
			    sizeof (struct udphdr));
			(void) tvsub(&tv, tp);
			triptime = (int64_t)tv.tv_sec * MICROSEC + tv.tv_usec;
			Printf("time=" TIMEFORMAT " ms", triptime/1000.0);
			tsum += triptime;
			tsum2 += triptime*triptime;
			if (triptime < tmin)
				tmin = triptime;
			if (triptime > tmax)
				tmax = triptime;
			print_newline = _B_TRUE;
		}
		if (print_newline)
			(void) putchar('\n');
		/*
		 * If it's stats, probe-all, npackets > 0, and we received reply
		 * for the last probe sent to this target address, then we
		 * don't need to wait anymore, let's move on to next target
		 * address, now!
		 */
		if (last_reply_from_targetaddr) {
			(void) alarm(0);	/* cancel alarm */
			current_targetaddr->probing_done = _B_TRUE;
			(void) sigrelse(SIGALRM);
			send_scheduled_probe();
			schedule_sigalrm();
		}
		break;

	case ICMP_REDIRECT:
		if (cc_left < sizeof (struct ip)) {
			if (verbose) {
				Printf("packet too short (%d bytes) from %s\n",
				    cc, pr_name((char *)&from->sin_addr,
				    AF_INET));
			}
			return;
		}

		ip = &icp->icmp_ip;
		dst_addr.addr = ip->ip_dst;
		if (is_a_target(ai_dst, &dst_addr) || verbose) {
			if (icp->icmp_code >= A_CNT(redirect)) {
				Printf("ICMP %d redirect from gateway %s\n",
				    icp->icmp_code,
				    pr_name((char *)&from->sin_addr, AF_INET));
			} else {
				Printf("ICMP %s redirect from gateway %s\n",
				    redirect[icp->icmp_code],
				    pr_name((char *)&from->sin_addr, AF_INET));
			}
			Printf(" to %s",
			    pr_name((char *)&icp->icmp_gwaddr, AF_INET));
			Printf(" for %s\n",
			    pr_name((char *)&ip->ip_dst, AF_INET));
		}
		break;

	case ICMP_ECHOREPLY:
		if (ntohs(icp->icmp_id) == ident) {
			if (!use_udp && !use_icmp_ts)
				valid_reply = _B_TRUE;
			else
				valid_reply = _B_FALSE;
		} else {
			return;
		}

		if (valid_reply) {
			/*
			 * For this valid reply, if we are still sending to
			 * this target IP address, we'd like to do some
			 * updates to targetaddr, so hold SIGALRMs.
			 */
			(void) sighold(SIGALRM);
			is_alive = _B_TRUE;
			nreceived++;
			reply_matched_current_target =
			    seq_match(current_targetaddr->starting_seq_num,
				current_targetaddr->num_sent,
				ntohs(icp->icmp_seq));
			if (reply_matched_current_target) {
				current_targetaddr->got_reply = _B_TRUE;
				nreceived_last_target++;
				/*
				 * Determine if stats, probe-all, and
				 * npackets != 0, and this is the reply for
				 * the last probe we sent to current target
				 * address.
				 */
				if (stats && probe_all && npackets > 0 &&
				    ((current_targetaddr->starting_seq_num +
				    current_targetaddr->num_probes - 1) %
				    (MAX_ICMP_SEQ + 1) ==
				    ntohs(icp->icmp_seq)) &&
				    (current_targetaddr->num_probes ==
				    current_targetaddr->num_sent))
					last_reply_from_targetaddr = _B_TRUE;
			} else {
				/*
				 * If it's just probe_all and we just received
				 * a reply from a target address we were
				 * probing and had timed out (now we are probing
				 * some other target address), we ignore
				 * this reply.
				 */
				if (probe_all && !stats) {
					valid_reply = _B_FALSE;
					/*
					 * Only if it's verbose, we get a
					 * message regarding this reply,
					 * otherwise we are done here.
					 */
					if (!verbose) {
						(void) sigrelse(SIGALRM);
						return;
					}
				}
			}
		}

		if (!stats && valid_reply) {
			/*
			 * if we are still sending to the same target address,
			 * then stop it, because we know it's alive.
			 */
			if (reply_matched_current_target) {
				(void) alarm(0);	/* cancel alarm */
				(void) sigset(SIGALRM, SIG_IGN);
				current_targetaddr->probing_done = _B_TRUE;
			}
			(void) sigrelse(SIGALRM);

			if (!probe_all) {
				Printf("%s is alive\n", targethost);
			} else {
				/*
				 * If we are using send_reply, the real
				 * target address is not the src address of the
				 * replies. Use icmp_seq to find out where this
				 * probe was sent to.
				 */
				if (send_reply) {
					(void) find_dstaddr(
					    ntohs(icp->icmp_seq), &dst_addr);
					(void) inet_ntop(AF_INET,
					    (void *)&dst_addr.addr,
					    tmp_buf, sizeof (tmp_buf));
				} else {
					(void) inet_ntop(AF_INET,
					    (void *)&from->sin_addr,
					    tmp_buf, sizeof (tmp_buf));
				}
				if (nflag) {
					Printf("%s is alive\n", tmp_buf);
				} else {
					Printf("%s (%s) is alive\n",
					    targethost, tmp_buf);
				}
			}
			if (reply_matched_current_target) {
				/*
				 * Let's get things going again, but now
				 * ping will start sending to next target IP
				 * address.
				 */
				send_scheduled_probe();
				(void) sigset(SIGALRM, sigalrm_handler);
				schedule_sigalrm();
			}
			return;
		} else {
			/*
			 * If we are not moving to next targetaddr, let's
			 * release the SIGALRM now. We don't want to stall in
			 * the middle of probing a targetaddr if the pr_name()
			 * call (see below) takes longer.
			 */
			if (!last_reply_from_targetaddr)
				(void) sigrelse(SIGALRM);
			/* else, we'll release it later */
		}
		/*
		 * If we are using send_reply, the real target address is
		 * not the src address of the replies. Use icmp_seq to find out
		 * where this probe was sent to.
		 */
		if (send_reply) {
			(void) find_dstaddr(ntohs(icp->icmp_seq), &dst_addr);
			Printf("%d bytes from %s: ", cc,
			    pr_name((char *)&dst_addr.addr,  AF_INET));
		} else {
			Printf("%d bytes from %s: ", cc,
			    pr_name((char *)&from->sin_addr, AF_INET));
		}
		Printf("icmp_seq=%d. ", ntohs(icp->icmp_seq));

		if (valid_reply && datalen >= sizeof (struct timeval) &&
		    cc_left >= sizeof (struct timeval)) {
			/* LINTED */
			tp = (struct timeval *)&icp->icmp_data[0];
			(void) tvsub(&tv, tp);
			triptime = (int64_t)tv.tv_sec * MICROSEC + tv.tv_usec;
			Printf("time=" TIMEFORMAT " ms", triptime/1000.0);
			tsum += triptime;
			tsum2 += triptime*triptime;
			if (triptime < tmin)
				tmin = triptime;
			if (triptime > tmax)
				tmax = triptime;
		}
		(void) putchar('\n');

		/*
		 * If it's stats, probe-all, npackets > 0, and we received reply
		 * for the last probe sent to this target address, then we
		 * don't need to wait anymore, let's move on to next target
		 * address, now!
		 */
		if (last_reply_from_targetaddr) {
			(void) alarm(0);	/* cancel alarm */
			current_targetaddr->probing_done = _B_TRUE;
			(void) sigrelse(SIGALRM);
			send_scheduled_probe();
			schedule_sigalrm();
		}
		break;

	case ICMP_SOURCEQUENCH:
		if (cc_left < sizeof (struct ip)) {
			if (verbose) {
				Printf("packet too short (%d bytes) from %s\n",
				    cc, pr_name((char *)&from->sin_addr,
				    AF_INET));
			}
			return;
		}
		ip = &icp->icmp_ip;
		hlen1 = ip->ip_hl << 2;
		dst_addr.addr = ip->ip_dst;
		if (is_a_target(ai_dst, &dst_addr) || verbose) {
			Printf("ICMP Source Quench from %s\n",
			    pr_name((char *)&from->sin_addr, AF_INET));
			Printf(" for %s from %s", pr_protocol(ip->ip_p),
			    pr_name((char *)&ip->ip_src, AF_INET));
			Printf(" to %s", pr_name((char *)&ip->ip_dst, AF_INET));

			/*
			 * if it's a UDP or TCP packet, we need at least first
			 * 4 bytes of it to see the src/dst ports
			 */
			if ((ip->ip_p == IPPROTO_TCP ||
			    ip->ip_p == IPPROTO_UDP) &&
			    (cc_left >= hlen1 + 4)) {
				/* LINTED */
				up = (struct udphdr *)((uchar_t *)ip + hlen1);
				Printf(" port %d", ntohs(up->uh_dport));
			}
			(void) putchar('\n');
		}
		break;

	case ICMP_PARAMPROB:
		if (cc_left < sizeof (struct ip)) {
			if (verbose) {
				Printf("packet too short (%d bytes) from %s\n",
				    cc, pr_name((char *)&from->sin_addr,
				    AF_INET));
			}
			return;
		}
		ip = &icp->icmp_ip;
		hlen1 = ip->ip_hl << 2;
		dst_addr.addr = ip->ip_dst;
		if (is_a_target(ai_dst, &dst_addr) || verbose) {
			switch (icp->icmp_code) {
			case ICMP_PARAMPROB_OPTABSENT:
				Printf("ICMP Missing a Required Option "
				    "parameter problem from %s\n",
				    pr_name((char *)&from->sin_addr, AF_INET));
				Printf(" option type = %d", icp->icmp_pptr);
				break;
			case ICMP_PARAMPROB_BADLENGTH:
				Printf("ICMP Bad Length parameter problem "
				    "from %s\n",
				    pr_name((char *)&from->sin_addr, AF_INET));
				Printf(" in byte %d", icp->icmp_pptr);
				if (icp->icmp_pptr <= hlen1) {
					Printf(" (value 0x%x)",
					    *((char *)ip + icp->icmp_pptr));
				}
				break;
			case 0:
			default:
				Printf("ICMP Parameter Problem from %s\n",
				    pr_name((char *)&from->sin_addr, AF_INET));
				Printf(" in byte %d", icp->icmp_pptr);
				if (icp->icmp_pptr <= hlen1) {
					Printf(" (value 0x%x)",
					    *((char *)ip + icp->icmp_pptr));
				}
				break;
			}

			Printf(" for %s from %s", pr_protocol(ip->ip_p),
			    pr_name((char *)&ip->ip_src, AF_INET));
			Printf(" to %s", pr_name((char *)&ip->ip_dst, AF_INET));

			/*
			 * if it's a UDP or TCP packet, we need at least first
			 * 4 bytes of it to see the src/dst ports
			 */
			if ((ip->ip_p == IPPROTO_TCP ||
			    ip->ip_p == IPPROTO_UDP) &&
			    (cc_left >= hlen1 + 4)) {
				/* LINTED */
				up = (struct udphdr *)((uchar_t *)ip + hlen1);
				Printf(" port %d", ntohs(up->uh_dport));
			}
			(void) putchar('\n');
		}
		break;

	case ICMP_TIMXCEED:
		if (cc_left < sizeof (struct ip)) {
			if (verbose) {
				Printf("packet too short (%d bytes) from %s\n",
				    cc, pr_name((char *)&from->sin_addr,
				    AF_INET));
			}
			return;
		}
		ip = &icp->icmp_ip;
		hlen1 = ip->ip_hl << 2;
		dst_addr.addr = ip->ip_dst;
		if (is_a_target(ai_dst, &dst_addr) || verbose) {
			if (icp->icmp_code >= A_CNT(timexceed)) {
				Printf("ICMP %d time exceeded from %s\n",
				    icp->icmp_code,
				    pr_name((char *)&from->sin_addr, AF_INET));
			} else {
				Printf("ICMP %s from %s\n",
				    timexceed[icp->icmp_code],
				    pr_name((char *)&from->sin_addr, AF_INET));
			}
			Printf(" for %s from %s", pr_protocol(ip->ip_p),
			    pr_name((char *)&ip->ip_src, AF_INET));
			Printf(" to %s", pr_name((char *)&ip->ip_dst, AF_INET));
			if ((ip->ip_p == IPPROTO_TCP ||
			    ip->ip_p == IPPROTO_UDP) &&
			    (cc_left >= hlen1 + 4)) {
				/* LINTED */
				up = (struct udphdr *)((uchar_t *)ip + hlen1);
				Printf(" port %d", ntohs(up->uh_dport));
			}
			(void) putchar('\n');
		}
		break;

	case ICMP_TSTAMPREPLY:
		/* the packet should have enough space to store timestamps */
		if (cc_left < sizeof (struct id_ts)) {
			if (verbose) {
				Printf("packet too short (%d bytes) from %s\n",
				    cc, pr_name((char *)&from->sin_addr,
				    AF_INET));
			}
			return;
		}

		if (ntohs(icp->icmp_id) == ident) {
			if (use_icmp_ts)
				valid_reply = _B_TRUE;
			else
				valid_reply = _B_FALSE;
		} else {
			return;
		}

		if (valid_reply) {
			/*
			 * For this valid reply, if we are still sending to
			 * this target IP address, we'd like to do some
			 * updates to targetaddr, so hold SIGALRMs.
			 */
			(void) sighold(SIGALRM);
			is_alive = _B_TRUE;
			nreceived++;
			reply_matched_current_target =
			    seq_match(current_targetaddr->starting_seq_num,
				current_targetaddr->num_sent,
				ntohs(icp->icmp_seq));
			if (reply_matched_current_target) {
				current_targetaddr->got_reply = _B_TRUE;
				nreceived_last_target++;
				/*
				 * Determine if stats, probe-all, and
				 * npackets != 0, and this is the reply for
				 * the last probe we sent to current target
				 * address.
				 */
				if (stats && probe_all && npackets > 0 &&
				    ((current_targetaddr->starting_seq_num +
				    current_targetaddr->num_probes - 1) %
				    (MAX_ICMP_SEQ + 1) ==
				    ntohs(icp->icmp_seq)) &&
				    (current_targetaddr->num_probes ==
				    current_targetaddr->num_sent))
					last_reply_from_targetaddr = _B_TRUE;
			} else {
				/*
				 * If it's just probe_all and we just received
				 * a reply from a target address we were
				 * probing and had timed out (now we are probing
				 * some other target address), we ignore
				 * this reply.
				 */
				if (probe_all && !stats) {
					valid_reply = _B_FALSE;
					/*
					 * Only if it's verbose, we get a
					 * message regarding this reply,
					 * otherwise we are done here.
					 */
					if (!verbose) {
						(void) sigrelse(SIGALRM);
						return;
					}
				}
			}
		}

		if (!stats && valid_reply) {
			/*
			 * if we are still sending to the same target address,
			 * then stop it, because we know it's alive.
			 */
			if (reply_matched_current_target) {
				(void) alarm(0);	/* cancel alarm */
				(void) sigset(SIGALRM, SIG_IGN);
				current_targetaddr->probing_done = _B_TRUE;
			}
			(void) sigrelse(SIGALRM);

			if (!probe_all) {
				Printf("%s is alive\n", targethost);
			} else {
				/*
				 * If we are using send_reply, the real
				 * target address is not the src address of the
				 * replies. Use icmp_seq to find out where this
				 * probe was sent to.
				 */
				if (send_reply) {
					(void) find_dstaddr(
					    ntohs(icp->icmp_seq), &dst_addr);
					(void) inet_ntop(AF_INET,
					    (void *)&dst_addr.addr,
					    tmp_buf, sizeof (tmp_buf));
				} else {
					(void) inet_ntop(AF_INET,
					    (void *)&from->sin_addr,
					    tmp_buf, sizeof (tmp_buf));
				}
				if (nflag) {
					Printf("%s is alive\n", tmp_buf);
				} else {
					Printf("%s (%s) is alive\n",
					    targethost, tmp_buf);
				}
			}
			if (reply_matched_current_target) {
				/*
				 * Let's get things going again, but now
				 * ping will start sending to next target IP
				 * address.
				 */
				send_scheduled_probe();
				(void) sigset(SIGALRM, sigalrm_handler);
				schedule_sigalrm();
			}
			return;
		} else {
			/*
			 * If we are not moving to next targetaddr, let's
			 * release the SIGALRM now. We don't want to stall in
			 * the middle of probing a targetaddr if the pr_name()
			 * call (see below) takes longer.
			 */
			if (!last_reply_from_targetaddr)
				(void) sigrelse(SIGALRM);
			/* else, we'll release it later */
		}

		/*
		 * If we are using send_reply, the real target address is
		 * not the src address of the replies. Use icmp_seq to find out
		 * where this probe was sent to.
		 */
		if (send_reply) {
			(void) find_dstaddr(ntohs(icp->icmp_seq), &dst_addr);
			Printf("%d bytes from %s: ", cc,
			    pr_name((char *)&dst_addr.addr,  AF_INET));
		} else {
			Printf("%d bytes from %s: ", cc,
			    pr_name((char *)&from->sin_addr, AF_INET));
		}
		Printf("icmp_seq=%d. ", ntohs(icp->icmp_seq));
		Printf("orig = %lu, recv = %lu, xmit = %lu ",
		    (ulong_t)ntohl(icp->icmp_otime),
		    (ulong_t)ntohl(icp->icmp_rtime),
		    (ulong_t)ntohl(icp->icmp_ttime));

		if (valid_reply) {
			/*
			 * icp->icmp_otime is the time passed since midnight.
			 * Therefore we need to adjust tv value, which is
			 * the time passed since Jan 1, 1970.
			 */
			triptime = (tv.tv_sec % (24LL * 60 * 60)) * MILLISEC +
			    (tv.tv_usec / (MICROSEC/MILLISEC));
			triptime -= ntohl(icp->icmp_otime);
			if (triptime < 0)
				triptime += 24LL * 60 * 60 * MILLISEC;

			Printf("time=%d. ms", (int)triptime);
			triptime *= (MICROSEC/MILLISEC);
			tsum += triptime;
			tsum2 += triptime*triptime;
			if (triptime < tmin)
				tmin = triptime;
			if (triptime > tmax)
				tmax = triptime;
		}
		(void) putchar('\n');
		/*
		 * If it's stats, probe-all, npackets > 0, and we received reply
		 * for the last probe sent to this target address, then we
		 * don't need to wait anymore, let's move on to next target
		 * address, now!
		 */
		if (last_reply_from_targetaddr) {
			(void) alarm(0);	/* cancel alarm */
			current_targetaddr->probing_done = _B_TRUE;
			(void) sigrelse(SIGALRM);
			send_scheduled_probe();
			schedule_sigalrm();
		}
		break;
	case ICMP_ROUTERADVERT:
	case ICMP_ROUTERSOLICIT:
		/* Router discovery messages */
		return;

	case ICMP_ECHO:
	case ICMP_TSTAMP:
	case ICMP_IREQ:
	case ICMP_MASKREQ:
		/* These were never passed out from the SunOS 4.X kernel. */
		return;

	case ICMP_IREQREPLY:
	case ICMP_MASKREPLY:
		/* Replies for information and address mask requests */
		return;

	default:
		if (verbose) {
			Printf("%d bytes from %s:\n", cc,
			    pr_name((char *)&from->sin_addr, AF_INET));
			Printf("icmp_type=%d (%s) ",
			    icp->icmp_type, pr_type(icp->icmp_type));
			Printf("icmp_code=%d\n", icp->icmp_code);
			for (i = 0; i < 12; i++) {
				Printf("x%2.2x: x%8.8x\n",
				    i * sizeof (int32_t), *intp++);
			}
		}
		break;
	}

	buf += sizeof (struct ip);
	hlen -= sizeof (struct ip);

	/* if verbose and there exists IP options */
	if (verbose && hlen > 0)
		pr_options((uchar_t *)buf, hlen);
}
コード例 #11
0
ファイル: thread.c プロジェクト: breily/twine
void twine_mutex_unlock(twine_mutex *lockVar) {
    sighold(SIGALRM);
    lockVar->value = 0;         // 0 = unlocked
    sigrelse(SIGALRM);
}
コード例 #12
0
ファイル: rmt_server.c プロジェクト: likev/CodeOrpgPub
void
  RMTD_server_main
  (
) {
    int port_number, sig;            /* parent port number */

    /* Get a port number for the server */
    port_number = PNUM_get_port_number ();
    if (port_number == FAILURE) {
        MISC_log ("Can not find a port number\n");
        exit (1);
    }

    /* initialize client registration module */
    if (CLRG_initialize (N_child) == FAILURE)
        exit (1);

    /* open the message server sockets */
    if (MSGD_open_msg_server (port_number) == FAILURE)
        exit (2);

    /* open the RPC server socket */
    if ((Rpc_pfd = SOCD_open_server (port_number)) == FAILURE) {
        MISC_log ("Opening server failed\n");
        exit (2);
    }

    MISC_log ("Max number of children set to %d", N_child);
    MISC_log ("The port number is %d", port_number);

    /* go to background */
    if (Run_in_background)
        Goto_background ();
  
    RMT_access_disc_file (1, " \n", 3);

    /* Catch SIGCLD for calling wait to remove dead child */
    if (Set_signal_action (SIGCLD, Sigcld_int) == FAILURE)
        exit (1);

    for (sig = 1; sig <= 32; sig++) {	/* catch other signals */
	if (sig == SIGCLD || sig == SIGKILL || sig == SIGSTOP)
	    continue;
	if (sig == SIGPIPE)
	    Set_signal_action (sig, SIG_IGN);
	else
	    Set_signal_action (sig, Termination_exit);
    }

    /* write the PID to the file */
    MISC_log ("PID: %d", (int) getpid());

    MISC_log ("%s starts operation\n", Prog_name);
    while (1) {		/* The main loop. It never ends. */
	int sfd[2];     /* socket fd pairs created by the stream pipe */

	if (Iamchild == RMT_TRUE) {	/* The child */

#ifdef THREADED
	    int rtn;
	    if ((rtn = pthread_attr_init (&pthread_custom_attr)) != 0) {
                MISC_log ("pthread_attr_init failed %d:%s\n", 
						rtn, strerror (rtn));
                exit(0);
            }
	    if (( rtn = pthread_attr_setdetachstate (&pthread_custom_attr,
                                       PTHREAD_CREATE_DETACHED)) != 0) {
                MISC_log ("pthread_attr_setdetachstate failed %d:%s\n", 
					rtn,strerror(rtn));
                exit(0);
            }
#else
	    void *buf;
	    Manage_clients (MC_INIT, 0, &buf);
#endif

	    while (1) {
		int fd;		/* client fd */
	
#ifdef THREADED
		{		/* waiting for a new fd from the parent */
		    fd_set readfds;
		    FD_ZERO (&readfds);
		    FD_SET (sfd[0], &readfds);
		    select (FD_SETSIZE, &readfds, NULL, NULL, NULL);
		}
		if ((fd = Receive_pipe_msg_from_parent (sfd[0])) < 0)
		    continue;
		pthread_mutex_lock (&countMutex);
		Num_threads++;
		pthread_mutex_unlock (&countMutex);
                pthread_create (&newThread, &pthread_custom_attr, 
						Process_child, (void *)fd);
#else
		fd = Manage_clients (MC_POLL, sfd[0], &buf);
		if (fd >= 0) {
		    int ret = Process_child (fd);
		    if (ret < 0)
			Manage_clients (MC_DELETE, fd, &buf);
		}
#endif
	    }
	}
	else {				/* parent */
	    int cpid;
	    int fd;		/* client fd */

	    sigrelse (SIGCHLD);
	    if (RMT_reread_config) {
		MISC_log ("Re-read configuration file %s\n", Conf_name);
		GCLD_initialize_host_table (Conf_name);
		MSGD_process_msgs (-1); 
		RMT_reread_config = 0;
		Conf_update_count++;
	    }
	    MSGD_process_msgs (Rpc_pfd); 
	    sighold (SIGCHLD);

	    /* accept new clients */
	    while (1) {
		int cl_type, cl_pid;
		unsigned int cl_addr;	/* LBO */
		int ret = 0;
		Client_regist newCl;

		if ((fd = GCLD_get_client (Rpc_pfd, &cl_type, 
					&cl_pid, &cl_addr)) == FAILURE)
		    break;

		if (cl_type == RMT_MULTIPLE_CLIENT && 
			(ret = CLRG_get_client_info (cl_pid, cl_addr)) > 0) {
		    Send_pipe_msg_to_child (ret, fd);
		    close (fd);			/* close client socket */
		}
		else {	/* no child for this client */

		    /* create a pipe to the child */
		    if (socketpair (AF_UNIX, SOCK_STREAM, 0, sfd) < 0) {
			MISC_log ("Pipe creation failed (errno = %d)", errno);
			close (fd);		/* close client socket */
			continue;
		    }
		    if (Send_pipe_msg_to_child (sfd[1], fd) == FAILURE) {
			close (fd);		/* close client socket */
		    	close (sfd[0]);		/* close pipe */
		    	close (sfd[1]);		/* close pipe */
			continue;
		    }

		    if (cl_type == RMT_SINGLE_CLIENT && cl_pid != 0)
			CLRG_term_client (cl_pid, cl_addr);

		    /* fork a child */
		    Cl_addr = cl_addr;
		    if ((cpid = fork ()) == 0) {
			int sig;
			for (sig = 1; sig <= 32; sig++) {
			    if (sig == SIGPIPE)
				Set_signal_action (sig, SIG_IGN);
			    else
				Set_signal_action (sig, SIG_DFL);
			}
		    	close (Rpc_pfd); 	/* Close parent socket fd */
			MSGD_close_msg_clients ();	/* close msg fds */
			RMTSM_close_msg_hosts ();	/* close msg fds */
		    	CLRG_close_other_client_fd (sfd[0]);
			close (fd);		/* close client socket */
		    	close (sfd[1]);		/* close parent side pipe */
			RMT_access_disc_file (0, NULL, 0);
		    	Iamchild = RMT_TRUE;	/* we must set this after 
						   	stopping timer */
		    	break;
		    }
		    else if (cpid < 0) {
		    	close (fd);	      /* close client socket */
		    	close (sfd[0]);       /* close pipe */
		    	close (sfd[1]);	      /* close pipe */
		    	MISC_log ("fork failed (errno = %d)",errno);
		    }
		    else {
			/* register the new client */
			newCl.childPid = cpid;		/* child pid */
			newCl.addr = cl_addr;		/* client addr */
			newCl.clientPid = cl_pid;	/* client pid */
			newCl.pipeFd = sfd[1];		/* to-child pipe fd */
		    	if (CLRG_register_client (&newCl) != SUCCESS)
			    close (sfd[1]);
			close (sfd[0]);		/* close child side pipe */
		    	close (fd);		/* close client socket */
		    }
		}
	    }
	}
    }
}
コード例 #13
0
ファイル: X001TrsSrv.c プロジェクト: HollyLoong/online
int main(short    argc, char **argv)
{
    char        sSrcSrvId[SRV_ID_LEN+1];
    char        sToSrvId[SRV_ID_LEN+1];
    char        sMsgInBuf[MSQ_MSG_SIZE_MAX];
    char        sIntMsgBuf[MSQ_MSG_SIZE_MAX];
    char        sMsgOutBuf[MSQ_MSG_SIZE_MAX];
    char        sMsgOutBuf1[MSQ_MSG_SIZE_MAX];
    int         nMsgInLen;
    int         nIntMsgLen;
    int         nMsgOutLen;
    char        sMsqType[FLD_MSQ_TYPE_LEN+1];
    int        nReturnCode;
    long        lMsqType;
    HSMOprDef       tHsmOpr;
    char        sMacBLen[4];
    tbl_term_key_def tTblTermKeyDef;  
    tbl_ins_key_def tTblInskeyDef;
    char     szMacKey[9] ;
    char     szMac[9] ;
        long   lBeginTime, lEndTime;
        struct tms       tTMS;
    char  sTempSrvid[4+1];
    char        sMonMsgBuf[MSQ_MSG_SIZE_MAX];
    
    if(argc < 3)
    {
        printf("Usage:%s srvid seq\n", argv[0]);
        exit(-1);
    }

    nReturnCode = TrsSrvInit (argc, argv);
    if (nReturnCode)
    {
        printf("TrsSrv: TrsSrvInit error[%d]\n",nReturnCode);
        exit(-2);
    }
    
    if (sigset(SIGTERM, HandleExit) == SIG_ERR)
    {
        HtLog (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__, 
                "sigset SIGTERM error, %d.", errno);
        exit(-3);
    }

    HtLog (gsTmpLogFile, HT_LOG_MODE_NORMAL, __FILE__,__LINE__, "TrsSrv started.");

    while (1)
    {
        memset (sMsgInBuf, 0, sizeof(sMsgInBuf) );
        nMsgInLen = MSQ_MSG_SIZE_MAX;
        sigrelse (SIGTERM);

        HtLog (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__, "recv begin, ");
        nReturnCode = MsqRcv(gsSrvId, gatSrvMsq, 0, MSQ_RCV_MODE_BLOCK, &nMsgInLen, sMsgInBuf);
        HtLog ("test.log", HT_LOG_MODE_ERROR, __FILE__,__LINE__,"sMsgInBuf:[%s]",sMsgInBuf); 

        sighold(SIGTERM);

        if (nReturnCode)
        {
            if (nReturnCode != ERR_CODE_MSQ_BASE + EINTR)
            {
                HtLog( gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__, "MsqRcv error, %d.", nReturnCode);
                exit(-4);
            }
            else
                continue;
        }

        lBeginTime = lEndTime = 0;
        lBeginTime = times(&tTMS);

        /* uncompress msg */
        if (!strcmp (gsParamMsgCompressFlag, FLAG_YES))
        {
            /* uncompress msg */
            /* sMsgBuf, nMsgLen -> sIntMsgBuf, nIntMsgLen */
            memset(sIntMsgBuf,0,sizeof(sIntMsgBuf));
            UnCompressbuf(sMsgInBuf, nMsgInLen, sIntMsgBuf, &nIntMsgLen);
            memset(sMsgInBuf,0,sizeof(sMsgInBuf));
            nMsgInLen = nIntMsgLen;
            memcpy (sMsgInBuf, sIntMsgBuf, nIntMsgLen);
        }

        memset (sSrcSrvId, 0, sizeof (sToSrvId));
        memcpy (sSrcSrvId, sMsgInBuf, SRV_ID_LEN);

        memset (sToSrvId, 0, sizeof (sToSrvId));
        memcpy (sToSrvId, sMsgInBuf+SRV_ID_LEN, SRV_ID_LEN);

        memset(&tIpcIntTxn, 0, sizeof(T_IpcIntTxnDef));
        memcpy(&tIpcIntTxn, sMsgInBuf, nMsgInLen);
		HtLog (gsLogFile, HT_LOG_MODE_NORMAL, __FILE__,__LINE__, "cF061Ind =%c sChAuthInfoLen=  %.3s",tIpcIntTxn.cF061Ind, tIpcIntTxn.sChAuthInfoLen);
		HtLog (gsLogFile, HT_LOG_MODE_NORMAL, __FILE__,__LINE__, "sChAuthInfo=  %s", tIpcIntTxn.sChAuthInfo);
	
        HtLog (gsLogFile, HT_LOG_MODE_NORMAL, __FILE__,__LINE__, "key_rsp[%s].", tIpcIntTxn.sKeyRsp);
                
#if 1
        if ( tIpcIntTxn.sTxnNum[INDEX_TXN_NUM_TYPE] == TXN_NUM_MANAGE || 
             tIpcIntTxn.sTxnNum[INDEX_TXN_NUM_TYPE] == TXN_NUM_POS_MANAGE &&
                memcmp(tIpcIntTxn.sTxnNum, "8311", 4) != 0)
        {
            HtLog (gsTmpLogFile, HT_LOG_MODE_NORMAL, __FILE__,__LINE__, "debugipcindex=2");
            HtDebugIpc(gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, 2, sMsgInBuf, gstDebugIpc);
        }
        else
        {
            HtDebugIpc(gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, 1, sMsgInBuf, gstDebugIpc);
        }
#endif
        //HtDebugString (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__,sMsgInBuf, nMsgInLen); 

        #if 0 /* 20140123 delete  */        
        /*add by lining for txn_num 8841 to change the DestSrvId to be 1602 */
        memset(sTempSrvid, 0x00, sizeof(sTempSrvid));    
        if (!memcmp(((T_IpcIntTxnDef *)sMsgInBuf)->sTxnNum, "8841", 4) && (!memcmp(sMsgInBuf, "28",2)))
        {
            memcpy(sTempSrvid, sMsgInBuf+SRV_ID_LEN, SRV_ID_LEN);
            memcpy(sMsgInBuf+SRV_ID_LEN, "1602", SRV_ID_LEN);
        }
        /*add end */
        #endif 

        /* msg format convert */
        nMsgOutLen = MSQ_MSG_SIZE_MAX;
		//if(memcmp(sMsgInBuf+SRV_ID_LEN,"1701",SRV_ID_LEN)==0)
		//	memcpy(sMsgInBuf+SRV_ID_LEN,"1702",SRV_ID_LEN);
		//HtDebugString (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__, sMsgInBuf, nMsgInLen);
					

		/*nReturnCode = CvtInToOut (gatConvType, gatUsageTransRule, &tIpcDftRule, &tBufChgRule, nMsgInLen, sMsgInBuf, &nMsgOutLen, sMsgOutBuf);*/ /*modify by zhouq 2014-02-26*/
        nReturnCode = CvtInToOut (gatConvType, gatUsageTransRule, &tIpcDftRule, &tBufChgRule, nMsgInLen, sMsgInBuf, &nMsgOutLen, sMsgOutBuf,tRspCodeMap);
        if (nReturnCode)
        {
            HtLog (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__,"CvtIntoOut error [%d] %4.4s ", nReturnCode,tIpcIntTxn.sTxnNum);
            /*HtDebugString(gsTmpLogFile, HT_LOG_MODE_ERROR,__FILE__, __LINE__, sMsgInBuf, nMsgInLen);*/
            continue;
        }

        #if 0 /* 20140123 delete */
        /*add by lining for txn_num 8841 to resume the DestSrvId  */
        if (!memcmp(((T_IpcIntTxnDef *)sMsgInBuf)->sTxnNum, "8841", 4) && (!memcmp(sMsgInBuf, "28",2)))
        {
            memcpy(sMsgInBuf+SRV_ID_LEN, sTempSrvid, SRV_ID_LEN);
            memcpy(sMsgOutBuf+SRV_ID_LEN, sTempSrvid, SRV_ID_LEN);
        }
        /*add end */
        #endif 

        memcpy(sMsgOutBuf+8, sMsgInBuf+8, 16); /* for test only */
        HtDebugString (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__,sMsgOutBuf, nMsgOutLen); 
        HtLog (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__,"nMsgOutLen=%d, 2*srvid+msqtype=[%.24s]", nMsgOutLen,sMsgOutBuf);
        
        /* s: xj 去往pos端的交易 */
        //if( (memcmp(sToSrvId, "2807", 4) == 0 || memcmp(sToSrvId, "2802", 4) == 0) && tIpcIntTxn.sTxnNum[0] != '6' && tIpcIntTxn.sTxnNum[0] != '8' )
        //20131123 modify 
        //if( memcmp(sToSrvId, "28", 2) == 0 && tIpcIntTxn.sTxnNum[0] != '6' && tIpcIntTxn.sTxnNum[0] != '8' )
		if(memcmp(sToSrvId, "1706", SRV_ID_LEN) == 0)
		{
			AddFld56(sMsgOutBuf+(SRV_ID_LEN*2+FLD_MSQ_TYPE_LEN)-2,nMsgOutLen-SRV_ID_LEN*2-FLD_MSQ_TYPE_LEN,&nMsgOutLen);
			nMsgOutLen=nMsgOutLen+SRV_ID_LEN*2+FLD_MSQ_TYPE_LEN;
			HtDebugString (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__,sMsgOutBuf, nMsgOutLen); 
		}

		if((memcmp(sToSrvId, "1708", SRV_ID_LEN) == 0)&&(memcmp(sSrcSrvId, "1201", SRV_ID_LEN) == 0))
		{
			AddFld57(sMsgOutBuf+(SRV_ID_LEN*2+FLD_MSQ_TYPE_LEN)-2,nMsgOutLen-SRV_ID_LEN*2-FLD_MSQ_TYPE_LEN,&nMsgOutLen);
			nMsgOutLen=nMsgOutLen+SRV_ID_LEN*2+FLD_MSQ_TYPE_LEN;
			HtDebugString (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__,sMsgOutBuf, nMsgOutLen); 
		}

        if((memcmp(sToSrvId, "1709", SRV_ID_LEN) == 0))
		{
			AddFld21(sMsgOutBuf+(SRV_ID_LEN*2+FLD_MSQ_TYPE_LEN)-2,nMsgOutLen-SRV_ID_LEN*2-FLD_MSQ_TYPE_LEN,&nMsgOutLen);
			nMsgOutLen=nMsgOutLen+SRV_ID_LEN*2+FLD_MSQ_TYPE_LEN;
			HtDebugString (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__,sMsgOutBuf, nMsgOutLen); 
		}
		
        if( ( memcmp(sToSrvId, "28", 2) == 0 || memcmp(sToSrvId, "1701", SRV_ID_LEN) == 0 
			|| memcmp(sToSrvId, "1705", SRV_ID_LEN) == 0|| memcmp(sToSrvId, "1706", SRV_ID_LEN) == 0
			|| memcmp(sToSrvId, "1707", SRV_ID_LEN) == 0||memcmp(sToSrvId, "1717", SRV_ID_LEN) == 0
			||memcmp(sToSrvId, "1727", SRV_ID_LEN) == 0|| memcmp(sToSrvId, "1709", SRV_ID_LEN) == 0
			|| memcmp(sToSrvId, "1708", SRV_ID_LEN) == 0||memcmp(sToSrvId, "1801", SRV_ID_LEN) == 0) && 
            ( tIpcIntTxn.sTxnNum[0] != '6' && tIpcIntTxn.sTxnNum[0] != '8' ) )
        {
            nReturnCode = PackSendGenMac(sMsgInBuf, sMsgOutBuf, nMsgOutLen);
            if (nReturnCode) 
            {
                HtLog(gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, "PackSendGenMac error [%d]", nReturnCode);
                continue;
            }
        }
        /* e: */
        if(memcmp(sMsgInBuf+SRV_ID_LEN, "1901", SRV_ID_LEN) == 0 || memcmp(sMsgInBuf+SRV_ID_LEN, "28", SRV_ID_LEN-2) == 0)
        {
            memset (sMsqType, 0, sizeof (sMsqType));
            memcpy (sMsqType, sMsgInBuf+SRV_ID_LEN*2, FLD_MSQ_TYPE_LEN);
            lMsqType = atol (sMsqType);
        }
        else
        {
            lMsqType = 0; 
        }
               
        /* send msg */
        HtLog (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__, "send to %4.4s ",sToSrvId);

        HtLog (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__, "nMsgOutLen [%d]", nMsgOutLen);

        HtLog(gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__, __LINE__, "sMsqType: [%ld]", lMsqType);

        HtDebugString(gsTmpLogFile,HT_LOG_MODE_ERROR,__FILE__,__LINE__, sMsgOutBuf, nMsgOutLen);

        lEndTime = times( &tTMS);

        HtLog (gsTmpLogFile, HT_LOG_MODE_NORMAL, __FILE__, __LINE__, " Processed, Used [%ld] Ticks", lEndTime - lBeginTime);
        HtDebugString (gsTmpLogFile, HT_LOG_MODE_NORMAL, __FILE__,__LINE__, sMsgOutBuf, nMsgOutLen);
		unsigned char i=100;
		while(i--)
		{
			nReturnCode = MsqSnd (sToSrvId, gatSrvMsq, lMsqType, nMsgOutLen, sMsgOutBuf);
			if (nReturnCode)
	        {
	            HtLog ("MsqErr.log", HT_LOG_MODE_ERROR, __FILE__,__LINE__, 
	                "MsqSnd to %s error Num[%d], %d. %d [%s]", sToSrvId, i, nReturnCode,errno,strerror(errno));
	            usleep(100000);
	        }
			else
				break;
		}
        if (nReturnCode)
        {
			HtLog ("MsqErr.log", HT_LOG_MODE_ERROR, __FILE__,__LINE__, "MsqSnd to %s error end", sToSrvId);
            HtLog (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__, 
                    "MsqSnd to %s error, %d.", sToSrvId, nReturnCode);
            continue;
        }
        #if 1
        /*add by zhouq :send to moni*/
        if( memcmp(sToSrvId,"28",SRV_ID_LEN-2)== 0 &&  
        	  tIpcIntTxn.sTxnNum[INDEX_TXN_NUM_TYPE] != TXN_NUM_MANAGE  && 
            tIpcIntTxn.sTxnNum[INDEX_TXN_NUM_TYPE] != TXN_NUM_POS_MANAGE )
        {
        	     HtLog (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__,"sRespCode:[%2.2s]",tIpcIntTxn.sRespCode); 
        	     if( ( tIpcIntTxn.sTxnNum[INDEX_TXN_NUM_TYPE] == TXN_NUM_REVSAL  || 
                     tIpcIntTxn.sTxnNum[INDEX_TXN_NUM_TYPE] == TXN_NUM_CANCEL_REVSAL
                    ) && memcmp(tIpcIntTxn.sRespCode,"00",2) == 0 
                  )  /*冲正成功排除,brige已经送到监控*/
                    continue;
                    
        	     HtLog (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__,"gsMonSrvId:[%s]",gsMonSrvId);
        	     /*memset(sMonMsgBuf, 0, sizeof(sMonMsgBuf) );
        	     memcpy(sMonMsgBuf,sMsgInBuf,nMsgInLen);
               memcpy(sMonMsgBuf,gsSrvId,SRV_ID_LEN);
               memcpy(sMonMsgBuf+SRV_ID_LEN,gsMonSrvId,SRV_ID_LEN);*/
               nReturnCode = MsqSnd (gsMonSrvId, gatSrvMsq, 0, nMsgInLen, sMsgInBuf);
               if (nReturnCode)
               {
                    HtLog (gsTmpLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__, 
                              "MsqSnd to %s error, %d.", gsMonSrvId, nReturnCode);
                    continue;
               }
        }
        /*add end*/
        #endif
    }
}
コード例 #14
0
ファイル: sillythreads.c プロジェクト: ssalenik/nothomework
/**
 * Modified version of the swap.c example provided on http://cgi.cs.mcgill.ca/~xcai9/2012_comp_310.html
 *
 * The scheduling algorithm; selects the next context to run, then starts it.
 */
void scheduler() {
	sighold(SIGALRM);

#if DEBUG == 1
	char print[100];
#endif

	// increment current thread run time
	threads[current_thread]->total_time += quantum;

	// check if thread has completed
	if (threads[current_thread]->state == EXIT) {
#if DEBUG == 1
		sprintf(print, "thread %d completed, run time: %d\n", current_thread,
				threads[current_thread]->total_time);
		perror(print);
#endif

	} else if (threads[current_thread]->state == WAIT) {

#if DEBUG == 1
		sprintf(print, "thread %d blocked\n", current_thread);
		perror(print);
#endif

	} else {
		// else append it to the end of the runqueue
		threads[current_thread]->state = RUNNABLE;
		list_append_int(runqueue, current_thread);

#if DEBUG == 1
		sprintf(print, "thread %d put on runqueue, run time: %d\n",
				current_thread, threads[current_thread]->total_time);
		perror(print);
#endif

	}

	// get the next thread waiting to run from the run queue
	current_thread = list_shift_int(runqueue);

	// check if there is a next item
	// current_thread is 0 if there is not
	if (current_thread == 0) {
		// return to main context
#if DEBUG == 1
		perror("all threads completed\n");
#endif

		//turn off timer
		sighold(SIGALRM);
		it.it_interval.tv_usec = 0;
		it.it_value.tv_usec = 0;

		//returns to main context
		return;
	} else {
		// else run next thread on queue
		threads[current_thread]->state = RUNNING;
#if DEBUG == 1
		sprintf(print, "scheduling thread %d\n", current_thread);
		perror(print);
#endif
		sigrelse(SIGALRM);
		setcontext(threads[current_thread]->context);
	}
}
コード例 #15
0
ファイル: D001Daemon.c プロジェクト: HollyLoong/online
void vHandleChange( int n )
{
    char    sFuncName[] = "vHandleChange";
    int        llEnvNum;
    int        llSrvNum;
    int        i, k;
    int        llResult;
    pid_t    llPid;
    int        ln_proc_num;

    HtLog(    gsLogFile, HT_LOG_MODE_NORMAL, __FILE__,__LINE__, "%s begin.", sFuncName);

    sighold( SIGUSR1 );

    /* open cursor */
    EXEC SQL open dm_srv_inf_cur;
    if (sqlca.sqlcode)
    {
        HtLog(    gsLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__, "Open cursor error, %d.", sqlca.sqlcode);
        return ;
    }
    
    llEnvNum = 0;
    for (;;)
    {
        /* get a srv inf */
        memset (hsSrvId, 0, sizeof (hsSrvId));
        memset (hsSrvNum, 0, sizeof (hsSrvNum));
        
        EXEC SQL fetch dm_srv_inf_cur into
             :hsSrvId, :hsSrvNum;
            
        if (sqlca.sqlcode == DBS_NOTFOUND)
            break;
            
        if (sqlca.sqlcode)
        {
            HtLog(    gsLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__, "Fetch error, %d.", sqlca.sqlcode);
            break;
        }
        llSrvNum = atoi (hsSrvNum);
            
        memcpy (genvProcEnv[ llEnvNum ].sSrvId, hsSrvId, SRV_ID_LEN);
        llEnvNum++;
        ln_proc_num = lGetProcNum( hsSrvId );
        if( ln_proc_num == llSrvNum )
            continue;
        else if( ln_proc_num > llSrvNum )
        {
            i = ln_proc_num - llSrvNum;
            for( k = 0; k < DM_MAX_PROC_NUM; k++ )
            {
                if(( gpcbaList[ k ].pid != -1 ) && 
                    ( !memcmp (gpcbaList[ k ].sSrvId, hsSrvId, SRV_ID_LEN) ) )
                {
                    llResult = kill( gpcbaList[ k ].pid, SIGTERM );
                    if( llResult == -1 )
                    {
                        HtLog(    gsLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__, "kill server %s pid %d error, %d.", gpcbaList[ k ].sSrvId, gpcbaList[ k ].pid, errno);
                    }
                    gpcbaList[ k ].pid = -1;
                    i--;
                    if( i <= 0 )
                        break;
                }
            }
        }
        else
        {
            for( i = 0; i < llSrvNum - ln_proc_num; i++ )
            {
                llPid = lStartProcess( hsSrvId, ln_proc_num+i+1 );
                if( llPid != -1 )
                {
                    llResult = lInsertPid( llPid, hsSrvId, ln_proc_num+i+1 );
                    if( llResult )
                    {
                        HtLog(    gsLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__, "lInsertPid error, server id %s.", hsSrvId);
                    }
                }
                else
                {
                    HtLog(    gsLogFile, HT_LOG_MODE_ERROR, __FILE__,__LINE__, "lStartProcess error, server id %s.", hsSrvId);
                }
            }
        }
    }
    EXEC SQL close dm_srv_inf_cur;

    sigrelse( SIGUSR1 );
    sigset( SIGUSR1, vHandleChange );
    
    HtLog(    gsLogFile, HT_LOG_MODE_NORMAL, __FILE__,__LINE__, "%s end.", sFuncName);
}/* end of vHandleChange */
コード例 #16
0
ファイル: AF.c プロジェクト: tongfw/pcp
static void AFhold(void)  { sighold(SIGALRM); }
コード例 #17
0
ファイル: ctfconvert.c プロジェクト: NextBSD/NextBSD
int
main(int argc, char **argv)
{
    tdata_t *filetd, *mstrtd;
    const char *label = NULL;
    int verbose = 0;
    int ignore_non_c = 0;
    int keep_stabs = 0;
    int c;

#ifdef illumos
    sighold(SIGINT);
    sighold(SIGQUIT);
    sighold(SIGTERM);
#endif

    progname = basename(argv[0]);

    if (getenv("CTFCONVERT_DEBUG_LEVEL"))
        debug_level = atoi(getenv("CTFCONVERT_DEBUG_LEVEL"));
    if (getenv("CTFCONVERT_DEBUG_PARSE"))
        debug_parse = atoi(getenv("CTFCONVERT_DEBUG_PARSE"));

    while ((c = getopt(argc, argv, ":l:L:o:givs")) != EOF) {
        switch (c) {
        case 'l':
            label = optarg;
            break;
        case 'L':
            if ((label = getenv(optarg)) == NULL)
                label = CTF_DEFAULT_LABEL;
            break;
        case 'o':
            outfile = optarg;
            break;
        case 's':
            dynsym = CTF_USE_DYNSYM;
            break;
        case 'i':
            ignore_non_c = 1;
            break;
        case 'g':
            keep_stabs = CTF_KEEP_STABS;
            break;
        case 'v':
            verbose = 1;
            break;
        default:
            usage();
            exit(2);
        }
    }

    if (getenv("STRIPSTABS_KEEP_STABS") != NULL)
        keep_stabs = CTF_KEEP_STABS;

    if (argc - optind != 1 || label == NULL) {
        usage();
        exit(2);
    }

    infile = argv[optind];
    if (access(infile, R_OK) != 0)
        terminate("Can't access %s", infile);

    /*
     * Upon receipt of a signal, we want to clean up and exit.  Our
     * primary goal during cleanup is to restore the system to a state
     * such that a subsequent make will eventually cause this command to
     * be re-run.  If we remove the input file (which we do if we get a
     * signal and the user didn't specify a separate output file), make
     * will need to rebuild the input file, and will then need to re-run
     * ctfconvert, which is what we want.
     */
    set_terminate_cleanup(terminate_cleanup);

#ifdef illumos
    sigset(SIGINT, handle_sig);
    sigset(SIGQUIT, handle_sig);
    sigset(SIGTERM, handle_sig);
#else
    signal(SIGINT, handle_sig);
    signal(SIGQUIT, handle_sig);
    signal(SIGTERM, handle_sig);
#endif

    filetd = tdata_new();

    if (!file_read(filetd, infile, ignore_non_c))
        terminate("%s doesn't have type data to convert\n", infile);

    if (verbose)
        iidesc_stats(filetd->td_iihash);

    mstrtd = tdata_new();
    merge_into_master(filetd, mstrtd, NULL, 1);

    tdata_label_add(mstrtd, label, CTF_LABEL_LASTIDX);

    /*
     * If the user supplied an output file that is different from the
     * input file, write directly to the output file.  Otherwise, write
     * to a temporary file, and replace the input file when we're done.
     */
    if (outfile && strcmp(infile, outfile) != 0) {
        write_ctf(mstrtd, infile, outfile, dynsym | keep_stabs);
    } else {
        char *tmpname = mktmpname(infile, ".ctf");
        write_ctf(mstrtd, infile, tmpname, dynsym | keep_stabs);
        if (rename(tmpname, infile) != 0)
            terminate("Couldn't rename temp file %s", tmpname);
        free(tmpname);
    }

    return (0);
}
コード例 #18
0
ファイル: main.c プロジェクト: drscream/illumos-joyent
int
main(int argc, char *argv[])
{
	FILE		*fp;
	char		*abi_comp_ptr;
	char		*abi_sym_ptr;
	char		*p;
	char		*prog_full_name = NULL;
	char		*pt;
	char		*value;
	char		*vfstab_file = NULL;
	char		*zoneName = (char *)NULL;
	char		cmdbin[PATH_MAX];
	char		param[MAX_PKG_PARAM_LENGTH];
	char		path[PATH_MAX];
	char		script[PATH_MAX];
	int		c;
	int		err;
	int		fd;
	int		i;
	int		map_client = 1;
	int		n;
	int		nodelete = 0; 	/* do not delete file or run scripts */
	int		pkgrmremote = 0;	/* dont remove remote objects */
	struct sigaction	nact;
	struct sigaction	oact;
	PKGserver	pkgserver = NULL;
	VFP_T		*tmpfp;

	/* reset contents of all default paths */

	(void) memset(cmdbin, '\0', sizeof (cmdbin));

	/* initialize locale environment */

	(void) setlocale(LC_ALL, "");
	(void) textdomain(TEXT_DOMAIN);

	/* initialize program name */

	prog_full_name = argv[0];
	(void) set_prog_name(argv[0]);

	/* tell spmi zones interface how to access package output functions */

	z_set_output_functions(echo, echoDebug, progerr);

	/* exit if not root */

	if (getuid()) {
		progerr(ERR_NOT_ROOT, get_prog_name());
		exit(1);
		/* NOTREACHED */
	}

	/* Read PKG_INSTALL_ROOT from the environment, if it's there. */

	if (!set_inst_root(getenv("PKG_INSTALL_ROOT"))) {
		progerr(ERR_ROOT_SET);
		exit(1);
	}

	pkgserversetmode(DEFAULTMODE);

	/* parse command line options */

	while ((c = getopt(argc, argv, "?Aa:b:FMN:nO:oR:V:vy")) != EOF) {
		switch (c) {
		/*
		 * Same as pkgrm: Allow admin to remove package objects from
		 * a shared area from a reference client.
		 */
		case 'A':
			pkgrmremote++;
			break;

		/*
		 * Same as pkgrm: Use the installation
		 * administration file, admin, in place of the
		 * default admin file. pkgrm first looks in the
		 * current working directory for the administration
		 * file.  If the specified administration file is not
		 * in the current working directory, pkgrm looks in
		 * the /var/sadm/install/admin directory for the
		 * administration file.
		 */
		case 'a':
			admnfile = flex_device(optarg, 0);
			break;

		/*
		 * Same as pkgrm: location where package executables
		 * can be found - default is /usr/sadm/install/bin.
		 */
		case 'b':
			if (!path_valid(optarg)) {
				progerr(ERR_PATH, optarg);
				exit(1);
			}
			if (isdir(optarg) != 0) {
				char *p = strerror(errno);
				progerr(ERR_CANNOT_USE_DIR, optarg, p);
				exit(1);
			}
			(void) strlcpy(cmdbin, optarg, sizeof (cmdbin));
			break;

		/*
		 * Same as pkgrm: suppresses the removal of any
		 * files and any class action scripts, and suppresses
		 * the running of any class action scripts.  The
		 * package files remain but the package looks like it
		 * is not installed. This is mainly for use by the
		 * upgrade process.
		 */
		case 'F':
			nodelete++;
			break;

		/*
		 * Same as pkgrm: Instruct pkgrm not to use the
		 * $root_path/etc/vfstab file for determining the
		 * client's mount points. This option assumes the
		 * mount points are correct on the server and it
		 * behaves consistently with Solaris 2.5 and earlier
		 * releases.
		 */
		case 'M':
			map_client = 0;
			break;

		/*
		 * Different from pkgrm: specify program name to use
		 * for messages.
		 */
		case 'N':
			(void) set_prog_name(optarg);
			break;

		/*
		 * Same as pkgrm: package removal occurs in
		 * non-interactive mode.  Suppress output of the list of
		 * removed files. The default mode is interactive.
		 */
		case 'n':
			nointeract++;
			(void) echoSetFlag(B_FALSE);
			break;

		/*
		 * Almost same as pkgrm: the -O option allows the behavior
		 * of the package tools to be modified. Recognized options:
		 * -> debug
		 * ---> enable debugging output
		 * -> preremovecheck
		 * ---> perform a "pre removal" check of the specified
		 * ---> package - suppress all regular output and cause a
		 * ---> series of one or more "name=value" pair format lines
		 * ---> to be output that describes the "removability" of
		 * ---> the specified package
		 * -> enable-hollow-package-support
		 * --> Enable hollow package support. When specified, for any
		 * --> package that has SUNW_PKG_HOLLOW=true:
		 * --> Do not calculate and verify package size against target
		 * --> Do not run any package procedure or class action scripts
		 * --> Do not create or remove any target directories
		 * --> Do not perform any script locking
		 * --> Do not install or uninstall any components of any package
		 * --> Do not output any status or database update messages
		 */
		case 'O':
			for (p = strtok(optarg, ","); p != (char *)NULL;
			    p = strtok(NULL, ",")) {

				/* process debug option */

				if (strcmp(p, "debug") == 0) {
					/* set debug flag/enable debug output */
					debugFlag = B_TRUE;
					(void) echoDebugSetFlag(debugFlag);

					/* debug info on arguments to pkgadd */
					for (n = 0; n < argc && argv[n]; n++) {
						echoDebug(DBG_ARG, n, argv[n]);
					}

					continue;
				}

				/* process enable-hollow-package-support opt */

				if (strcmp(p,
				    "enable-hollow-package-support") == 0) {
					set_depend_pkginfo_DB(B_TRUE);
					continue;
				}

				/* process preremovecheck option */

				if (strcmp(p, "preremovecheck") == 0) {
					preremoveCheck = B_TRUE;
					nointeract++;	/* -n */
					nodelete++;	/* -F */
					quitSetSilentExit(B_TRUE);
					continue;
				}

				/* process addzonename option */

				if (strcmp(p, "addzonename") == 0) {
					zoneName = z_get_zonename();
					quitSetZoneName(zoneName);
					continue;
				}

				/* process parent-zone-name option */

				if (strncmp(p, PARENTZONENAME,
				    PARENTZONENAME_LEN) == 0) {
					parentZoneName = p+PARENTZONENAME_LEN;
					continue;
				}

				/* process parent-zone-type option */

				if (strncmp(p, PARENTZONETYPE,
				    PARENTZONETYPE_LEN) == 0) {
					parentZoneType = p+PARENTZONETYPE_LEN;
					continue;
				}

				if (strncmp(p, PKGSERV_MODE,
				    PKGSERV_MODE_LEN) == 0) {
					pkgserversetmode(pkgparsemode(p +
					    PKGSERV_MODE_LEN));
					continue;
				}
				/* option not recognized - issue warning */

				progerr(ERR_INVALID_O_OPTION, p);
				continue;
			}
			break;

		/*
		 * Different from pkgrm: This is an old non-ABI package
		 */

		case 'o':
			script_in = PROC_XSTDIN;
			break;

		/*
		 * Same as pkgrm: defines the full path name of a
		 * directory to use as the root_path.  All files,
		 * including package system information files, are
		 * relocated to a directory tree starting in the
		 * specified root_path.
		 */
		case 'R':
			if (!set_inst_root(optarg)) {
				progerr(ERR_ROOT_CMD);
				exit(1);
			}
			break;

		/*
		 * Same as pkgrm: allow admin to establish the client
		 * filesystem using a vfstab-like file of stable format.
		 */
		case 'V':
			vfstab_file = flex_device(optarg, 2);
			map_client = 1;
			break;

		/*
		 * Same as pkgrm: trace all of the scripts that
		 * get executed by pkgrm, located in the
		 * pkginst/install directory. This option is used for
		 * debugging the procedural and non-procedural
		 * scripts.
		 */
		case 'v':
			pkgverbose++;
			break;

		/*
		 * Different from pkgrm: process this package using
		 * old non-ABI symlinks
		 */
		case 'y':
			set_nonABI_symlinks();
			break;

		default:
			usage();
			/*NOTREACHED*/
			/*
			 * Although usage() calls a noreturn function,
			 * needed to add return (1);  so that main() would
			 * pass compilation checks. The statement below
			 * should never be executed.
			 */
			return (1);
		}
	}

	/*
	 * ********************************************************************
	 * validate command line options
	 * ********************************************************************
	 */

	(void) echoDebugSetFlag(debugFlag);
	(void) log_set_verbose(debugFlag);

	if (z_running_in_global_zone()) {
		echoDebug(DBG_ENTRY_IN_GZ, prog_full_name);
	} else {
		echoDebug(DBG_ENTRY_IN_LZ, prog_full_name, getzoneid(),
		    z_get_zonename());
	}

	/* establish cmdbin path */

	if (cmdbin[0] == '\0') {
		(void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin));
	}

	/* Read the mount table */

	if (get_mntinfo(map_client, vfstab_file)) {
		quit(99);
	}

	/*
	 * This function defines the standard /var/... directories used later
	 * to construct the paths to the various databases.
	 */

	set_PKGpaths(get_inst_root());

	/*
	 * If this is being removed from a client whose /var filesystem is
	 * mounted in some odd way, remap the administrative paths to the
	 * real filesystem. This could be avoided by simply mounting up the
	 * client now; but we aren't yet to the point in the process where
	 * modification of the filesystem is permitted.
	 */
	if (is_an_inst_root()) {
		int fsys_value;

		fsys_value = fsys(get_PKGLOC());
		if (use_srvr_map_n(fsys_value))
			set_PKGLOC(server_map(get_PKGLOC(), fsys_value));

		fsys_value = fsys(get_PKGADM());
		if (use_srvr_map_n(fsys_value))
			set_PKGADM(server_map(get_PKGADM(), fsys_value));
	} else {
		pkgrmremote = 0;	/* Makes no sense on local host. */
	}

	/*
	 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
	 */

	/* hold SIGINT/SIGHUP interrupts */

	(void) sighold(SIGHUP);
	(void) sighold(SIGINT);

	/* connect quit.c:trap() to SIGINT */

	nact.sa_handler = quitGetTrapHandler();
	nact.sa_flags = SA_RESTART;
	(void) sigemptyset(&nact.sa_mask);

	(void) sigaction(SIGINT, &nact, &oact);

	/* connect quit.c:trap() to SIGHUP */

	nact.sa_handler = quitGetTrapHandler();
	nact.sa_flags = SA_RESTART;
	(void) sigemptyset(&nact.sa_mask);

	(void) sigaction(SIGHUP, &nact, &oact);

	/* release hold on signals */

	(void) sigrelse(SIGHUP);
	(void) sigrelse(SIGINT);

	pkginst = argv[optind++];
	if (optind != argc) {
		usage();
	}

	/* validate package software database (contents) file */

	if (vcfile() == 0) {
		quit(99);
	}

	/*
	 * Acquire the package lock - currently at "remove initialization"
	 */

	if (!lockinst(get_prog_name(), pkginst, "remove-initial")) {
		quit(99);
	}

	/* establish temporary directory to use */

	tmpdir = getenv("TMPDIR");
	if (tmpdir == NULL) {
		tmpdir = P_tmpdir;
	}

	echoDebug(DBG_PKGREMOVE_TMPDIR, tmpdir);

	/*
	 * Initialize installation admin parameters by reading
	 * the adminfile.
	 */

	echoDebug(DBG_PKGREMOVE_ADMINFILE, admnfile ? admnfile : "");
	setadminFile(admnfile);

	/*
	 * about to perform first operation that could be modified by the
	 * preremove check option - if preremove check is selected (that is,
	 * only gathering dependencies), then output a debug message to
	 * indicate that the check is beginning. Also turn echo() output
	 * off and set various other flags.
	 */

	if (preremoveCheck == B_TRUE) {
		(void) echoSetFlag(B_FALSE);
		echoDebug(DBG_PKGREMOVE_PRERMCHK, pkginst ? pkginst : "",
		    zoneName ? zoneName : "global");
		rcksetPreremoveCheck(B_TRUE);
		rcksetZoneName(zoneName);
	}

	(void) snprintf(pkgloc, sizeof (pkgloc), "%s/%s", get_PKGLOC(),
	    pkginst);
	(void) snprintf(pkgbin, sizeof (pkgbin), "%s/install", pkgloc);
	(void) snprintf(rlockfile, sizeof (rlockfile), "%s/!R-Lock!", pkgloc);

	if (chdir(pkgbin)) {
		progerr(ERR_CHDIR, pkgbin);
		quit(99);
	}

	echo(MSG_PREREMOVE_REMINST, pkginst);

	/*
	 * if a lock file is present, then a previous attempt to remove this
	 * package may have been unsuccessful.
	 */

	if (access(rlockfile, F_OK) == 0) {
		echo(ERR_UNSUCC);
		echoDebug(DBG_PKGINSTALL_HAS_LOCKFILE, pkginst, rlockfile,
		    zoneName ? zoneName : "global");
	}

	/*
	 * Process all parameters from the pkginfo file
	 * and place them in the execution environment
	 */

	/* Add DB retreival of the pkginfo parameters here */
	(void) snprintf(path, sizeof (path), "%s/pkginfo", pkgloc);
	if ((fp = fopen(path, "r")) == NULL) {
		progerr(ERR_PKGINFO, path);
		quit(99);
	}

	/* Mount up the client if necessary. */
	if (map_client && !mount_client()) {
		logerr(MSG_MANMOUNT);
	}

	/* Get mount point of client */
	client_mntdir = getenv("CLIENT_MNTDIR");

	getuserlocale();

	/*
	 * current environment has been read; clear environment out
	 * so putparam() can be used to populate the new environment
	 * to be passed to any executables/scripts.
	 */

	environ = NULL;

	if (nonABI_symlinks()) {
		putparam("PKG_NONABI_SYMLINKS", "TRUE");
	}

	/*
	 * read the pkginfo file and fix any PKGSAV path - the correct
	 * install_root will be prepended to the existing path.
	 */

	param[0] = '\0';
	while (value = fpkgparam(fp, param)) {
		int validx = 0;
		char *newvalue;

		/* strip out any setting of PATH */

		if (strcmp(param, "PATH") == 0) {
			free(value);
			param[0] = '\0';
			continue;
		}

		/* if not PKGSAV then write out unchanged */

		if (strcmp(param, "PKGSAV") != 0) {
			putparam(param, value);
			free(value);
			param[0] = '\0';
			continue;
		}

		/*
		 * PKGSAV parameter found - interpret the directory:
		 * If in host:path format or marked with the leading "//",
		 * then there is no client-relative translation - take it
		 * literally later rather than use fixpath().
		 */

		if (strstr(value, ":/")) {
			/* no modification needed */
			validx = 0;
		} else if (strstr(value, "//") == value) {
			validx = 1;
		} else if (is_an_inst_root()) {
			/* This PKGSAV needs to be made client-relative. */
			newvalue = fixpath(value);
			free(value);
			value = newvalue;
		}
		putparam(param, value+validx);
		free(value);
		param[0] = '\0';
	}

	(void) fclose(fp);

	/* write parent condition information to environment */

	putConditionInfo(parentZoneName, parentZoneType);

	putuserlocale();

	/*
	 * Now do all the various setups based on ABI compliance
	 */

	/* Read the environment provided by the pkginfo file */
	abi_comp_ptr = getenv("NONABI_SCRIPTS");

	/* if not ABI compliant set global flag */
	abi_sym_ptr = getenv("PKG_NONABI_SYMLINKS");
	if (abi_sym_ptr && strncasecmp(abi_sym_ptr, "TRUE", 4) == 0) {
		set_nonABI_symlinks();
	}

	/*
	 * If pkginfo says it's not compliant then set non_abi_scripts.
	 */
	if (abi_comp_ptr && strncmp(abi_comp_ptr, "TRUE", 4) == 0) {
		script_in = PROC_XSTDIN;
	}

	/*
	 * Since this is a removal, we can tell whether it's absolute or
	 * not from the resident pkginfo file read above.
	 */
	if ((err = set_basedirs((getenv("BASEDIR") != NULL), adm.basedir,
	    pkginst, nointeract)) != 0) {
		quit(err);
	}

	/*
	 * See if were are removing a package that only wants to update
	 * the database or only remove files associated with CAS's. We
	 * only check the PKG_HOLLOW_VARIABLE variable if told to do so by
	 * the caller.
	 */

	if (is_depend_pkginfo_DB()) {
		pt = getenv(PKG_HOLLOW_VARIABLE);

		if ((pt != NULL) && (strncasecmp(pt, "true", 4) == 0)) {
			echoDebug(DBG_PKGREMOVE_HOLLOW_ENABLED);

			/*
			 * this is a hollow package and hollow package support
			 * is enabled -- override admin settings to suppress
			 * checks that do not make sense since no scripts will
			 * be executed and no files will be removed.
			 */

			setadminSetting("conflict", "nocheck");
			setadminSetting("setuid", "nocheck");
			setadminSetting("action", "nocheck");
			setadminSetting("partial", "nocheck");
			setadminSetting("space", "nocheck");
			setadminSetting("authentication", "nocheck");
		} else {
			echoDebug(DBG_PKGREMOVE_HOLLOW_DISABLED);
			set_depend_pkginfo_DB(B_FALSE);
		}
	}

	put_path_params();

	/* If client mount point, add it to pkgremove environment */

	if (client_mntdir != NULL) {
		putparam("CLIENT_MNTDIR", client_mntdir);
	}

	/* Establish the class list and the class attributes. */

	if ((value = getenv("CLASSES")) != NULL) {
		cl_sets(qstrdup(value));
	} else {
		progerr(ERR_CLASSES, path);
		quit(99);
	}

	/* establish path and tmpdir */

	if (cmdbin[0] == '\0') {
		(void) strlcpy(cmdbin, PKGBIN, sizeof (cmdbin));
	}

	(void) snprintf(path, sizeof (path), "%s:%s", DEFPATH, cmdbin);
	putparam("PATH", path);

	putparam("TMPDIR", tmpdir);

	/*
	 * Check ulimit requirement (provided in pkginfo). The purpose of
	 * this limit is to terminate pathological file growth resulting from
	 * file edits in scripts. It does not apply to files in the pkgmap
	 * and it does not apply to any database files manipulated by the
	 * installation service.
	 */
	if (value = getenv("ULIMIT")) {
		if (assign_ulimit(value) == -1) {
			progerr(ERR_BADULIMIT, value);
			warnflag++;
		}
		putparam("PKG_ULIMIT", "TRUE");
	}

	/*
	 * If only gathering dependencies, check and output status of all
	 * remaining dependencies and exit.
	 */

	if (preremoveCheck == B_TRUE) {
		/*
		 * make sure current runlevel is appropriate
		 */

		(void) fprintf(stdout, "rckrunlevel=%d\n", rckrunlevel());

		/*
		 * determine if any packaging scripts provided with
		 * this package will execute as a priviledged user
		 */

		(void) fprintf(stdout, "rckpriv=%d\n", rckpriv());

		/*
		 * verify package dependencies
		 */

		(void) fprintf(stdout, "rckdepend=%d\n", rckdepend());

		/*
		 * ****** preremove check done - exit ******
		 */

		echoDebug(DBG_PKGREMOVE_PRERMCHK_OK);
		quit(0);
		/*NOTREACHED*/
	}

	/*
	 * Not gathering dependencies only, proceed to check dependencies
	 * and continue with the package removal operation.
	 */

	/*
	 * make sure current runlevel is appropriate
	 */

	n = rckrunlevel();

	if (n != 0) {
		quit(n);
		/* NOTREACHED */
	}

	/*
	 * determine if any packaging scripts provided with
	 * this package will execute as a priviledged user
	 */

	n = rckpriv();

	if (n != 0) {
		quit(n);
		/* NOTREACHED */
	}

	/*
	 * verify package dependencies
	 */
	n = rckdepend();

	if (n != 0) {
		quit(n);
		/* NOTREACHED */
	}

	/*
	 * *********************************************************************
	 * the actual removal of the package begins here
	 * *********************************************************************
	 */

	/*
	 * create lockfile to indicate start of removal
	 */
	started++;
	if ((fd = open(rlockfile, O_WRONLY|O_CREAT|O_TRUNC, 0644)) < 0) {
		progerr(ERR_LOCKFILE, rlockfile);
		quit(99);
	} else {
		(void) close(fd);
	}

	if (zoneName == (char *)NULL) {
		echo(MSG_PKGREMOVE_PROCPKG_GZ);
		echoDebug(DBG_PKGREMOVE_PROCPKG_GZ, pkginst, rlockfile);
	} else {
		echo(MSG_PKGREMOVE_PROCPKG_LZ, zoneName);
		echoDebug(DBG_PKGREMOVE_PROCPKG_LZ, pkginst, rlockfile,
		    zoneName);
	}
	if (delmap(0, pkginst, &pkgserver, &tmpfp) != 0) {
		progerr(ERR_DB_QUERY, pkginst);
		quit(99);
	}

	/*
	 * Run a preremove script if one is provided by the package.
	 * Don't execute preremove script if only updating the DB.
	 * Don't execute preremove script if files are not being deleted.
	 */

	/* update the lock - at the preremove script */
	lockupd("preremove");

	/* execute preremove script if one is provided */
	(void) snprintf(script, sizeof (script), "%s/preremove", pkgbin);
	if (access(script, F_OK) != 0) {
		/* no script present */
		echoDebug(DBG_PKGREMOVE_POC_NONE, pkginst,
		    zoneName ? zoneName : "global");
	} else if (nodelete) {
		/* not deleting files: skip preremove script */
		echoDebug(DBG_PKGREMOVE_POC_NODEL, pkginst, script,
		    zoneName ? zoneName : "global");
	} else if (is_depend_pkginfo_DB()) {
		/* updating db only: skip preremove script */
		echoDebug(DBG_PKGREMOVE_POC_DBUPD, pkginst, script,
		    zoneName ? zoneName : "global");
	} else {
		/* script present and ok to run: run the script */
		set_ulimit("preremove", ERR_PREREMOVE);
		if (zoneName == (char *)NULL) {
			echo(MSG_PKGREMOVE_EXEPOC_GZ);
			echoDebug(DBG_PKGREMOVE_EXEPOC_GZ, pkginst, script);
		} else {
			echo(MSG_PKGREMOVE_EXEPOC_LZ, zoneName);
			echoDebug(DBG_PKGREMOVE_EXEPOC_LZ, pkginst, script,
			    zoneName);
		}
		putparam("PKG_PROC_SCRIPT", "preremove");
		if (pkgverbose) {
			ckreturn(pkgexecl(script_in, PROC_STDOUT,
			    PROC_USER, PROC_GRP, SHELL, "-x",
			    script, NULL), ERR_PREREMOVE);
		} else {
			ckreturn(pkgexecl(script_in, PROC_STDOUT,
			    PROC_USER, PROC_GRP, SHELL, script,
			    NULL), ERR_PREREMOVE);
		}
		clr_ulimit();
	}

	/* update the lock - doing removal */

	lockupd("remove");

	/*
	 * Remove all components belonging to this package.
	 * Don't remove components if only updating the DB.
	 * Don't remove components if files are not being deleted.
	 */

	if (nodelete) {
		echoDebug(DBG_PKGREMOVE_REM_NODEL, pkginst,
		    zoneName ? zoneName : "global");
	} else if (is_depend_pkginfo_DB()) {
		echoDebug(DBG_PKGREMOVE_REM_DBUPD, pkginst,
		    zoneName ? zoneName : "global");
	} else {
		echoDebug(DBG_PKGREMOVE_REM, pkginst,
		    zoneName ? zoneName : "global");
		/*
		 * remove package one class at a time
		 */

		/* reverse order of classes */
		for (i = cl_getn() - 1; i >= 0; i--) {
			rmclass(cl_nam(i), pkgrmremote, zoneName);
		}

		rmclass(NULL, pkgrmremote, zoneName);
	}

	z_destroyMountTable();

	/*
	 * Execute postremove script, if any
	 * Don't execute postremove script if only updating the DB.
	 * Don't execute postremove script if files are not being deleted.
	 */

	/* update the lock - at the postremove script */
	lockupd("postremove");

	/* execute postremove script if one is provided */
	(void) snprintf(script, sizeof (script), "%s/postremove", pkgbin);
	if (access(script, F_OK) != 0) {
		/* no script present */
		echoDebug(DBG_PKGREMOVE_PIC_NONE, pkginst,
		    zoneName ? zoneName : "global");
	} else if (nodelete) {
		/* not deleting files: skip postremove script */
		echoDebug(DBG_PKGREMOVE_PIC_NODEL, pkginst, script,
		    zoneName ? zoneName : "global");
	} else if (is_depend_pkginfo_DB()) {
		/* updating db only: skip postremove script */
		echoDebug(DBG_PKGREMOVE_PIC_DBUPD, pkginst, script,
		    zoneName ? zoneName : "global");
	} else {
		/* script present and ok to run: run the script */
		set_ulimit("postremove", ERR_POSTREMOVE);
		if (zoneName == (char *)NULL) {
			echo(MSG_PKGREMOVE_EXEPIC_GZ);
			echoDebug(DBG_PKGREMOVE_EXEPIC_GZ, pkginst, script);
		} else {
			echo(MSG_PKGREMOVE_EXEPIC_LZ, zoneName);
			echoDebug(DBG_PKGREMOVE_EXEPIC_LZ, pkginst, script,
			    zoneName);
		}
		putparam("PKG_PROC_SCRIPT", "postremove");
		putparam("TMPDIR", tmpdir);
		if (pkgverbose) {
			ckreturn(pkgexecl(script_in, PROC_STDOUT, PROC_USER,
			    PROC_GRP, SHELL, "-x", script, NULL),
			    ERR_POSTREMOVE);
		} else {
			ckreturn(pkgexecl(script_in, PROC_STDOUT, PROC_USER,
			    PROC_GRP, SHELL, script, NULL),
			    ERR_POSTREMOVE);
		}
		clr_ulimit();
	}

	if (zoneName == (char *)NULL) {
		echo(MSG_PKGREMOVE_UPDINF_GZ);
	} else {
		echo(MSG_PKGREMOVE_UPDINF_LZ, zoneName);
	}

	if (delmap(1, pkginst, &pkgserver, &tmpfp) != 0) {
		progerr(ERR_DB_QUERY, pkginst);
		quit(99);
	}

	if (!warnflag && !failflag) {
		(void) chdir("/");
		if (rrmdir(pkgloc))
			warnflag++;
	}

	if ((z_running_in_global_zone() == B_TRUE) &&
	    (pkgIsPkgInGzOnly(get_inst_root(), pkginst) == B_TRUE)) {
		boolean_t	b;

		b = pkgRemovePackageFromGzonlyList(get_inst_root(), pkginst);
		if (b == B_FALSE) {
			progerr(ERR_PKGREMOVE_GZONLY_REMOVE, pkginst);
			ckreturn(1, NULL);
		}
	}

	/* release the generic package lock */

	(void) unlockinst();

	pkgcloseserver(pkgserver);

	quit(0);
	/* LINTED: no return */
}
コード例 #19
0
ファイル: runcmd.c プロジェクト: belenix/belenixold
int
esystem(char *cmd, int ifd, int ofd)
{
	char	*perrfile;
	int	status = 0;
	pid_t	pid;

	perrfile = tmpnam(NULL);
	if (perrfile == NULL) {
		progerr(
		    pkg_gt("unable to create temp error file, errno=%d"),
		    errno);
		return (-1);
	}
	(void) strlcpy(errfile, perrfile, sizeof (errfile));

	/* flush standard i/o before creating new process */

	(void) fflush(stderr);
	(void) fflush(stdout);

	/*
	 * create new process to execute command in;
	 * vfork() is being used to avoid duplicating the parents
	 * memory space - this means that the child process may
	 * not modify any of the parents memory including the
	 * standard i/o descriptors - all the child can do is
	 * adjust interrupts and open files as a prelude to a
	 * call to exec().
	 */

	pid = vfork();
	if (pid == 0) {
		/*
		 * this is the child process
		 */
		int	i;

		/* reset any signals to default */

		for (i = 0; i < NSIG; i++) {
			(void) sigset(i, SIG_DFL);
		}

		if (ifd > 0) {
			(void) dup2(ifd, STDIN_FILENO);
		}

		if (ofd >= 0 && ofd != STDOUT_FILENO) {
			(void) dup2(ofd, STDOUT_FILENO);
		}

		i = open(errfile, O_WRONLY|O_CREAT|O_TRUNC, 0666);
		if (i >= 0) {
			dup2(i, STDERR_FILENO);
		}

		/* Close all open files except standard i/o */

		closefrom(3);

		/* execute target executable */

		execl("/sbin/sh", "/sbin/sh", "-c", cmd, NULL);
		progerr(pkg_gt("exec of <%s> failed, errno=%d"), cmd, errno);
		_exit(99);
	} else if (pid < 0) {
		/* fork failed! */

		logerr(pkg_gt("bad vfork(), errno=%d"), errno);
		return (-1);
	}

	/*
	 * this is the parent process
	 */

	sighold(SIGINT);
	pid = waitpid(pid, &status, 0);
	sigrelse(SIGINT);

	if (pid < 0) {
		return (-1); /* probably interrupted */
	}

	switch (status & 0177) {
		case 0:
		case 0177:
			status = status >> 8;
			/*FALLTHROUGH*/

		default:
			/* terminated by a signal */
			status = status & 0177;
	}

	if (status == 0) {
		ecleanup();
	}

	return (status);
}
コード例 #20
0
ファイル: xfs_copy.c プロジェクト: Fleurer/xfsprogs
int
main(int argc, char **argv)
{
	int		i, j;
	int		howfar = 0;
	int		open_flags;
	xfs_off_t	pos, end_pos;
	size_t		length;
	int		c, first_residue, tmp_residue;
	__uint64_t	size, sizeb;
	__uint64_t	numblocks = 0;
	int		wblocks = 0;
	int		num_threads = 0;
	struct dioattr	d;
	int		wbuf_size;
	int		wbuf_align;
	int		wbuf_miniosize;
	int		source_is_file = 0;
	int		buffered_output = 0;
	int		duplicate = 0;
	uint		btree_levels, current_level;
	ag_header_t	ag_hdr;
	xfs_mount_t	*mp;
	xfs_mount_t	mbuf;
	xfs_buf_t	*sbp;
	xfs_sb_t	*sb;
	xfs_agnumber_t	num_ags, agno;
	xfs_agblock_t	bno;
	xfs_daddr_t	begin, next_begin, ag_begin, new_begin, ag_end;
	struct xfs_btree_block *block;
	xfs_alloc_ptr_t	*ptr;
	xfs_alloc_rec_t	*rec_ptr;
	extern char	*optarg;
	extern int	optind;
	libxfs_init_t	xargs;
	thread_args	*tcarg;
	struct stat64	statbuf;

	progname = basename(argv[0]);

	setlocale(LC_ALL, "");
	bindtextdomain(PACKAGE, LOCALEDIR);
	textdomain(PACKAGE);

	while ((c = getopt(argc, argv, "bdL:V")) != EOF)  {
		switch (c) {
		case 'b':
			buffered_output = 1;
			break;
		case 'd':
			duplicate = 1;
			break;
		case 'L':
			logfile_name = optarg;
			break;
		case 'V':
			printf(_("%s version %s\n"), progname, VERSION);
			exit(0);
		case '?':
			usage();
		}
	}

	if (argc - optind < 2)
		usage();

	if (logfile_name)  {
		logfd = open(logfile_name, O_CREAT|O_WRONLY|O_EXCL, 0600);
	} else  {
		logfile_name = LOGFILE_NAME;
		logfd = mkstemp(logfile_name);
	}

	if (logfd < 0)  {
		fprintf(stderr, _("%s: couldn't open log file \"%s\"\n"),
			progname, logfile_name);
		perror(_("Aborting XFS copy - reason"));
		exit(1);
	}

	if ((logerr = fdopen(logfd, "w")) == NULL)  {
		fprintf(stderr, _("%s: couldn't set up logfile stream\n"),
			progname);
		perror(_("Aborting XFS copy - reason"));
		exit(1);
	}

	source_name = argv[optind];
	source_fd = -1;
	optind++;

	num_targets = argc - optind;
	if ((target = malloc(sizeof(target_control) * num_targets)) == NULL)  {
		do_log(_("Couldn't allocate target array\n"));
		die_perror();
	}
	for (i = 0; optind < argc; i++, optind++)  {
		target[i].name = argv[optind];
		target[i].fd = -1;
		target[i].position = -1;
		target[i].state = INACTIVE;
		target[i].error = 0;
		target[i].err_type = 0;
	}

	parent_pid = getpid();

	if (atexit(killall))  {
		do_log(_("%s: couldn't register atexit function.\n"), progname);
		die_perror();
	}

	/* open up source -- is it a file? */

	open_flags = O_RDONLY;

	if ((source_fd = open(source_name, open_flags)) < 0)  {
		do_log(_("%s:  couldn't open source \"%s\"\n"),
			progname, source_name);
		die_perror();
	}

	if (fstat64(source_fd, &statbuf) < 0)  {
		do_log(_("%s:  couldn't stat source \"%s\"\n"),
			progname, source_name);
		die_perror();
	}

	if (S_ISREG(statbuf.st_mode))
		source_is_file = 1;

	if (source_is_file && platform_test_xfs_fd(source_fd))  {
		if (fcntl(source_fd, F_SETFL, open_flags | O_DIRECT) < 0)  {
			do_log(_("%s: Cannot set direct I/O flag on \"%s\".\n"),
				progname, source_name);
			die_perror();
		}
		if (xfsctl(source_name, source_fd, XFS_IOC_DIOINFO, &d) < 0)  {
			do_log(_("%s: xfsctl on file \"%s\" failed.\n"),
				progname, source_name);
			die_perror();
		}

		wbuf_align = d.d_mem;
		wbuf_size = MIN(d.d_maxiosz, 1 * 1024 * 1024);
		wbuf_miniosize = d.d_miniosz;
	} else  {
		/* set arbitrary I/O params, miniosize at least 1 disk block */

		wbuf_align = getpagesize();
		wbuf_size = 1 * 1024 * 1024;
		wbuf_miniosize = -1;	/* set after mounting source fs */
	}

	if (!source_is_file)  {
		/*
		 * check to make sure a filesystem isn't mounted
		 * on the device
		 */
		if (platform_check_ismounted(source_name, NULL, &statbuf, 0))  {
			do_log(
	_("%s:  Warning -- a filesystem is mounted on the source device.\n"),
				progname);
			do_log(
	_("\t\tGenerated copies may be corrupt unless the source is\n"));
			do_log(
	_("\t\tunmounted or mounted read-only.  Copy proceeding...\n"));
		}
	}

	/* prepare the libxfs_init structure */

	memset(&xargs, 0, sizeof(xargs));
	xargs.isdirect = LIBXFS_DIRECT;
	xargs.isreadonly = LIBXFS_ISREADONLY;

	if (source_is_file)  {
		xargs.dname = source_name;
		xargs.disfile = 1;
	} else
		xargs.volname = source_name;

	if (!libxfs_init(&xargs))  {
		do_log(_("%s: couldn't initialize XFS library\n"
			"%s: Aborting.\n"), progname, progname);
		exit(1);
	}

	/* prepare the mount structure */

	memset(&mbuf, 0, sizeof(xfs_mount_t));
	libxfs_buftarg_init(&mbuf, xargs.ddev, xargs.logdev, xargs.rtdev);
	sbp = libxfs_readbuf(mbuf.m_ddev_targp, XFS_SB_DADDR, 1, 0,
							&xfs_sb_buf_ops);
	sb = &mbuf.m_sb;
	libxfs_sb_from_disk(sb, XFS_BUF_TO_SBP(sbp));

	mp = libxfs_mount(&mbuf, sb, xargs.ddev, xargs.logdev, xargs.rtdev, 0);
	if (mp == NULL) {
		do_log(_("%s: %s filesystem failed to initialize\n"
			"%s: Aborting.\n"), progname, source_name, progname);
		exit(1);
	} else if (mp->m_sb.sb_inprogress)  {
		do_log(_("%s %s filesystem failed to initialize\n"
			"%s: Aborting.\n"), progname, source_name, progname);
		exit(1);
	} else if (mp->m_sb.sb_logstart == 0)  {
		do_log(_("%s: %s has an external log.\n%s: Aborting.\n"),
			progname, source_name, progname);
		exit(1);
	} else if (mp->m_sb.sb_rextents != 0)  {
		do_log(_("%s: %s has a real-time section.\n"
			"%s: Aborting.\n"), progname, source_name, progname);
		exit(1);
	}

	source_blocksize = mp->m_sb.sb_blocksize;
	source_sectorsize = mp->m_sb.sb_sectsize;

	if (wbuf_miniosize == -1)
		wbuf_miniosize = source_sectorsize;

	ASSERT(source_blocksize % source_sectorsize == 0);
	ASSERT(source_sectorsize % BBSIZE == 0);

	if (source_blocksize > source_sectorsize)  {
		/* get number of leftover sectors in last block of ag header */

		tmp_residue = ((XFS_AGFL_DADDR(mp) + 1) * source_sectorsize)
					% source_blocksize;
		first_residue = (tmp_residue == 0) ? 0 :
			source_blocksize - tmp_residue;
		ASSERT(first_residue % source_sectorsize == 0);
	} else if (source_blocksize == source_sectorsize)  {
		first_residue = 0;
	} else  {
		do_log(_("Error:  filesystem block size is smaller than the"
			" disk sectorsize.\nAborting XFS copy now.\n"));
		exit(1);
	}

	first_agbno = (((XFS_AGFL_DADDR(mp) + 1) * source_sectorsize)
				+ first_residue) / source_blocksize;
	ASSERT(first_agbno != 0);
	ASSERT( ((((XFS_AGFL_DADDR(mp) + 1) * source_sectorsize)
				+ first_residue) % source_blocksize) == 0);

	/* now open targets */

	open_flags = O_RDWR;

	for (i = 0; i < num_targets; i++)  {
		int	write_last_block = 0;

		if (stat64(target[i].name, &statbuf) < 0)  {
			/* ok, assume it's a file and create it */

			do_out(_("Creating file %s\n"), target[i].name);

			open_flags |= O_CREAT;
			if (!buffered_output)
				open_flags |= O_DIRECT;
			write_last_block = 1;
		} else if (S_ISREG(statbuf.st_mode))  {
			open_flags |= O_TRUNC;
			if (!buffered_output)
				open_flags |= O_DIRECT;
			write_last_block = 1;
		} else  {
			/*
			 * check to make sure a filesystem isn't mounted
			 * on the device
			 */
			if (platform_check_ismounted(target[i].name,
							NULL, &statbuf, 0))  {
				do_log(_("%s:  a filesystem is mounted "
					"on target device \"%s\".\n"
					"%s cannot copy to mounted filesystems."
					"  Aborting\n"),
					progname, target[i].name, progname);
				exit(1);
			}
		}

		target[i].fd = open(target[i].name, open_flags, 0644);
		if (target[i].fd < 0)  {
			do_log(_("%s:  couldn't open target \"%s\"\n"),
				progname, target[i].name);
			die_perror();
		}

		if (write_last_block)  {
			/* ensure regular files are correctly sized */

			if (ftruncate64(target[i].fd, mp->m_sb.sb_dblocks *
						source_blocksize))  {
				do_log(_("%s:  cannot grow data section.\n"),
					progname);
				die_perror();
			}
			if (platform_test_xfs_fd(target[i].fd))  {
				if (xfsctl(target[i].name, target[i].fd,
						XFS_IOC_DIOINFO, &d) < 0)  {
					do_log(
				_("%s:  xfsctl on \"%s\" failed.\n"),
						progname, target[i].name);
					die_perror();
				} else {
					wbuf_align = MAX(wbuf_align, d.d_mem);
					wbuf_size = MIN(d.d_maxiosz, wbuf_size);
					wbuf_miniosize = MAX(d.d_miniosz,
								wbuf_miniosize);
				}
			}
		} else  {
			char	*lb[XFS_MAX_SECTORSIZE] = { NULL };
			off64_t	off;

			/* ensure device files are sufficiently large */

			off = mp->m_sb.sb_dblocks * source_blocksize;
			off -= sizeof(lb);
			if (pwrite64(target[i].fd, lb, sizeof(lb), off) < 0)  {
				do_log(_("%s:  failed to write last block\n"),
					progname);
				do_log(_("\tIs target \"%s\" too small?\n"),
					target[i].name);
				die_perror();
			}
		}
	}

	/* initialize locks and bufs */

	if (pthread_mutex_init(&glob_masks.mutex, NULL) != 0)  {
		do_log(_("Couldn't initialize global thread mask\n"));
		die_perror();
	}
	glob_masks.num_working = 0;

	if (wbuf_init(&w_buf, wbuf_size, wbuf_align,
					wbuf_miniosize, 0) == NULL)  {
		do_log(_("Error initializing wbuf 0\n"));
		die_perror();
	}

	wblocks = wbuf_size / BBSIZE;

	if (wbuf_init(&btree_buf, MAX(source_blocksize, wbuf_miniosize),
				wbuf_align, wbuf_miniosize, 1) == NULL)  {
		do_log(_("Error initializing btree buf 1\n"));
		die_perror();
	}

	if (pthread_mutex_init(&mainwait,NULL) != 0)  {
		do_log(_("Error creating first semaphore.\n"));
		die_perror();
		exit(1);
	}
	/* need to start out blocking */
	pthread_mutex_lock(&mainwait);

	/* set up sigchild signal handler */

	signal(SIGCHLD, handler);
	sighold(SIGCHLD);

	/* make children */

	if ((targ = malloc(num_targets * sizeof(thread_args))) == NULL)  {
		do_log(_("Couldn't malloc space for thread args\n"));
		die_perror();
		exit(1);
	}

	for (i = 0, tcarg = targ; i < num_targets; i++, tcarg++)  {
		if (!duplicate)
			platform_uuid_generate(&tcarg->uuid);
		else
			platform_uuid_copy(&tcarg->uuid, &mp->m_sb.sb_uuid);

		if (pthread_mutex_init(&tcarg->wait, NULL) != 0)  {
			do_log(_("Error creating thread mutex %d\n"), i);
			die_perror();
			exit(1);
		}
		/* need to start out blocking */
		pthread_mutex_lock(&tcarg->wait);
	}

	for (i = 0, tcarg = targ; i < num_targets; i++, tcarg++)  {
		tcarg->id = i;
		tcarg->fd = target[i].fd;

		target[i].state = ACTIVE;
		num_threads++;

		if (pthread_create(&target[i].pid, NULL,
					begin_reader, (void *)tcarg))  {
			do_log(_("Error creating thread for target %d\n"), i);
			die_perror();
		}
	}

	ASSERT(num_targets == num_threads);

	/* set up statistics */

	num_ags = mp->m_sb.sb_agcount;

	init_bar(mp->m_sb.sb_blocksize / BBSIZE
			* ((__uint64_t)mp->m_sb.sb_dblocks
			    - (__uint64_t)mp->m_sb.sb_fdblocks + 10 * num_ags));

	kids = num_targets;
	block = (struct xfs_btree_block *) btree_buf.data;

	for (agno = 0; agno < num_ags && kids > 0; agno++)  {
		/* read in first blocks of the ag */

		read_ag_header(source_fd, agno, &w_buf, &ag_hdr, mp,
			source_blocksize, source_sectorsize);

		/* set the in_progress bit for the first AG */

		if (agno == 0)
			ag_hdr.xfs_sb->sb_inprogress = 1;

		/* save what we need (agf) in the btree buffer */

		memmove(btree_buf.data, ag_hdr.xfs_agf, source_sectorsize);
		ag_hdr.xfs_agf = (xfs_agf_t *) btree_buf.data;
		btree_buf.length = source_blocksize;

		/* write the ag header out */

		write_wbuf();

		/* traverse btree until we get to the leftmost leaf node */

		bno = be32_to_cpu(ag_hdr.xfs_agf->agf_roots[XFS_BTNUM_BNOi]);
		current_level = 0;
		btree_levels = be32_to_cpu(ag_hdr.xfs_agf->
						agf_levels[XFS_BTNUM_BNOi]);

		ag_end = XFS_AGB_TO_DADDR(mp, agno,
				be32_to_cpu(ag_hdr.xfs_agf->agf_length) - 1)
				+ source_blocksize / BBSIZE;

		for (;;) {
			/* none of this touches the w_buf buffer */

			if (current_level >= btree_levels) {
				do_log(
			_("Error: current level %d >= btree levels %d\n"),
					current_level, btree_levels);
				exit(1);
			}

			current_level++;

			btree_buf.position = pos = (xfs_off_t)
				XFS_AGB_TO_DADDR(mp,agno,bno) << BBSHIFT;
			btree_buf.length = source_blocksize;

			read_wbuf(source_fd, &btree_buf, mp);
			block = (struct xfs_btree_block *)
				 ((char *)btree_buf.data +
				  pos - btree_buf.position);

			ASSERT(be32_to_cpu(block->bb_magic) == XFS_ABTB_MAGIC);

			if (be16_to_cpu(block->bb_level) == 0)
				break;

			ptr = XFS_ALLOC_PTR_ADDR(mp, block, 1,
							mp->m_alloc_mxr[1]);
			bno = be32_to_cpu(ptr[0]);
		}

		/* align first data copy but don't overwrite ag header */

		pos = w_buf.position >> BBSHIFT;
		length = w_buf.length >> BBSHIFT;
		next_begin = pos + length;
		ag_begin = next_begin;

		ASSERT(w_buf.position % source_sectorsize == 0);

		/* handle the rest of the ag */

		for (;;) {
			if (be16_to_cpu(block->bb_level) != 0)  {
				do_log(
			_("WARNING:  source filesystem inconsistent.\n"));
				do_log(
			_("  A leaf btree rec isn't a leaf.  Aborting now.\n"));
				exit(1);
			}

			rec_ptr = XFS_ALLOC_REC_ADDR(mp, block, 1);
			for (i = 0; i < be16_to_cpu(block->bb_numrecs);
							i++, rec_ptr++)  {
				/* calculate in daddr's */

				begin = next_begin;

				/*
				 * protect against pathological case of a
				 * hole right after the ag header in a
				 * mis-aligned case
				 */

				if (begin < ag_begin)
					begin = ag_begin;

				/*
				 * round size up to ensure we copy a
				 * range bigger than required
				 */

				sizeb = XFS_AGB_TO_DADDR(mp, agno, 
					be32_to_cpu(rec_ptr->ar_startblock)) - 
						begin;
				size = roundup(sizeb <<BBSHIFT, wbuf_miniosize);
				if (size > 0)  {
					/* copy extent */

					w_buf.position = (xfs_off_t)
						begin << BBSHIFT;

					while (size > 0)  {
						/*
						 * let lower layer do alignment
						 */
						if (size > w_buf.size)  {
							w_buf.length = w_buf.size;
							size -= w_buf.size;
							sizeb -= wblocks;
							numblocks += wblocks;
						} else  {
							w_buf.length = size;
							numblocks += sizeb;
							size = 0;
						}

						read_wbuf(source_fd, &w_buf, mp);
						write_wbuf();

						w_buf.position += w_buf.length;

						howfar = bump_bar(
							howfar, numblocks);
					}
				}

				/* round next starting point down */

				new_begin = XFS_AGB_TO_DADDR(mp, agno,
						be32_to_cpu(rec_ptr->ar_startblock) +
					 	be32_to_cpu(rec_ptr->ar_blockcount));
				next_begin = rounddown(new_begin,
						w_buf.min_io_size >> BBSHIFT);
			}

			if (be32_to_cpu(block->bb_u.s.bb_rightsib) == NULLAGBLOCK)
				break;

			/* read in next btree record block */

			btree_buf.position = pos = (xfs_off_t)
				XFS_AGB_TO_DADDR(mp, agno, be32_to_cpu(
						block->bb_u.s.bb_rightsib)) << BBSHIFT;
			btree_buf.length = source_blocksize;

			/* let read_wbuf handle alignment */

			read_wbuf(source_fd, &btree_buf, mp);

			block = (struct xfs_btree_block *)
				 ((char *) btree_buf.data +
				  pos - btree_buf.position);

			ASSERT(be32_to_cpu(block->bb_magic) == XFS_ABTB_MAGIC);
		}

		/*
		 * write out range of used blocks after last range
		 * of free blocks in AG
		 */
		if (next_begin < ag_end)  {
			begin = next_begin;

			sizeb = ag_end - begin;
			size = roundup(sizeb << BBSHIFT, wbuf_miniosize);

			if (size > 0)  {
				/* copy extent */

				w_buf.position = (xfs_off_t) begin << BBSHIFT;

				while (size > 0)  {
					/*
					 * let lower layer do alignment
					 */
					if (size > w_buf.size)  {
						w_buf.length = w_buf.size;
						size -= w_buf.size;
						sizeb -= wblocks;
						numblocks += wblocks;
					} else  {
						w_buf.length = size;
						numblocks += sizeb;
						size = 0;
					}

					read_wbuf(source_fd, &w_buf, mp);
					write_wbuf();

					w_buf.position += w_buf.length;

					howfar = bump_bar(howfar, numblocks);
				}
			}
		}
	}

	if (kids > 0)  {
		if (!duplicate)  {

			/* write a clean log using the specified UUID */
			for (j = 0, tcarg = targ; j < num_targets; j++)  {
				w_buf.owner = tcarg;
				w_buf.length = rounddown(w_buf.size,
							 w_buf.min_io_size);
				pos = write_log_header(
							source_fd, &w_buf, mp);
				end_pos = write_log_trailer(
							source_fd, &w_buf, mp);
				w_buf.position = pos;
				memset(w_buf.data, 0, w_buf.length);

				while (w_buf.position < end_pos)  {
					do_write(tcarg);
					w_buf.position += w_buf.length;
				}
				tcarg++;
			}
		} else {
			num_ags = 1;
		}

		/* reread and rewrite superblocks (UUID and in-progress) */
		/* [backwards, so inprogress bit only updated when done] */

		for (i = num_ags - 1; i >= 0; i--)  {
			read_ag_header(source_fd, i, &w_buf, &ag_hdr, mp,
				source_blocksize, source_sectorsize);
			if (i == 0)
				ag_hdr.xfs_sb->sb_inprogress = 0;

			/* do each thread in turn, each has its own UUID */

			for (j = 0, tcarg = targ; j < num_targets; j++)  {
				platform_uuid_copy(&ag_hdr.xfs_sb->sb_uuid,
							&tcarg->uuid);
				do_write(tcarg);
				tcarg++;
			}
		}

		bump_bar(100, 0);
	}

	check_errors();
	killall();
	pthread_exit(NULL);
	/*NOTREACHED*/
	return 0;
}
コード例 #21
0
ファイル: 3-core-buildonly.c プロジェクト: mmanley/Antares
int main(int argc, char *argv[])
{
	int signo, TEST_RETURN;
	struct sigaction sa, osa;

	if (argc < 2) {
        	printf("Usage:  %s [1|2|3|4]\n", argv[0]);
		return PTS_UNRESOLVED;
	}

	/*
		Various error conditions
	*/
	switch (argv[1][0]) {
		case '1':
			signo=-1;
			break;
		case '2':
			signo=-10000;
			break;
		case '3':
			signo=INT32_MIN+1;
			break;
		case '4':
			signo=INT32_MIN;
			break;
		default:
			printf("Usage:  %s [1|2|3|4]\n", argv[0]);
			return PTS_UNRESOLVED;
	}

        /* special sig11 case */
        sa.sa_handler = &sig11_handler;
        sigemptyset(&sa.sa_mask);
        sa.sa_flags = 0;

        sigaction(SIGSEGV, NULL, &osa);
        sigaction(SIGSEGV, &sa, NULL);

        if (setjmp(sig11_recover)) {
              errno = EINVAL;
	      TEST_RETURN=-2;
        } else {
              TEST_RETURN=sighold(signo);
        }
        sigaction(SIGSEGV, &osa, NULL);

	if (TEST_RETURN == -1) {
		if (EINVAL == errno) {
			printf("%ssighold_3-core-buildonly%s:%s %s PASSED%s\n", boldOn, argv[1], boldOff, green, normal);
			return PTS_PASS;
		} else {
			printf ("errno not set to EINVAL\n");
			return PTS_FAIL;
		}
	}
	if (TEST_RETURN == -2) {
		printf ("test received SIGSEGV\n");
		return PTS_UNRESOLVED;
	}
	
	printf("sighold did not return -1\n");
	return PTS_FAIL;
}
コード例 #22
0
TEST(signal, sighold_EINVAL) {
  errno = 0;
  ASSERT_EQ(-1, sighold(99999));
  ASSERT_EQ(EINVAL, errno);
}
コード例 #23
0
ファイル: dlog.c プロジェクト: crossmeta/sgi
static bool_t
promptinput( char *buf,
	     size_t bufsz,
	     ix_t *exceptionixp,
	     time_t timeout,
	     ix_t timeoutix,
	     ix_t sigintix,
	     ix_t sighupix,
	     ix_t sigquitix,
	     char *fmt,
	     ... )
{
	va_list args;
	u_intgen_t alarm_save = 0;
	void (* sigalrm_save)(int) = NULL;
	void (* sigint_save)(int) = NULL;
	void (* sighup_save)(int) = NULL;
	void (* sigterm_save)(int) = NULL;
	void (* sigquit_save)(int) = NULL;
	intgen_t nread;
	pid_t pid = getpid( );

	/* display the pre-prompt
	 */
	va_start( args, fmt );
	mlog_va( MLOG_NORMAL | MLOG_NOLOCK | MLOG_BARE, fmt, args );
	va_end( args );

	/* display standard prompt
	 */
#ifdef NOTYET
	if ( dlog_timeouts_flag && timeoutix != IXMAX ) {
		mlog( MLOG_NORMAL | MLOG_NOLOCK | MLOG_BARE,
		      "(timeout in %d sec)",
		      timeout );
	}
#endif /* NOTYET */
	mlog( MLOG_NORMAL | MLOG_NOLOCK | MLOG_BARE, promptstr );

	/* set up signal handling
	 */
	dlog_signo_received = -1;
	if ( dlog_timeouts_flag && timeoutix != IXMAX ) {
		if ( pid == parentpid && ! miniroot ) {
			( void )sigrelse( SIGALRM );
		}
		sigalrm_save = sigset( SIGALRM, sighandler );
		alarm_save = alarm( ( u_intgen_t )timeout );
	}
	if ( sigintix != IXMAX ) {
		if ( pid == parentpid && ! miniroot ) {
			( void )sigrelse( SIGINT );
		}
		sigint_save = sigset( SIGINT, sighandler );
	}
	if ( sighupix != IXMAX ) {
		if ( pid == parentpid && ! miniroot ) {
			( void )sigrelse( SIGHUP );
		}
		sighup_save = sigset( SIGHUP, sighandler );
		if ( pid == parentpid && ! miniroot ) {
			( void )sigrelse( SIGTERM );
		}
		sigterm_save = sigset( SIGTERM, sighandler );
	}
	if ( sigquitix != IXMAX ) {
		if ( pid == parentpid && ! miniroot ) {
			( void )sigrelse( SIGQUIT );
		}
		sigquit_save = sigset( SIGQUIT, sighandler );
	}

	/* wait for input, timeout, or interrupt
	 */
	ASSERT( dlog_ttyfd >= 0 );
	nread = read( dlog_ttyfd, buf, bufsz - 1 );

	/* restore signal handling
	 */
	if ( sigquitix != IXMAX ) {
		( void )sigset( SIGQUIT, sigquit_save );
		if ( pid == parentpid && ! miniroot ) {
			( void )sighold( SIGQUIT );
		}
	}
	if ( sighupix != IXMAX ) {
		( void )sigset( SIGHUP, sighup_save );
		if ( pid == parentpid && ! miniroot ) {
			( void )sighold( SIGHUP );
		}
		( void )sigset( SIGTERM, sigterm_save );
		if ( pid == parentpid && ! miniroot ) {
			( void )sighold( SIGTERM );
		}
	}
	if ( sigintix != IXMAX ) {
		( void )sigset( SIGINT, sigint_save );
		if ( pid == parentpid && ! miniroot ) {
			( void )sighold( SIGINT );
		}
	}
	if ( dlog_timeouts_flag && timeoutix != IXMAX ) {
		( void )alarm( alarm_save );
		( void )sigset( SIGALRM, sigalrm_save );
		if ( pid == parentpid && ! miniroot ) {
			( void )sighold( SIGALRM );
		}
	}
	
	/* check for timeout or interrupt
	 */
	if ( nread < 0 ) {
		if ( dlog_signo_received == SIGALRM ) {
			mlog( MLOG_NORMAL | MLOG_NOLOCK | MLOG_BARE,
			      "timeout\n" );
			*exceptionixp = timeoutix;
		} else if ( dlog_signo_received == SIGINT ) {
			mlog( MLOG_NORMAL | MLOG_NOLOCK | MLOG_BARE,
			      "keyboard interrupt\n" );
			*exceptionixp = sigintix;
		} else if ( dlog_signo_received == SIGHUP ) {
			mlog( MLOG_NORMAL | MLOG_NOLOCK | MLOG_BARE,
			      "hangup\n" );
			*exceptionixp = sighupix;
		} else if ( dlog_signo_received == SIGTERM ) {
			mlog( MLOG_NORMAL | MLOG_NOLOCK | MLOG_BARE,
			      "terminate\n" );
			*exceptionixp = sighupix;
		} else if ( dlog_signo_received == SIGQUIT ) {
			mlog( MLOG_NORMAL | MLOG_NOLOCK | MLOG_BARE,
			      "keyboard quit\n" );
			*exceptionixp = sigquitix;
		} else {
			mlog( MLOG_NORMAL | MLOG_NOLOCK | MLOG_BARE,
			      "unknown signal during dialog: %d\n",
			      dlog_signo_received );
			*exceptionixp = sigquitix;
		}
		return BOOL_FALSE;
	} else if ( nread == 0 ) {
		*exceptionixp = timeoutix;
		if ( bufsz > 0 ) {
			buf[ 0 ] = 0;
		}
		return BOOL_FALSE;
	} else {
		ASSERT( dlog_signo_received == -1 );
		ASSERT( ( size_t )nread < bufsz );
		ASSERT( buf[ nread - 1 ] == '\n' );
		buf[ nread - 1 ] = 0;
		*exceptionixp = 0;
		return BOOL_TRUE;
	}
}
コード例 #24
0
ファイル: lock.c プロジェクト: belenix/belenixold
int
admin_lock(int argc, char **argv)
{
	FINDLOCK_T		tResult;
	LOCK_T			theLock;
	char			*RFlag = "/";	/* altRoot */
	char			*endptr;
	char			*kFlag = "";	/* key */
	char			*oFlag = "";	/* object */
	char			*p;
	char			c;
	int			aFlag = 0;	/* acquire lock */
	int			eFlag = 0;	/* exclusive lock */
	int			exclusive = 1;	/* exclusive vs shared lock */
	int			fd;
	int			qFlag = 0;	/* quiet */
	int			rFlag = 0;	/* release lock */
	int			result;
	int			sFlag = 0;	/* shared lock */
	int			tFlag = 0;	/* test comparison */
	int			wFlag = 0;	/* wait */
	long			WFlag = 0;	/* wait timeout */
	pid_t			pFlag = 0;	/* process # */
	struct sigaction	nact;
	struct sigaction	oact;
	void			(*funcSighup)();
	void			(*funcSigint)();
	zoneid_t		zFlag = -1;	/* zone i.d. */

	while ((c = getopt(argc, argv, ":aek:o:p:qrR:stwW:z:")) != EOF) {
		switch (c) {
		case 'a':	/* acquire lock */
			aFlag++;
			break;

		case 'e':	/* exclusive lock */
			eFlag++;
			break;

		case 'k':	/* lock-key */
			kFlag = optarg;
			if (strlen(optarg) > LOCK_KEY_MAXLEN) {
				log_msg(LOG_MSG_ERR,
					MSG_LOCK_kARG_TOOLONG,
					strlen(optarg), LOCK_KEY_MAXLEN);
				return (1);
			}
			break;

		case 'o':	/* object */
			oFlag = optarg;
			if (strlen(optarg) > LOCK_OBJECT_MAXLEN) {
				log_msg(LOG_MSG_ERR,
					MSG_LOCK_oARG_TOOLONG,
					strlen(optarg), LOCK_OBJECT_MAXLEN);
				return (1);
			}
			break;

		case 'p':	/* process i.d. */
			errno = 0;
			endptr = 0;
			pFlag = strtol(optarg, &endptr, 10);
			if ((endptr != (char *)NULL) && (*endptr != '\0')) {
				log_msg(LOG_MSG_ERR, MSG_LOCK_pFLAG_BADINT,
							optarg, *endptr);
				return (1);
			}
			if ((pFlag == 0) && (errno != 0)) {
				log_msg(LOG_MSG_ERR,
					MSG_LOCK_pFLAG_ERROR,
					optarg,  strerror(errno));
				return (1);
			}
			break;

		case 'q':	/* quiet */
			qFlag++;
			break;

		case 'r':	/* release lock */
			rFlag++;
			break;

		case 'R':	/* alternative root */
			/* if root directory is not absolute path, error */
			if (*optarg != '/') {
				log_msg(LOG_MSG_ERR,
					MSG_LOCK_RARG_NOT_ABSOLUTE, optarg);
				return (1);
			}

			/* if root directory does not exist, create it */
			if (access(optarg, F_OK) != 0) {

				/* create top level root directory */
				if (mkdirp(optarg, 0755) != 0) {
					log_msg(LOG_MSG_ERR,
						MSG_LOCK_ALTROOT_CANTCREATE,
						optarg, strerror(errno));
					return (1);
				}
			}

			/* if $ALTROOT/tmp directory does not exist create it */
			p = pkgstrPrintf("%s/tmp", optarg);
			if (access(p, F_OK) != 0) {

				/* create $ALTROOT/tmp directory */
				if (mkdirp(p, 0777) != 0) {
					log_msg(LOG_MSG_ERR,
						MSG_LOCK_ALTROOT_CANTCREATE,
						p, strerror(errno));
					return (1);
				}
			}

			/* if $ALTROOT/tmp directory cannot be created, exit */
			if (access(p, F_OK) != 0) {
				log_msg(LOG_MSG_ERR, MSG_LOCK_ALTROOT_NONEXIST,
					optarg, strerror(errno));
				return (1);
			}

			(void) free(p);

			RFlag = optarg;
			break;

		case 's':	/* shared */
			sFlag++;
			break;

		case 't':	/* test comparison */
			tFlag++;
			break;

		case 'w':	/* wait */
			wFlag++;
			break;

		case 'W':	/* wait with timeout */
			errno = 0;
			endptr = 0;
			WFlag = strtol(optarg, &endptr, 10);
			if ((endptr != (char *)NULL) && (*endptr != '\0')) {
				log_msg(LOG_MSG_ERR, MSG_LOCK_WFLAG_BADINT,
							optarg, *endptr);
				return (1);
			}
			if ((WFlag == 0) && (errno != 0)) {
				log_msg(LOG_MSG_ERR,
					MSG_LOCK_WFLAG_ERROR,
					optarg,  strerror(errno));
				return (1);
			}
			wFlag++;
			break;

		case 'z':	/* zone i.d. */
			errno = 0;
			endptr = 0;
			zFlag = strtol(optarg, &endptr, 10);
			if ((endptr != (char *)NULL) && (*endptr != '\0')) {
				log_msg(LOG_MSG_ERR, MSG_LOCK_zFLAG_BADINT,
							optarg, *endptr);
				return (1);
			}
			if ((zFlag == 0) && (errno != 0)) {
				log_msg(LOG_MSG_ERR,
					MSG_LOCK_zFLAG_ERROR,
					optarg,  strerror(errno));
				return (1);
			}
			break;

		case ':':
			log_msg(LOG_MSG_ERR, MSG_MISSING_OPERAND, optopt);
			/* LINTED fallthrough on case statement */
		case '?':

		default:
			log_msg(LOG_MSG_ERR, MSG_USAGE);
			return (1);
		}
	}

	/*
	 * validate arguments
	 */

	/* if -t option is specified, override all other options */

	if (tFlag) {
		int	rs;
		int	rx;
		int	a;

		/* only 2 or 3 args are valid */

		a = argc-optind;
		if ((a < 2) || (a > 3)) {
			(void) fprintf(stderr, MSG_T_OPTION_ARGS, argc-optind);
			return (1);
		}

		/* if 3rd argument given, it is return value to check */

		if (a == 3) {
			rs = atoi(argv[optind+2]);
		}
		rx = _lockMatch(argv[optind+0], argv[optind+1]);

		/* if 3rd argument not given, code to check is code returned */

		if (a == 2) {
			rs = rx;
		}

		/* report results */

		if (a == 2) {
			(void) fprintf(stderr, MSG_T_RESULT_TWO,
				rx, argv[optind+0], argv[optind+1]);
			return (rx);
		}

		if (rx != rs) {
			(void) fprintf(stderr, MSG_T_RESULT_THREE,
				rs, rx, argv[optind+0], argv[optind+1]);
		}

		/* always successful */

		return (rx == rs ? 0 : 1);
	}

	/* must be no non-option arguments left */

	if ((argc-optind) > 0) {
		log_msg(LOG_MSG_ERR, MSG_USAGE);
		return (1);
	}

	/* -a and -r cannot be used together */

	if (aFlag && rFlag) {
		log_msg(LOG_MSG_ERR, MSG_LOCK_ar_TOGETHER);
		return (1);
	}

	/* -e and -s cannot be used together */

	if (eFlag && sFlag) {
		log_msg(LOG_MSG_ERR, MSG_LOCK_es_TOGETHER);
		return (1);
	}

	/* -e can only be used if -a is used */

	if (!aFlag && eFlag) {
		log_msg(LOG_MSG_ERR, MSG_LOCK_e_without_a);
		return (1);
	}

	/* -s can only be used if -a is used */

	if (!aFlag && sFlag) {
		log_msg(LOG_MSG_ERR, MSG_LOCK_s_without_a);
		return (1);
	}

	/*
	 * perform the requested operation
	 */

	/*
	 * hook SIGINT and SIGHUP interrupts into quit.c's trap handler
	 */

	/* hold SIGINT/SIGHUP interrupts */

	(void) sighold(SIGHUP);
	(void) sighold(SIGINT);

	/* connect sigint_handler() to SIGINT */

	nact.sa_handler = sigint_handler;
	nact.sa_flags = SA_RESTART;
	(void) sigemptyset(&nact.sa_mask);

	if (sigaction(SIGINT, &nact, &oact) < 0) {
		funcSigint = SIG_DFL;
	} else {
		funcSigint = oact.sa_handler;
	}

	/* connect sighupt_handler() to SIGHUP */

	nact.sa_handler = sighup_handler;
	nact.sa_flags = SA_RESTART;
	(void) sigemptyset(&nact.sa_mask);

	if (sigaction(SIGHUP, &nact, &oact) < 0) {
		funcSighup = SIG_DFL;
	} else {
		funcSighup = oact.sa_handler;
	}

	/* release hold on signals */

	(void) sigrelse(SIGHUP);
	(void) sigrelse(SIGINT);

	/* open the lock file */

	fd = _openLockFile(RFlag);
	if (fd < 0) {
		return (1);
	}

	if (aFlag) {
		/* set "exclusive" mode based on -e/-s flag used */

		if (sFlag) {
			exclusive = 0;
		} else if (eFlag) {
			exclusive = 1;
		}

		/* acquire lock */

		tResult = lock_acquire(&theLock, &fd, RFlag, kFlag, oFlag,
			qFlag, wFlag, WFlag, exclusive, RFlag, pFlag, zFlag);

		switch (tResult) {
		case FINDLOCK_LOCKACQUIRED:
			(void) fprintf(stdout, "%s\n",
				theLock._lrLock.lockKey);
			result = 0;
			break;
		case FINDLOCK_LOCKED:
			(void) fprintf(stdout, "%s\n",
				theLock._lrLock.lockObject);
			result = 1;
			break;
		default:
			result = 1;
			break;
		}

	} else if (rFlag) {
		/* release lock */
		result = lock_release(fd, kFlag, oFlag, qFlag);
	} else {
		/* lock status */
		result = lock_status(fd, kFlag, oFlag, qFlag);
	}

	/* close the lock file */

	(void) close(fd);

	/* return results of operation */

	return (result);
}
コード例 #25
0
ファイル: pkgtrans.c プロジェクト: apprisi/illumos-gate
static int
pkgxfer(char *srcinst, int options)
{
	int	r;
	struct pkginfo info;
	FILE	*fp, *pp;
	char	*pt, *src, *dst;
	char	dstdir[PATH_MAX],
		temp[PATH_MAX],
		srcdir[PATH_MAX],
		cmd[CMDSIZE],
		pkgname[NON_ABI_NAMELNGTH];
	int	i, n, part, nparts, maxpartsize, curpartcnt, iscomp;
	char	volnos[128], tmpvol[128];
	struct	statvfs64 svfsb;
	longlong_t free_blocks;
	struct	stat	srcstat;

	info.pkginst = NULL; /* required initialization */

	/*
	 * when this routine is entered, the first part of
	 * the package to transfer is already available in
	 * the directory indicated by 'src' --- unless the
	 * source device is a datstream, in which case only
	 * the pkginfo and pkgmap files are available in 'src'
	 */
	src = srcdev.dirname;
	dst = dstdev.dirname;

	if (!(options & PT_SILENT))
		(void) fprintf(stderr, pkg_gt(MSG_TRANSFER), srcinst);
	(void) strlcpy(dstinst, srcinst, sizeof (dstinst));

	if (!(options & PT_ODTSTREAM)) {
		/* destination is a (possibly mounted) directory */
		(void) snprintf(dstdir, sizeof (dstdir),
		    "%s/%s", dst, dstinst);

		/*
		 * need to check destination directory to assure
		 * that we will not be duplicating a package which
		 * already resides there (though we are allowed to
		 * overwrite the same version)
		 */
		pkgdir = src;
		if (fpkginfo(&info, srcinst)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_NOEXISTS), srcinst);
			(void) fpkginfo(&info, NULL);
			return (1);
		}
		pkgdir = dst;

		(void) strlcpy(temp, srcinst, sizeof (temp));
		if (pt = strchr(temp, '.'))
			*pt = '\0';
		(void) strlcat(temp, ".*", sizeof (temp));

		if (pt = fpkginst(temp, info.arch, info.version)) {
			/*
			 * the same instance already exists, although
			 * its pkgid might be different
			 */
			if (options & PT_OVERWRITE) {
				(void) strlcpy(dstinst, pt, sizeof (dstinst));
				(void) snprintf(dstdir, sizeof (dstdir),
				    "%s/%s", dst, dstinst);
			} else {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_DUPVERS), srcinst);
				(void) fpkginfo(&info, NULL);
				(void) fpkginst(NULL);
				return (2);
			}
		} else if (options & PT_RENAME) {
			/*
			 * find next available instance by appending numbers
			 * to the package abbreviation until the instance
			 * does not exist in the destination directory
			 */
			if (pt = strchr(temp, '.'))
				*pt = '\0';
			for (i = 2; (access(dstdir, 0) == 0); i++) {
				(void) snprintf(dstinst, sizeof (dstinst),
				    "%s.%d", temp, i);
				(void) snprintf(dstdir, sizeof (dstdir),
				    "%s/%s", dst, dstinst);
			}
		} else if (options & PT_OVERWRITE) {
			/*
			 * we're allowed to overwrite, but there seems
			 * to be no valid package to overwrite, and we are
			 * not allowed to rename the destination, so act
			 * as if we weren't given permission to overwrite
			 * --- this keeps us from removing a destination
			 * instance which is named the same as the source
			 * instance, but really reflects a different pkg!
			 */
			options &= (~PT_OVERWRITE);
		}
		(void) fpkginfo(&info, NULL);
		(void) fpkginst(NULL);

		if (ckoverwrite(dst, dstinst, options))
			return (2);

		if (isdir(dstdir) && mkdir(dstdir, 0755)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_MKDIR), dstdir);
			return (1);
		}

		(void) snprintf(srcdir, sizeof (srcdir),
		    "%s/%s", src, srcinst);
		if (stat(srcdir, &srcstat) != -1) {
			if (chmod(dstdir, (srcstat.st_mode & S_IAMB)) == -1) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_CHMODDIR), dstdir);
				return (1);
			}
		} else {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_STATDIR), srcdir);
			return (1);
		}
	}

	if (!(options & PT_SILENT) && strcmp(dstinst, srcinst))
		(void) fprintf(stderr, pkg_gt(MSG_RENAME), dstinst);

	(void) snprintf(srcdir, sizeof (srcdir), "%s/%s", src, srcinst);
	if (chdir(srcdir)) {
		progerr(pkg_gt(ERR_TRANSFER));
		logerr(pkg_gt(MSG_CHDIR), srcdir);
		return (1);
	}

	if (ids_name) {	/* unpack the datatstream into a directory */
		/*
		 * transfer pkginfo & pkgmap first
		 */
		(void) snprintf(cmd, sizeof (cmd),
		    "%s -pudm %s", CPIOPROC, dstdir);
		if ((pp = epopen(cmd, "w")) == NULL) {
			rpterr();
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_POPEN), cmd, errno);
			return (1);
		}
		(void) fprintf(pp, "%s\n%s\n", PKGINFO, PKGMAP);

		(void) sighold(SIGINT);
		(void) sighold(SIGHUP);
		r = epclose(pp);
		(void) sigrelse(SIGINT);
		(void) sigrelse(SIGHUP);

		if (r != 0) {
			rpterr();
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_PCLOSE), cmd, errno);
			return (1);
		}

		if (options & PT_INFO_ONLY)
			return (0); /* don't transfer objects */

		if (chdir(dstdir)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_CHDIR), dstdir);
			return (1);
		}

		/*
		 * for each part of the package, use cpio() to
		 * unpack the archive into the destination directory
		 */
		nparts = ds_findpkg(srcdev.cdevice, srcinst);
		if (nparts < 0) {
			progerr(pkg_gt(ERR_TRANSFER));
			return (1);
		}
		for (part = 1; part <= nparts; /* void */) {
			if (ds_getpkg(srcdev.cdevice, part, dstdir)) {
				progerr(pkg_gt(ERR_TRANSFER));
				return (1);
			}
			part++;
			if (dstdev.mount) {
				(void) chdir("/");
				if (pkgumount(&dstdev))
					return (1);
				if (part <= nparts) {
					if (n = pkgmount(&dstdev, NULL, part+1,
					    nparts, 1))
						return (n);
					if (ckoverwrite(dst, dstinst, options))
						return (1);
					if (isdir(dstdir) &&
					    mkdir(dstdir, 0755)) {
						progerr(
						    pkg_gt(ERR_TRANSFER));
						logerr(pkg_gt(MSG_MKDIR),
						    dstdir);
						return (1);
					}
					/*
					 * since volume is removable, each part
					 * must contain a duplicate of the
					 * pkginfo file to properly identify the
					 * volume
					 */
					if (chdir(srcdir)) {
						progerr(
						    pkg_gt(ERR_TRANSFER));
						logerr(pkg_gt(MSG_CHDIR),
						    srcdir);
						return (1);
					}
					if ((pp = epopen(cmd, "w")) == NULL) {
						rpterr();
						progerr(
						    pkg_gt(ERR_TRANSFER));
						logerr(pkg_gt(MSG_POPEN),
						    cmd, errno);
						return (1);
					}
					(void) fprintf(pp, "pkginfo");

					(void) sighold(SIGINT);
					(void) sighold(SIGHUP);
					r = epclose(pp);
					(void) sigrelse(SIGINT);
					(void) sigrelse(SIGHUP);

					if (r != 0) {
						rpterr();
						progerr(
						    pkg_gt(ERR_TRANSFER));
						logerr(pkg_gt(MSG_PCLOSE),
						    cmd, errno);
						return (1);
					}
					if (chdir(dstdir)) {
						progerr(
						    pkg_gt(ERR_TRANSFER));
						logerr(pkg_gt(MSG_CHDIR),
						    dstdir);
						return (1);
					}
				}
			}
		}
		return (0);
	}

	if ((fp = fopen(PKGMAP, "r")) == NULL) {
		progerr(pkg_gt(ERR_TRANSFER));
		logerr(pkg_gt(MSG_NOPKGMAP), srcinst);
		return (1);
	}

	nparts = 1;
	if (!rd_map_size(fp, &nparts, &maxpartsize, &compressedsize))
		return (1);
	else
		(void) fclose(fp);

	if (srcdev.mount) {
		if (ckvolseq(srcdir, 1, nparts)) {
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_SEQUENCE));
			return (1);
		}
	}

	/* write each part of this package */
	if (options & PT_ODTSTREAM) {
		char line[128];
		(void) mgets(line, 128);
		curpartcnt = -1;
		/* LINTED E_SEC_SCANF_UNBOUNDED_COPY */
		if (sscanf(line, "%s %d %d %[ 0-9]", pkgname, &nparts,
		    &maxpartsize, volnos) == 4) {
			(void) sscanf(volnos,
			    "%d %[ 0-9]", &curpartcnt, tmpvol);
			(void) strlcpy(volnos, tmpvol, sizeof (volnos));
		}
	}

	for (part = 1; part <= nparts; /* void */) {
		if (curpartcnt == 0 && (options & PT_ODTSTREAM)) {
			char prompt[128];
			int index;
			ds_volno++;
			(void) ds_close(0);
			(void) sprintf(prompt,
			    pkg_gt("Insert %%v %d of %d into %%p"),
			    ds_volno, ds_volcnt);
			if (n = getvol(ods_name, NULL, DM_FORMAT, prompt))
				return (n);
			if ((ds_fd = open(dstdev.cdevice, O_WRONLY)) < 0) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_OPEN), dstdev.cdevice,
				    errno);
				return (1);
			}
			if (ds_ginit(dstdev.cdevice) < 0) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_OPEN), dstdev.cdevice,
				    errno);
				(void) ds_close(0);
				return (1);
			}

			(void) sscanf(volnos, "%d %[ 0-9]", &index, tmpvol);
			(void) strlcpy(volnos, tmpvol, sizeof (volnos));
			curpartcnt += index;
		}

		if (options & PT_INFO_ONLY)
			nparts = 0;

		if (part == 1) {
			(void) snprintf(cmd, sizeof (cmd),
			    "find %s %s", PKGINFO, PKGMAP);
			if (nparts && (isdir(INSTALL) == 0)) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, INSTALL, sizeof (cmd));
			}
		} else
			(void) snprintf(cmd, sizeof (cmd), "find %s", PKGINFO);

		if (nparts > 1) {
			(void) snprintf(temp, sizeof (temp),
			    "%s.%d", RELOC, part);
			if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, temp, sizeof (cmd));
			}
			(void) snprintf(temp, sizeof (temp),
			    "%s.%d", ROOT, part);
			if (iscpio(temp, &iscomp) || isdir(temp) == 0) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, temp, sizeof (cmd));
			}
			(void) snprintf(temp, sizeof (temp),
			    "%s.%d", ARCHIVE, part);
			if (isdir(temp) == 0) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, temp, sizeof (cmd));
			}
		} else if (nparts) {
			for (i = 0; reloc_names[i] != NULL; i++) {
				if (iscpio(reloc_names[i], &iscomp) ||
				    isdir(reloc_names[i]) == 0) {
					(void) strlcat(cmd, " ", sizeof (cmd));
					(void) strlcat(cmd, reloc_names[i],
					    sizeof (cmd));
				}
			}
			for (i = 0; root_names[i] != NULL; i++) {
				if (iscpio(root_names[i], &iscomp) ||
				    isdir(root_names[i]) == 0) {
					(void) strlcat(cmd, " ", sizeof (cmd));
					(void) strlcat(cmd, root_names[i],
					    sizeof (cmd));
				}
			}
			if (isdir(ARCHIVE) == 0) {
				(void) strlcat(cmd, " ", sizeof (cmd));
				(void) strlcat(cmd, ARCHIVE, sizeof (cmd));
			}
		}
		if (options & PT_ODTSTREAM) {
			(void) snprintf(cmd + strlen(cmd),
			    sizeof (cmd) - strlen(cmd),
			    " -print | %s -ocD -C %d",
			    CPIOPROC, (int)BLK_SIZE);
		} else {
			if (statvfs64(dstdir, &svfsb) == -1) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_STATVFS), dstdir, errno);
				return (1);
			}

			free_blocks = (((long)svfsb.f_frsize > 0) ?
			    howmany(svfsb.f_frsize, DEV_BSIZE) :
			    howmany(svfsb.f_bsize, DEV_BSIZE)) * svfsb.f_bavail;

			if ((has_comp_size ? compressedsize : maxpartsize) >
			    free_blocks) {
				progerr(pkg_gt(ERR_TRANSFER));
				logerr(pkg_gt(MSG_NOSPACE),
				    has_comp_size ?
				    (long)compressedsize : (long)maxpartsize,
				    free_blocks);
				return (1);
			}
			(void) snprintf(cmd + strlen(cmd),
			    sizeof (cmd) - strlen(cmd),
			    " -print | %s -pdum %s",
			    CPIOPROC, dstdir);
		}

		n = esystem(cmd, -1, (options & PT_ODTSTREAM) ? ds_fd : -1);
		if (n) {
			rpterr();
			progerr(pkg_gt(ERR_TRANSFER));
			logerr(pkg_gt(MSG_CMDFAIL), cmd, n);
			return (1);
		}

		part++;
		if (srcdev.mount && (nparts > 1)) {
			/* unmount current source volume */
			(void) chdir("/");
			if (pkgumount(&srcdev))
				return (1);
			/* loop until volume is mounted successfully */
			while (part <= nparts) {
				/* read only */
				n = pkgmount(&srcdev, NULL, part, nparts, 1);
				if (n)
					return (n);
				if (chdir(srcdir)) {
					progerr(pkg_gt(ERR_TRANSFER));
					logerr(pkg_gt(MSG_CORRUPT));
					(void) chdir("/");
					(void) pkgumount(&srcdev);
					continue;
				}
				if (ckvolseq(srcdir, part, nparts)) {
					(void) chdir("/");
					(void) pkgumount(&srcdev);
					continue;
				}
				break;
			}
		}
		if (!(options & PT_ODTSTREAM) && dstdev.mount) {
			/* unmount current volume */
			if (pkgumount(&dstdev))
				return (1);
			/* loop until next volume is mounted successfully */
			while (part <= nparts) {
				/* writable */
				n = pkgmount(&dstdev, NULL, part, nparts, 1);
				if (n)
					return (n);
				if (ckoverwrite(dst, dstinst, options))
					continue;
				if (isdir(dstdir) && mkdir(dstdir, 0755)) {
					progerr(pkg_gt(ERR_TRANSFER));
					logerr(pkg_gt(MSG_MKDIR), dstdir);
					continue;
				}
				break;
			}
		}

		if ((options & PT_ODTSTREAM) && part <= nparts) {
			if (curpartcnt >= 0 && part > curpartcnt) {
				char prompt[128];
				int index;
				ds_volno++;
				if (ds_close(0))
					return (1);
				(void) sprintf(prompt,
				    pkg_gt("Insert %%v %d of %d into %%p"),
				    ds_volno, ds_volcnt);
				if (n = getvol(ods_name, NULL, DM_FORMAT,
				    prompt))
					return (n);
				if ((ds_fd = open(dstdev.cdevice, 1)) < 0) {
					progerr(pkg_gt(ERR_TRANSFER));
					logerr(pkg_gt(MSG_OPEN),
					    dstdev.cdevice, errno);
					return (1);
				}
				if (ds_ginit(dstdev.cdevice) < 0) {
					progerr(pkg_gt(ERR_TRANSFER));
					logerr(pkg_gt(MSG_OPEN),
					    dstdev.cdevice, errno);
					(void) ds_close(0);
					return (1);
				}

				(void) sscanf(volnos, "%d %[ 0-9]", &index,
				    tmpvol);
				(void) strlcpy(volnos, tmpvol, sizeof (volnos));
				curpartcnt += index;
			}
		}

	}
	return (0);
}
コード例 #26
0
ファイル: main.c プロジェクト: axelri/hoskell
/*
 * Interpret the user input as either
 * a shell command or a program to be run
 */
void exec_command(char **tokens, int bg) {
    char *path, *first, **firstparsed, **checkenv, *pager;
    char *pathenv, *pathcp, **pathtokens;
    char *tmp_str;
    int i;
    pid_t parent;

    /* copy the first command string and handle
     * this case specially - it might be a shell command */
    first = malloc(sizeof(char)*strlen(tokens[0])+1);
    strcpy(first, tokens[0]);
    firstparsed = tokenize(first, ' ');

    if (strcmp(firstparsed[0], "") == 0) {
        free(first);
        free(firstparsed);
        free(tokens);
        return;
    }

    if (strcmp(firstparsed[0], "exit") == 0) {
        free(first);
        free(firstparsed);
        free(tokens);
        /* try to terminate all childs before exiting */

        /* send term to whole group, but ignore in parent */
        register_sighandler(SIGTERM, SIG_IGN);
        parent = getpid();
        sighold(SIGCHLD);

        /* give processes a chance to finish */
        if (kill(-parent, SIGTERM) == -1) {
            printf("Error: %s\n", strerror(errno));
            exit(1);
        }
        sleep(1);

        poll_childs();
        sigrelse(SIGCHLD);

        printf("Bye!\n");
        exit(0);
    }

    if (strcmp(firstparsed[0], "cd") == 0) {
        if (firstparsed[1] == '\0') {
            /* default dir to change to */
            path = getenv("HOME");
        } else {
            path = firstparsed[1];
        }

        if (DEBUG) {
            printf("Change Directory to %s\n", path);
        }

        if (chdir(path) == -1) {
            fprintf(stderr, "Error: %s\n", strerror(errno));
        }

        free(first);
        free(firstparsed);
        free(tokens);
        return;
    }

    if (strcmp(firstparsed[0], "checkEnv") == 0) {
        pager = getenv("PAGER");

        if (pager == NULL) {
            pathenv = getenv("PATH");
            pathcp = malloc(strlen(pathenv)+1);
            strcpy(pathcp, pathenv);
            pathtokens = tokenize(pathcp, ':');

            for (i = 0; i < tokens_length(pathtokens); i++) {
                if((tmp_str = malloc(strlen(pathtokens[i])+strlen("/less")+1)) != NULL){
                    tmp_str[0] = '\0';
                    strcat(tmp_str,pathtokens[i]);
                    strcat(tmp_str,"/less");

                    if (access(tmp_str, X_OK) != -1) {
                        pager = "less";
                        free(tmp_str);
                        break;
                    }
                    free(tmp_str);
                }
            }

            if (pager == NULL) pager = "more";
            free(pathcp);
            free(pathtokens);
        }

        if (DEBUG) {
            printf("Pager: %s\n", pager);
        }

        /* As our fork_and_run function takes an array of commands, we prepare an
          array with these commands in the checkenv array */

        /* tmp_str will become "grep <arguments>" if any arguments are passed to
          checkEnv */
        tmp_str = malloc(sizeof(char*) * (LIMIT + 1));

        if (tokens_length(firstparsed) > 1) {
            checkenv = malloc(sizeof(char*) * (4 + 1));

            tmp_str[0] = '\0';
            strcat(tmp_str, "grep ");
            for (i = 1; firstparsed[i] != NULL; i++) {
                strcat(tmp_str, firstparsed[i]);
                strcat(tmp_str, " ");
            }
            checkenv[0] = "printenv";
            checkenv[1] = tmp_str;
            checkenv[2] = "sort";
            checkenv[3] = pager;
            checkenv[4] = NULL;
        } else {
            checkenv = malloc(sizeof(char*) * (3 + 1));
            checkenv[0] = "printenv";
            checkenv[1] = "sort";
            checkenv[2] = pager;
            checkenv[3] = NULL;
        }

        fork_and_run(checkenv, bg);

        free(tmp_str);
        free(checkenv);
        free(first);
        free(firstparsed);
        free(tokens);
        return;
    }

    /* what was wrote wasn't "cd", "exit" or "checkEnv". We still execute
      the command. */
    free(first);
    free(firstparsed);
    fork_and_run(tokens, bg);
    free(tokens);
}
コード例 #27
0
ファイル: main.c プロジェクト: andreiw/polaris
int
main(int argc, char *argv[])
{
	int i, n;
	struct interface *ifp;
	int c;
	struct timeval waittime;
	int timeout;
	boolean_t daemon = _B_TRUE;	/* Fork off a detached daemon */
	FILE *pidfp;
	mode_t pidmode = (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* 0644 */

	rip6_port = htons(IPPORT_ROUTESERVER6);
	allrouters.sin6_family = AF_INET6;
	allrouters.sin6_port = rip6_port;
	allrouters.sin6_addr = allrouters_in6;

	while ((c = getopt(argc, argv, "nsqvTtdgPp:")) != EOF) {
		switch (c) {
		case 'n':
			install = _B_FALSE;
			break;
		case 's':
			supplier = _B_TRUE;
			break;
		case 'q':
			supplier = _B_FALSE;
			break;
		case 'v':
			tracing |= ACTION_BIT;
			break;
		case 'T':
			daemon = _B_FALSE;
			break;
		case 't':
			tracepackets = _B_TRUE;
			daemon = _B_FALSE;
			tracing |= (INPUT_BIT | OUTPUT_BIT);
			break;
		case 'd':
			break;
		case 'P':
			dopoison = _B_FALSE;
			break;
		case 'p':
			rip6_port = htons(atoi(optarg));
			allrouters.sin6_port = rip6_port;
			break;
		default:
			usage(argv[0]);
			/* NOTREACHED */
		}
	}

	/*
	 * Any extra argument is considered
	 * a tracing log file.
	 */
	if (optind < argc) {
		traceon(argv[optind]);
	} else if (tracing && !daemon) {
		traceonfp(stdout);
	} else if (tracing) {
		(void) fprintf(stderr, "Need logfile with -v\n");
		usage(argv[0]);
		/* NOTREACHED */
	}

	if (daemon) {
		int t;

		if (fork())
			exit(EXIT_SUCCESS);
		for (t = 0; t < 20; t++) {
			if (!tracing || (t != fileno(ftrace)))
				(void) close(t);
		}
		(void) open("/", 0);
		(void) dup2(0, 1);
		(void) dup2(0, 2);
		(void) setsid();
	}

	/* Store our process id, blow away any existing file if it exists. */
	if ((pidfp = fopen(PATH_PID, "w")) == NULL) {
		(void) fprintf(stderr, "%s: unable to open " PATH_PID ": %s\n",
		    argv[0], strerror(errno));
	} else {
		(void) fprintf(pidfp, "%ld\n", getpid());
		(void) fclose(pidfp);
		(void) chmod(PATH_PID, pidmode);
	}


	iocsoc = socket(AF_INET6, SOCK_DGRAM, 0);
	if (iocsoc < 0) {
		syslog(LOG_ERR, "main: socket: %m");
		exit(EXIT_FAILURE);
	}

	setup_rtsock();

	/*
	 * Allocate the buffer to hold the RIPng packet.  In reality, it will be
	 * smaller than IPV6_MAX_PACKET octets due to (at least) the IPv6 and
	 * UDP headers but IPV6_MAX_PACKET is a convenient size.
	 */
	packet = (char *)malloc(IPV6_MAX_PACKET);
	if (packet == NULL) {
		syslog(LOG_ERR, "main: malloc: %m");
		exit(EXIT_FAILURE);
	}
	msg = (struct rip6 *)packet;

	/*
	 * Allocate the buffer to hold the ancillary data.  This data is used to
	 * insure that the incoming hop count of a RIPCMD6_RESPONSE message is
	 * IPV6_MAX_HOPS which indicates that it came from a direct neighbor
	 * (namely, no intervening router decremented it).
	 */
	control = (char *)malloc(IPV6_MAX_PACKET);
	if (control == NULL) {
		syslog(LOG_ERR, "main: malloc: %m");
		exit(EXIT_FAILURE);
	}

	openlog("in.ripngd", LOG_PID | LOG_CONS, LOG_DAEMON);

	(void) gettimeofday(&now, (struct timezone *)NULL);

	initifs();
	solicitall(&allrouters);

	if (supplier)
		supplyall(&allrouters, 0, (struct interface *)NULL, _B_TRUE);

	(void) sigset(SIGALRM, (void (*)(int))timer);
	(void) sigset(SIGHUP, (void (*)(int))initifs);
	(void) sigset(SIGTERM, (void (*)(int))term);
	(void) sigset(SIGUSR1, (void (*)(int))if_dump);
	(void) sigset(SIGUSR2, (void (*)(int))rtdump);

	/*
	 * Seed the pseudo-random number generator for GET_RANDOM().
	 */
	srandom((uint_t)gethostid());

	timer();

	for (;;) {
		if (needupdate) {
			waittime = nextmcast;
			timevalsub(&waittime, &now);
			if (waittime.tv_sec < 0) {
				timeout = 0;
			} else {
				timeout = TIME_TO_MSECS(waittime);
			}
			if (tracing & ACTION_BIT) {
				(void) fprintf(ftrace,
				    "poll until dynamic update in %d msec\n",
				    timeout);
				(void) fflush(ftrace);
			}
		} else {
			timeout = INFTIM;
		}

		if ((n = poll(poll_ifs, poll_ifs_num, timeout)) < 0) {
			if (errno == EINTR)
				continue;
			syslog(LOG_ERR, "main: poll: %m");
			exit(EXIT_FAILURE);
		}
		(void) sighold(SIGALRM);
		(void) sighold(SIGHUP);
		/*
		 * Poll timed out.
		 */
		if (n == 0) {
			if (needupdate) {
				TRACE_ACTION("send delayed dynamic update",
				    (struct rt_entry *)NULL);
				(void) gettimeofday(&now,
				    (struct timezone *)NULL);
				supplyall(&allrouters, RTS_CHANGED,
				    (struct interface *)NULL, _B_TRUE);
				lastmcast = now;
				needupdate = _B_FALSE;
				nextmcast.tv_sec = 0;
			}
			(void) sigrelse(SIGHUP);
			(void) sigrelse(SIGALRM);
			continue;
		}
		(void) gettimeofday(&now, (struct timezone *)NULL);
		for (i = 0; i < poll_ifs_num; i++) {
			/*
			 * This case should never happen.
			 */
			if (poll_ifs[i].revents & POLLERR) {
				syslog(LOG_ERR,
				    "main: poll returned a POLLERR event");
				continue;
			}
			if (poll_ifs[i].revents & POLLIN) {
				for (ifp = ifnet; ifp != NULL;
				    ifp = ifp->int_next) {
					if (poll_ifs[i].fd == ifp->int_sock)
						in_data(ifp);
				}
			}
		}
		(void) sigrelse(SIGHUP);
		(void) sigrelse(SIGALRM);
	}

	return (0);
}
コード例 #28
0
ファイル: sighold02.c プロジェクト: shubmit/shub-ltp
void do_child()
{
	int rv;			/* function return value */
	int sig;		/* current signal */
	int cnt;

	p_p.result = TPASS;

	/* set up signal handlers for the signals */
	if (setup_sigs(p_p.mesg) < 0) {
		p_p.result = TBROK;

	} else {
		/* all set up to catch signals, now hold them */

		for (cnt = 0, sig = 1; sig < NUMSIGS; sig++) {
			if ((sig == 41) && !CRAYT3E && !SGI) {
				sig = 42;	/* skip over SIGPEFAILURE for non-CRAYT3E systems */
			}
			if ((sig != SIGCLD) && (sig != SIGKILL) &&
			    (sig != SIGALRM) && (sig != SIGSTOP)
#ifdef SIGNOBDM
			    && (sig != SIGNOBDM)
#endif
			    && (sig != SIGCANCEL) && (sig != SIGTIMER)
			    ) {

				cnt++;
				TEST(sighold(sig));
				rv = TEST_RETURN;
				if (rv != 0) {
					/* THEY say sighold ALWAYS returns 0 */
					p_p.result = TFAIL;
					(void)sprintf(p_p.mesg,
						      "sighold(%d) failed, rv:%d, errno:%d",
						      sig, rv, errno);
					break;
				}
			}
		}
		if (STD_TIMING_ON) {
			p_p.rtimes = tblock;
		}
		if (p_p.result == TPASS) {
			sprintf(p_p.mesg,
				"Sighold called without error for %d of %d signals",
				cnt, NUMSIGS - 1);
		}
	}

	/*
	 * write to parent (if not READY, parent will BROK) and
	 * wait for parent to send signals.  The timeout clock is set so
	 * that we will not wait forever - if sighold() did its job, we
	 * will not receive the signals.  If sighold() blew it we will
	 * catch a signal and the interrupt handler will exit(1).
	 */
#if debug
	printf("child: %d writing to parent fd:%d\n", getpid(), CHILDSWRITEFD);
#endif
	if (write_pipe(CHILDSWRITEFD) < 0 || p_p.result != TPASS) {
		exit(2);
	}

	/*
	 * Read pipe from parent, that will tell us that all signals were sent
	 */
	if (read_pipe(CHILDSREADFD) != 0) {
		p_p.result = TBROK;
		strcpy(p_p.mesg, "read() pipe failed");
	} else if (signals_received[0] == '\0') {
		p_p.result = TPASS;
		strcpy(p_p.mesg,
		       "No signals trapped after being sent by parent");
	} else {
		p_p.result = TFAIL;
		sprintf(p_p.mesg, "signals received: %s", signals_received);
	}

	if (write_pipe(CHILDSWRITEFD) < 0) {
		exit(2);
	}

	/* exit back to parent */
	if (p_p.result == TPASS)
		exit(0);
	else
		exit(1);
}
コード例 #29
0
ファイル: snmpd.c プロジェクト: WimObiwan/net-snmp
/*******************************************************************-o-******
 * receive
 *
 * Parameters:
 *      
 * Returns:
 *	0	On success.
 *	-1	System error.
 *
 * Infinite while-loop which monitors incoming messages for the agent.
 * Invoke the established message handlers for incoming messages on a per
 * port basis.  Handle timeouts.
 */
static int
receive(void)
{
    int             numfds;
    netsnmp_large_fd_set readfds, writefds, exceptfds;
    struct timeval  timeout, *tvp = &timeout;
    int             count, block, i;
#ifdef	USING_SMUX_MODULE
    int             sd;
#endif                          /* USING_SMUX_MODULE */

    netsnmp_large_fd_set_init(&readfds, FD_SETSIZE);
    netsnmp_large_fd_set_init(&writefds, FD_SETSIZE);
    netsnmp_large_fd_set_init(&exceptfds, FD_SETSIZE);

    /*
     * ignore early sighup during startup
     */
    reconfig = 0;

#if defined(WIN32)
    create_stdin_waiter_thread();
#endif

    /*
     * Loop-forever: execute message handlers for sockets with data
     */
    while (netsnmp_running) {
        if (reconfig) {
#if HAVE_SIGHOLD
            sighold(SIGHUP);
#endif
            reconfig = 0;
            snmp_log(LOG_INFO, "Reconfiguring daemon\n");
	    /*  Stop and restart logging.  This allows logfiles to be
		rotated etc.  */
	    netsnmp_logging_restart();
	    snmp_log(LOG_INFO, "NET-SNMP version %s restarted\n",
		     netsnmp_get_version());
            update_config();
            send_easy_trap(SNMP_TRAP_ENTERPRISESPECIFIC, 3);
#if HAVE_SIGHOLD
            sigrelse(SIGHUP);
#endif
        }

        /*
         * default to sleeping for a really long time. INT_MAX
         * should be sufficient (eg we don't care if time_t is
         * a long that's bigger than an int).
         */
        tvp = &timeout;
        tvp->tv_sec = INT_MAX;
        tvp->tv_usec = 0;

        numfds = 0;
        NETSNMP_LARGE_FD_ZERO(&readfds);
        NETSNMP_LARGE_FD_ZERO(&writefds);
        NETSNMP_LARGE_FD_ZERO(&exceptfds);
        block = 0;
        snmp_select_info2(&numfds, &readfds, tvp, &block);
        if (block == 1) {
            tvp = NULL;         /* block without timeout */
	}

#ifdef	USING_SMUX_MODULE
        if (smux_listen_sd >= 0) {
            NETSNMP_LARGE_FD_SET(smux_listen_sd, &readfds);
            numfds =
                smux_listen_sd >= numfds ? smux_listen_sd + 1 : numfds;

            for (i = 0; i < smux_snmp_select_list_get_length(); i++) {
                sd = smux_snmp_select_list_get_SD_from_List(i);
                if (sd != 0)
                {
                   NETSNMP_LARGE_FD_SET(sd, &readfds);
                   numfds = sd >= numfds ? sd + 1 : numfds;
                }
            }
        }
#endif                          /* USING_SMUX_MODULE */

#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
        netsnmp_external_event_info2(&numfds, &readfds, &writefds, &exceptfds);
#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */

    reselect:
        for (i = 0; i < NUM_EXTERNAL_SIGS; i++) {
            if (external_signal_scheduled[i]) {
                external_signal_scheduled[i]--;
                external_signal_handler[i](i);
            }
        }

        DEBUGMSGTL(("snmpd/select", "select( numfds=%d, ..., tvp=%p)\n",
                    numfds, tvp));
        if (tvp)
            DEBUGMSGTL(("timer", "tvp %ld.%ld\n", (long) tvp->tv_sec,
                        (long) tvp->tv_usec));
        count = netsnmp_large_fd_set_select(numfds, &readfds, &writefds, &exceptfds,
				     tvp);
        DEBUGMSGTL(("snmpd/select", "returned, count = %d\n", count));

        if (count > 0) {

#ifdef USING_SMUX_MODULE
            /*
             * handle the SMUX sd's 
             */
            if (smux_listen_sd >= 0) {
                for (i = 0; i < smux_snmp_select_list_get_length(); i++) {
                    sd = smux_snmp_select_list_get_SD_from_List(i);
                    if (NETSNMP_LARGE_FD_ISSET(sd, &readfds)) {
                        if (smux_process(sd) < 0) {
                            smux_snmp_select_list_del(sd);
                        }
                    }
                }
                /*
                 * new connection 
                 */
                if (NETSNMP_LARGE_FD_ISSET(smux_listen_sd, &readfds)) {
                    if ((sd = smux_accept(smux_listen_sd)) >= 0) {
                        smux_snmp_select_list_add(sd);
                    }
                }
            }

#endif                          /* USING_SMUX_MODULE */

#ifndef NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER
            netsnmp_dispatch_external_events2(&count, &readfds,
                                              &writefds, &exceptfds);
#endif /* NETSNMP_FEATURE_REMOVE_FD_EVENT_MANAGER */

            /* If there are still events leftover, process them */
            if (count > 0) {
              snmp_read2(&readfds);
            }
        } else
            switch (count) {
            case 0:
                snmp_timeout();
                break;
            case -1:
                DEBUGMSGTL(("snmpd/select", "  errno = %d\n", errno));
                if (errno == EINTR) {
                    /*
                     * likely that we got a signal. Check our special signal
                     * flags before retrying select.
                     */
		    if (netsnmp_running && !reconfig) {
                        goto reselect;
		    }
                    continue;
                } else {
                    snmp_log_perror("select");
                }
                return -1;
            default:
                snmp_log(LOG_ERR, "select returned %d\n", count);
                return -1;
            }                   /* endif -- count>0 */

        /*
         * see if persistent store needs to be saved
         */
        snmp_store_if_needed();

        /*
         * run requested alarms 
         */
        run_alarms();

        netsnmp_check_outstanding_agent_requests();

    }                           /* endwhile */

    netsnmp_large_fd_set_cleanup(&readfds);
    netsnmp_large_fd_set_cleanup(&writefds);
    netsnmp_large_fd_set_cleanup(&exceptfds);

#if defined(WIN32)
    join_stdin_waiter_thread();
#endif

    snmp_log(LOG_INFO, "Received TERM or STOP signal...  shutting down...\n");
    return 0;

}                               /* end receive() */
コード例 #30
0
ファイル: main.c プロジェクト: feychting/OS
/*
 * This function does what "printenv | grep <arguments> | sort | pager"
 * usually does in a shell. Pipes are used to transfer results between
 * children, instead of them printing to stdout and reading from stdin.
 * The parent always waits for the child to finish, since the results
 * are used by other children.
 */
int handleCheckEnv(char *arg) {
    pid_t childPID, childPID2, childPID3;
    int pipe1[2], pipe2[2];

    if (pipe(pipe1) == -1) {
        perror("pipe1");
        return EXIT_FAILURE;
    }
    if (pipe(pipe2) == -1) {
        perror("pipe2");
        return EXIT_FAILURE;
    }
    sighold(SIGCHLD); /*Don't let signals interrupt.*/
    if ((childPID = fork()) >= 0) { /*In first child.*/
        if (childPID == 0) {
            close(pipe1[READ]);
            /*
             * Reroute stdout to pipe1.
             */
            if (dup2(pipe1[WRITE], STDOUT_FILENO) == -1) {
                perror("dup2 failed");
                return EXIT_FAILURE;
            }
            close(pipe1[WRITE]);
            /*
             * Execute printenv with an argument if given by user.
             */
            if (execlp("printenv", "printenv", arg, NULL) == -1) {
                perror("printenv failed");
                return EXIT_FAILURE;
            }
        }
        else { /*In parent.*/
            waitpid(childPID, NULL, 0);
            close(pipe1[WRITE]);
            childPID2 = fork();
            if (childPID2 >= 0) {
                if (childPID2 == 0) { /*In second child.*/
                    /*
                     * Reroute stdin to pipe1.
                     */
                    if (dup2(pipe1[READ], STDIN_FILENO) == -1) {
                        perror("dup2 failed");
                        return EXIT_FAILURE;
                    }
                    close(pipe1[READ]);
                    close(pipe2[READ]);
                    /*
                     * Reroute stdout to pipe2.
                     */
                    if (dup2(pipe2[WRITE], STDOUT_FILENO) == -1) {
                        perror("dup2 failed");
                        return EXIT_FAILURE;
                    }
                    close(pipe2[WRITE]);
                    /*
                     * Execute sort on result from printenv.
                     */
                    if (execlp("sort", "sort", NULL) == -1) {
                        perror("Sort failed");
                        return EXIT_FAILURE;
                    }
                }
                else { /*In parent.*/
                    waitpid(childPID2, NULL, 0);
                    close(pipe1[READ]);
                    close(pipe2[WRITE]);
                    childPID3 = fork();
                    if (childPID3 >= 0) {
                        if (childPID3 == 0) { /*In third child.*/
                            char *pager = getenv("PAGER");
                            if (dup2(pipe2[READ], STDIN_FILENO) == -1) {
                                perror("dup2 failed");
                            }
                            close(pipe2[READ]);

                            if (!pager) {
                                pager = "less";
                            }
                            /*
                             * Print result using the pager specified in environment,
                             * unless it is less. If it fails, set pager to less.
                             */
                            if ((strcmp(pager, "less")>0) && (execlp(pager, pager, NULL) == -1)) {
                                perror("Pager failed, use less");
                                pager = "less";
                            }
                            /*
                             * Try printing using less, if that fails, try to use more.
                             */
                            if ((strcmp(pager, "less") == 0) && (execlp(pager, pager, NULL) == -1)) {
                                perror("Less failed, do more");
                                execlp("more", "more", NULL);
                            }
                        } else { /*In parent.*/
                            waitpid(childPID3, NULL, 0);
                            close(pipe2[READ]);
                        }
                    }
                }
            }
            else{
                perror("fork failed!");
                return EXIT_FAILURE;
            }
        }
    }
    else {
        perror("fork failed!");
        return EXIT_FAILURE;
    }
    sigrelse(SIGCHLD); /*Let signals through again.*/
    return 0;
}