Esempio n. 1
0
int main()
{
	while (TRUE)
	{
		// print prompt and read into string array input.
		print_prompt();
		char* input[64];
		scan_input(input);

		// perform a fork and process input.
		int pid = fork();
		if (pid != 0)
		{
			// code for parent process.
			int statloc;
			process_parent(&statloc);
		}
		else
		{
			// code for forked child process.
			process_child(input);
		}

	}
}
Esempio n. 2
0
int main( int argc, char *argv[] )
{
    int skipcount=parse_cmdline( argc, argv );
    int ret=0;

    /* Warn if we're run as SUID */
    if( getuid()!=geteuid() ) {
        fprintf(stderr, "!!!!Running privbind SUID is a security risk!!!!\n");
    }

    /* Create a couple of sockets for communication with our children */
    int sv[2];
    if( socketpair(AF_UNIX, SOCK_SEQPACKET, 0, sv)<0 ) {
        perror("privbind: socketpair");
        return 2;
    }

    pid_t child_pid=fork();
    /* http://sourceforge.net/mailarchive/message.php?msg_name=20070601194744.GA29875%40fermat.math.technion.ac.il
     * Reverse the usual role of "parent" and "child".
     * Parent process perform "child" actions - running the command.
     * Child process is the one that listens on the socket and handles the binds
     */
    switch(child_pid) {
    case -1:
        perror("privbind: fork");
        exit(1);

    case 0:
        /* We are the child */
        ret=process_parent( sv );
        break;
    default:
        /* We are the parent */

    {
        /* Wait for the child to exit. */
        int status=0;

        do {
            waitpid( child_pid, &status, 0 );
        } while( !WIFEXITED(status) && !WIFSIGNALED(status) );

        if( WIFEXITED(status) ) {
            ret=WEXITSTATUS(status);

            if( ret==0 ) {
                /* Child has indicated that it is ready */
                ret=process_child( sv, argc-skipcount, argv+skipcount );
            }
        } else {
            fprintf(stderr, "privbind: root process terminated with signal %d\n", WTERMSIG(status) );
            ret=2;
        }
    }
    break;
    }

    return ret;
}
Esempio n. 3
0
int main(int argc, char *argv[])
{
	int i, n_count, sem_value, status;

	if (argc != 2) {
		printf("%s [counter]\n", argv[0]);
		exit(EXIT_FAILURE);
	}

	n_count = atoi(argv[1]);
	p_psem = sem_open(NAME_POSIX_SEM, O_CREAT | O_EXCL, 0600, n_count);

	if (p_psem == SEM_FAILED) {
		if (errno != EEXIST) {
			perror("FAIL: sem_open");
			exit(EXIT_FAILURE);
		}
		p_psem = sem_open(NAME_POSIX_SEM, 0);
		printf("[%d] Attach to an existed sem \n", getpid());
	} else
		printf("[%d] Create new sem \n", getpid());

	sem_getvalue(p_psem, &sem_value);
	printf("[%d] sem_getvalue = %d\n", getpid(), sem_value);

	for (i = 0; i < max_child; i++) {
		printf("[%d] iteration(%d) : Atomically decrease\n", getpid(), i);
		sem_wait(p_psem);

		switch ( fork() ) {
			case 0:		/* child */
				process_child(i);
				sem_post(p_psem);
				exit(EXIT_SUCCESS);
			case -1:	/* error */
				fprintf(stderr, "FAIL: fork() [%s:%d]\n", __FUNCTION__, __LINE__);
				exit(EXIT_FAILURE);
			default:	/* parrent */
				break;
		}
		usleep(10000);
	}

	for (i = 0; i < max_child; i++) {
		pid_t pid_child;
		if ((pid_child = waitpid(-1, &status, 0)) == -1) {
			perror("waitpid error");
			continue;
		}
	}

	sem_getvalue(p_psem, &sem_value);
	printf("[%d] sem_getvalue = %d \n", getpid(), sem_value);
	if (sem_unlink(NAME_POSIX_SEM) == -1) {
		perror("sem_unlink error");
		exit(EXIT_FAILURE);
	}
	return EXIT_SUCCESS;
}
Esempio n. 4
0
int main()
{
	while (TRUE)
	{
		// print prompt and read into string array input.
		print_prompt();
		char* input[64];
		scan_input(input);
		int input_len = array_len(input);
		int option = 0;

		// if last parameter is an & then run child process in background.
		/*if (input_len != 0 && !strcmp(input[input_len], "&"))
		{
			option = 1;
			input[input_len] = NULL;
		}*/

		/* pass to change_directory if input is a cd command.
		   Else perform a fork and process input. */
		if (input_len != 0 && !strcmp(input[0], "cd"))
		{
			change_directory(input);
		}
		else if (input_len != 0 && fork() != 0)
		{
			// code for parent process.
			int statloc;
			process_parent(&statloc, option);
		}
		else if (input_len != 0)
		{
			// code for forked child process.
			process_child(input);
		}

	}
}
int
do_process(void)
{
	struct kevent ke;
	int kq, status;
	pid_t pid, pid2;
	int didfork, didchild;
	int i;
	struct timespec ts;

	/*
	 * Timeout in case something doesn't work.
	 */
	ts.tv_sec = 10;
	ts.tv_nsec = 0;

	ASS((kq = kqueue()) >= 0, warn("kqueue"));

	/*
	 * Install a signal handler so that we can use pause() to synchronize
	 * with the child with the parent.
	 */
	signal(SIGUSR1, usr1handler);

	switch ((pid = fork())) {
	case -1:
		err(1, "fork");
	case 0:
		_exit(process_child());
	}

	sleep(2);	/* wait for child to settle down. */

	EV_SET(&ke, pid, EVFILT_PROC, EV_ADD|EV_ENABLE|EV_CLEAR,
	    NOTE_EXIT|NOTE_FORK|NOTE_EXEC|NOTE_TRACK, 0, NULL);
	ASS(kevent(kq, &ke, 1, NULL, 0, NULL) == 0,
	    warn("can't register events on kqueue"));

	kill(pid, SIGUSR1);	/* sync 1 */

	didfork = didchild = 0;

	pid2 = -1;
	for (i = 0; i < 2; i++) {
		ASS(kevent(kq, NULL, 0, &ke, 1, &ts) == 1,
		    warnx("didn't receive event"));
		ASSX(ke.filter == EVFILT_PROC);
		switch (ke.fflags) {
		case NOTE_CHILD:
			didchild = 1;
			ASSX((pid_t)ke.data == pid);
			pid2 = ke.ident;
			fprintf(stderr, "child %d\n", pid2);
			break;
		case NOTE_FORK:
			didfork = 1;
			ASSX(ke.ident == pid);
			fprintf(stderr, "fork\n");
			break;
		case NOTE_TRACKERR:
			errx(1, "child tracking failed due to resource shortage");
		default:
			errx(1, "kevent returned weird event 0x%x pid %d",
			    ke.fflags, (pid_t)ke.ident);
		}
	}

	if (pid2 == -1)
		return (1);

	/* Both children now sleeping. */

	ASSX(didchild == didfork == 1);
	
	kill(pid2, SIGUSR1);	/* sync 2.1 */
	kill(pid, SIGUSR1);	/* sync 2 */

	if (wait(&status) < 0)
		err(1, "wait");

	if (!WIFEXITED(status))
		errx(1, "child didn't exit?");

	close(kq);
	return (WEXITSTATUS(status) != 0);
}