Exemplo n.º 1
0
Arquivo: vfork.c Projeto: zxwbj/danei
int main (void) {
	int local = 200;
	int* heap = malloc (sizeof (int));
	*heap = 300;
	printf ("父进程:%d %d %d\n", global,
		local, *heap);
	pid_t pid = vfork ();
	if (pid == -1) {
		perror ("fork");
		return -1;
	}
	if (pid == 0) {
		printf ("子进程:%d %d %d\n", ++global,
			++local, ++*heap);
//	free (heap);
//	return 0;
		exit (0);
	}
//sleep (1);
	printf ("父进程:%d %d %d\n", global,
		local, *heap);
	free (heap);
	return 0;
}
Exemplo n.º 2
0
/* This does a fork/exec in one call, using vfork().  Returns PID of new child,
 * -1 for failure.  Runs argv[0], searching path if that has no / in it. */
pid_t spawn(char **argv)
{
	/* Compiler should not optimize stores here */
	volatile int failed;
	pid_t pid;

// Ain't it a good place to fflush(NULL)?

	/* Be nice to nommu machines. */
	failed = 0;
	pid = vfork();
	if (pid < 0) /* error */
		return pid;
	if (!pid) { /* child */
		/* This macro is ok - it doesn't do NOEXEC/NOFORK tricks */
		BB_EXECVP(argv[0], argv);

		/* We are (maybe) sharing a stack with blocked parent,
		 * let parent know we failed and then exit to unblock parent
		 * (but don't run atexit() stuff, which would screw up parent.)
		 */
		failed = errno;
		_exit(111);
	}
	/* parent */
	/* Unfortunately, this is not reliable: according to standards
	 * vfork() can be equivalent to fork() and we won't see value
	 * of 'failed'.
	 * Interested party can wait on pid and learn exit code.
	 * If 111 - then it (most probably) failed to exec */
	if (failed) {
		errno = failed;
		return -1;
	}
	return pid;
}
Exemplo n.º 3
0
int main()
{
	int val = 0;
	pid_t id = vfork();
	if(id < 0)
	{
		exit(1);
	}
	else if(id == 0) //child
	{
		atexit(fun);
		printf("this is child process.\n");
	//	++g_val;
	//	++val;
		sleep(3);
		exit(0);
	}
	else
	{
		printf("this is father process\n");
	//	printf("father exit, g_val = %d, val = %d\n", g_val, val);
	}
	return 0;
}
Exemplo n.º 4
0
static int pipeencode(char *filename, char *argument, int fdin, int fdout)
{
	int res;
	int x;
#if defined(HAVE_WORKING_FORK)
        res = fork();
#else
        res = vfork();
#endif
	if (res < 0) 
		cw_log(LOG_WARNING, "Fork failed\n");
	if (res)
		return res;
	dup2(fdin, STDIN_FILENO);
	dup2(fdout, STDOUT_FILENO);
	for (x=0;x<256;x++) {
		if ((x != STDIN_FILENO && x != STDOUT_FILENO) || STDERR_FILENO == x)
			close(x);
	}
	cw_log(LOG_WARNING, "Launching '%s' '%s'\n", filename, argument);
	execlp(filename, "TEST", argument, (char *)NULL);
	cw_log(LOG_WARNING, "Execute of %s failed\n", filename);
	return -1;
}
Exemplo n.º 5
0
static pid_t path_pfexecve(Shell_t *shp,const char *path, char *argv[],char *const envp[],int spawn)
{
#if SHOPT_PFSH 
	char  resolvedpath[PATH_MAX + 1];
	pid_t	pid;
#endif /*SHOPT_PFSH */
	if(shp->vex->cur)
	{
		spawnvex_apply(shp->vex,0,0);
		spawnvex_apply(shp->vexp,0,SPAWN_RESET);
	}
#if SHOPT_PFSH 
	if(spawn)
	{
		while((pid = vfork()) < 0)
			_sh_fork(shp,pid, 0, (int*)0);
		if(pid)
			return(pid);
	}
	if(!sh_isoption(shp,SH_PFSH))
		return(execve(path, argv, envp));
	/* Solaris implements realpath(3C) using the resolvepath(2) */
	/* system call so we can save us to call access(2) first */

	/* we can exec the command directly instead of via pfexec(1) if */
	/* there is a matching entry without attributes in exec_attr(4) */
	if(!path_xattr(shp,path,resolvedpath))
		return(execve(path, argv, envp));
	--argv;
	argv[0] = argv[1];
	argv[1] = resolvedpath;
	return(execve("/usr/bin/pfexec", argv, envp));
#else
	return(execve(path, argv, envp));
#endif
}
Exemplo n.º 6
0
int main(int argc, char const *argv[]){
	int local = 999;
	pid_t pid;

	printf("before vfork\n");
	show_status(getpid(), global, local);

	pid = vfork();

	if(pid < 0){
		err_sys("vfork error");
	}else if (0 == pid){
		printf("child process\n");
		global += 111;
		local -= 111;
		show_status(getpid(), global, local);
		exit(EXIT_SUCCESS);
	}else{
		printf("parent process\n");
		show_status(getpid(), global, local);
	}

	exit(EXIT_SUCCESS);
}
Exemplo n.º 7
0
int* forkn(int n, int *buckets, int *matrix1, int n1, int m1, int *matrix2, int n2, int m2) {
    pid_t pid;
    int i, j, l;
    int current_line = 0;
    int k = 0;
    int *result_matrix = (int*)calloc(n1*m2, sizeof(int));
    for (i = 0; i < n; i++) {
        if ((pid = vfork()) < 0) {
            printf("vfork error");
        } else if (pid == 0) {
            printf("child ");
            int n_lines = buckets[k];
            for (j = 0; j < n_lines; j++) {
                for (l = 0; l < m2; l++) {
                    result_matrix[ID(m2,current_line,l)] = multiplyLineColumn(matrix1, matrix2, m1, m2, current_line, l);
                }
                current_line++;
            }
            k++;
            _exit(0);
        }
    }
    return result_matrix;
}
Exemplo n.º 8
0
int main()
{
       pid_t   pid;
       int     i;

       pid = vfork();
//       pid = fork();
       if (pid == 0) {
               a = 1;
               for (i = 0; i < 5; i++) {
                       printf("child %d\n", i + 1);
                       sleep(1);
               }
               exit (EXIT_SUCCESS);
       }
       else {
               printf("*data %d\n", a);
               for (i = 0; i < 5; i++) {
                       printf("parent %d\n", i + 1);
                       sleep(1);
               }
               exit (EXIT_SUCCESS);
       }
}
Exemplo n.º 9
0
int
main(int argc, char *argv[])
{
    switch (vfork()) {
    case -1: errExit("vfork");

    case 0: if (close(STDOUT_FILENO) == -1)
                errMsg("close - child");
            _exit(EXIT_SUCCESS);

    default: break;
    }

    /* Now parent closes STDOUT_FILENO twice: only the second close
       should fail, indicating that the close(STDOUT_FILENO) by the
       child did not affect the parent. */

    if (close(STDOUT_FILENO) == -1)
        errMsg("close");
    if (close(STDOUT_FILENO) == -1)
        errMsg("close");

    exit(EXIT_SUCCESS);
}
Exemplo n.º 10
0
int kcinth()
{
   u16    segment, offset;
   int    a,b,c,d, r;
   segment = running->uss; 
   offset = running->usp;

   a = get_word(segment, offset + 2*PA);
   b = get_word(segment, offset + 2*PB);
   c = get_word(segment, offset + 2*PC);
   d = get_word(segment, offset + 2*PD);

   switch(a){
       case 0 : r = running->pid;     break;
       case 1 : r = do_ps();          break;
       case 2 : r = chname(b);        break;
       case 3 : r = kmode();          break;
       case 4 : r = tswitch();        break;
       case 5 : r = do_wait(b);       break;
       case 6 : r = do_exit(b);       break;
        
       case 7 : r = fork();           break;
       case 8 : r = exec(b);          break;

       case 9 : r = vfork();          break;

       case 12: r = upline(b); break;
       
       case 90: r =  getc();          break;
       case 91: color=running->pid+11;
                r =  putc(b);         break;       
       case 99: do_exit(b);           break;
       default: printf("invalid syscall # : %d\n", a); 
   }
   put_word(r, segment, offset + 2*AX);
}
Exemplo n.º 11
0
EXPORT
BOOL CreateProcessA(LPCTSTR lpApplicationName, LPTSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, LPSECURITY_ATTRIBUTES lpThreadAttributes, BOOL bInheritHandles, DWORD dwCreationFlags, LPVOID lpEnvironment, LPCTSTR lpCurrentDirectory, LPSTARTUPINFO lpStartupInfo, LPPROCESS_INFORMATION lpProcessInformation){
	pid_t pid = vfork();
	//printf("Creating process %s %s\n", lpApplicationName, lpCommandLine);
	if(pid == 0){
		char commandline[256];
		strncpy(commandline, lpCommandLine, 255);
		commandline[255] = 0;
//		ptrace(PT_TRACE_ME, 0, 0, 0);
		// parse command line;
		int i=0;
		char *p = strchr(commandline, ' ');
		char *q = commandline;
		char *argv[16];
		while(p){
			*p = 0;
			argv[i++] = q;
			fflush(stdout);
			q = p + 1;
			p = strchr(commandline, ' ');
		}
		argv[i] = q;
		argv[i+1] = 0;
		//printf("Execing %s %s %s", argv[0], argv[1], argv[2]);
		fflush(stdout);
		execv(argv[0], argv);
		perror("Failed to execv!"); 
	} else {
		DebugActiveProcess(pid);
//		ptrace(PT_ATTACH, pid, 0, 0);
//		ptrace(PT_DETACH, pid, 0, 0);
		lpProcessInformation->dwProcessId = pid;
		lpProcessInformation->hProcess = pid;
	}
	return 1;
}
Exemplo n.º 12
0
static void edit_file(const struct passwd *pas, const char *file)
{
	const char *ptr;
	int pid = vfork();

	if (pid < 0) /* failure */
		bb_perror_msg_and_die("vfork");
	if (pid) { /* parent */
		wait4pid(pid);
		return;
	}

	/* CHILD - change user and run editor */
	change_user(pas);
	ptr = getenv("VISUAL");
	if (!ptr) {
		ptr = getenv("EDITOR");
		if (!ptr)
			ptr = "vi";
	}

	BB_EXECLP(ptr, ptr, file, NULL);
	bb_perror_msg_and_die("exec %s", ptr);
}
Exemplo n.º 13
0
R_API int r_sys_cmd (const char *str) {
#if __FreeBSD__
	/* freebsd system() is broken */
	int st, pid, fds[2];
	if (pipe (fds))
		return -1;
	pid = vfork ();
	if (pid == -1)
		return -1;
	if (pid == 0) {
		dup2 (1, fds[1]);
		// char *argv[] = { "/bin/sh", "-c", str, NULL};
		// execv (argv[0], argv);
		r_sandbox_system (str, 0);
		_exit (127); /* error */
	} else {
		dup2 (1, fds[0]);
		waitpid (pid, &st, 0);
	}
	return WEXITSTATUS (st);
#else
	return r_sandbox_system (str, 1);
#endif
}
Exemplo n.º 14
0
int test_vfork()
{
	int var;
	pid_t pid;

	var = 88;
	if (write(STDOUT_FILENO, fork_buf, sizeof(fork_buf) - 1) != sizeof(fork_buf) - 1)
		err_sys("write");

	printf("before vfork\n");

	if ((pid = vfork()) < 0)
		err_sys("fork");
	else if (pid == 0) {
		globval++;
		var++;
		sleep(2);
//		exit(0);
	}
	printf("pid = %d, globval = %d, var = %d\n", (long)getpid(), globval, var);

	exit(0);
	return 0;
}
Exemplo n.º 15
0
int
posix_spawn(pid_t *pid, const char * path,
	__unused void *arg,
	const posix_spawnattr_t *attrp,
	char *const argv[], char *const envp[])
{
	pid_t p;
	volatile int error;

	error = 0;
#ifdef THERE_IS_NO_FORK
	/* Pray we can sanely modify signal foo */
	p = vfork();
#else
	p = fork();
#endif
	switch (p) {
	case -1:
		return errno;
	case 0:
		if (attrp) {
			error = posix_spawnattr_handle(attrp);
			if (error)
				_exit(127);
		}
		execve(path, argv, envp);
		error = errno;
		_exit(127);
	default:
		if (error != 0)
			waitpid(p, NULL, WNOHANG);
		else if (pid != NULL)
			*pid = p;
		return error;
	}
}
Exemplo n.º 16
0
void UnistdVfork(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs)
{
    ReturnValue->Val->Integer = vfork();
}
Exemplo n.º 17
0
int main(int argc, char *argv[])
{
    int ch, exit_status, status;
    pid_t bill;

    exit_status = EXIT_SUCCESS;

    while ((ch = getopt(argc, argv, "h?q")) != -1) {
        switch (ch) {
        case 'q':
            Flag_Quiet = true;
            break;

        case 'h':
        case '?':
        default:
            emit_help();
            /* NOTREACHED */
        }
    }
    argc -= optind;
    argv += optind;

    if (argc < 2)
        emit_help();

    iTimer.it_value.tv_sec = parse_duration(*argv++);

    bill = vfork();
    if (bill == 0) {            /* child */
        if (execvp(*argv, argv) == -1)
            err(EX_OSERR, "could not exec %s", *argv);
        /* NOTREACHED */

    } else if (bill > 0) {      /* parent */
        /* do not restart the wait() after SIGALRM, skip to the end... */
        if (siginterrupt(SIGALRM, 1) == -1)
            err(EX_SOFTWARE, "could not siginterrupt()");

        if (signal(SIGALRM, handle_alarm) == SIG_ERR)
            err(EX_SOFTWARE, "could not setup signal()");

        if (setitimer(ITIMER_REAL, &iTimer, NULL) == -1)
            err(EX_SOFTWARE, "could not setitimer()");

        wait(&status);

        /* the end */
        if (Kill_Bill) {
            if (!Flag_Quiet)
                warnx("duration %ld exceeded: killing pid %d",
                      (long)iTimer.it_value.tv_sec, bill);
            /*
             * Assume child is well behaved, and does not deadlock or
             * otherwise require multiple signals (race condition risk) to
             * take down.
             */
            if (kill(bill, SIGTERM) == -1)
                err(EX_OSERR, "could not kill child pid %d", bill);

            exit_status = EXIT_TIMEOUT;
        } else {
            /*
             * Pass on the child exit status. These can be illustrated
             * via something like:
             *
             *   timeout 99 perl -e 'exit 42'      ; echo $?
             *   timeout 99 perl -e 'kill 15, $$'  ; echo $?
             */
            if (WIFEXITED(status))
                exit_status = WEXITSTATUS(status);
            else if (WIFSIGNALED(status))
                exit_status = 128 + WTERMSIG(status);
        }
    } else {
        err(EX_OSERR, "could not fork()");
    }

    exit(exit_status);
}
Exemplo n.º 18
0
int start_pppd (struct call *c, struct ppp_opts *opts)
{
    char a, b;
    char tty[80];
    char *stropt[80];
    struct ppp_opts *p;
#ifdef USE_KERNEL
    struct l2tp_call_opts co;
#endif
    int pos = 1;
    int fd2;
#ifdef DEBUG_PPPD
    int x;
#endif
    struct termios ptyconf;
    struct call *sc;
    struct tunnel *st;

    p = opts;
    stropt[0] = strdup (PPPD);
    while (p)
    {
        stropt[pos] = (char *) malloc (strlen (p->option) + 1);
        strncpy (stropt[pos], p->option, strlen (p->option) + 1);
        pos++;
        p = p->next;
    }
    stropt[pos] = NULL;
    if (c->pppd > 0)
    {
        log (LOG_WARN, "%s: PPP already started on call!\n", __FUNCTION__);
        return -EINVAL;
    }
    if (c->fd > -1)
    {
        log (LOG_WARN, "%s: file descriptor already assigned!\n",
             __FUNCTION__);
        return -EINVAL;
    }
#ifdef USE_KERNEL
    if (kernel_support)
    {
        co.ourtid = c->container->ourtid;
        co.ourcid = c->ourcid;
        ioctl (server_socket, L2TPIOCGETCALLOPTS, &co);
        stropt[pos++] = strdup ("channel");
        stropt[pos] = (char *) malloc (10);
        snprintf (stropt[pos], 10, "%d", co.id);
        pos++;
        stropt[pos] = NULL;
    }
    else
    {
#endif
        if ((c->fd = getPtyMaster (&a, &b)) < 0)
        {
            log (LOG_WARN, "%s: unable to allocate pty, abandoning!\n",
                 __FUNCTION__);
            return -EINVAL;
        }

        /* set fd opened above to not echo so we don't see read our own packets
           back of the file descriptor that we just wrote them to */
        tcgetattr (c->fd, &ptyconf);
        *(c->oldptyconf) = ptyconf;
        ptyconf.c_cflag &= ~(ICANON | ECHO);
        ptyconf.c_lflag &= ~ECHO;
        tcsetattr (c->fd, TCSANOW, &ptyconf);

        snprintf (tty, sizeof (tty), "/dev/tty%c%c", a, b);
        fd2 = open (tty, O_RDWR);
        if (fd2 < 0) {
            log (LOG_WARN, "unable to open tty %s, cannot start pppd", tty);
            return -EINVAL;
        }
	stropt[pos++] = strdup(tty);	
	stropt[pos] = NULL;
#ifdef USE_KERNEL
    }
#endif

#ifdef DEBUG_PPPD
    log (LOG_DEBUG, "%s: I'm running:  ", __FUNCTION__);
    for (x = 0; stropt[x]; x++)
    {
        log (LOG_DEBUG, "\"%s\" ", stropt[x]);
    };
    log (LOG_DEBUG, "\n");
#endif
#ifdef __uClinux__
    c->pppd = vfork ();
#else 
    c->pppd = fork ();
#endif
    if (c->pppd < 0)
    {
        log (LOG_WARN, "%s: unable to fork(), abandoning!\n", __FUNCTION__);
        return -EINVAL;
    }
    else if (!c->pppd)
    {
        /* child */

        close (0); /* redundant; the dup2() below would do that, too */
        close (1); /* ditto */
        /* close (2); No, we want to keep the connection to /dev/null. */ 

        /* connect the pty to stdin and stdout */
        dup2 (fd2, 0);
        dup2 (fd2, 1);

        /* close all the calls pty fds */
        st = tunnels.head;
        while (st)
        {
            sc = st->call_head;
            while (sc)
            {
                close (sc->fd);
                sc = sc->next;
            }
            st = st->next;
        }

        /* close the UDP socket fd */
        close (server_socket);

        /* close the control pipe fd */
        close (control_fd);

        if( c->dialing[0] )
        {
            setenv( "CALLER_ID", c->dialing, 1 );
        }
        execv (PPPD, stropt);
        log (LOG_WARN, "%s: Exec of %s failed!\n", __FUNCTION__, PPPD);
        _exit (1);
    }
    close (fd2);
    pos = 0;
    while (stropt[pos])
    {
        free (stropt[pos]);
        pos++;
    };
    return 0;
}
Exemplo n.º 19
0
int
main(int argc, char *argv[])
{
	struct netperf_child *instance;
	char len_str[32];
	char *args[32];
	const char *host;
	volatile int ninst;
	int len, ninst_done;
	int opt, i, null_fd;
	double result;
	pid_t mypid;

	host = NULL;
	ninst = 2;
	len = 10;

	while ((opt = getopt(argc, argv, "i:H:l:")) != -1) {
		switch (opt) {
		case 'i':
			ninst = strtoul(optarg, NULL, 10);
			break;

		case 'H':
			host = optarg;
			break;

		case 'l':
			len = strtoul(optarg, NULL, 10);
			break;

		default:
			usage(argv[0]);
		}
	}
	if (ninst <= 0 || host == NULL || len <= 0)
		usage(argv[0]);

	mypid = getpid();

	snprintf(len_str, sizeof(len_str), "%d", len);

	i = 0;
	args[i++] = __DECONST(char *, NETPERF_CMD);
	args[i++] = __DECONST(char *, "-P0");
	args[i++] = __DECONST(char *, "-H");
	args[i++] = __DECONST(char *, host);
	args[i++] = __DECONST(char *, "-l");
	args[i++] = __DECONST(char *, len_str);
	args[i++] = __DECONST(char *, "-t");
	args[i++] = __DECONST(char *, "TCP_CC");
	args[i] = NULL;

	instance = calloc(ninst, sizeof(struct netperf_child));
	if (instance == NULL) {
		fprintf(stderr, "calloc failed\n");
		exit(1);
	}

	null_fd = open("/dev/null", O_RDWR);
	if (null_fd < 0) {
		fprintf(stderr, "open null failed: %d\n", errno);
		exit(1);
	}

	for (i = 0; i < ninst; ++i) {
		char filename[128];

		snprintf(filename, sizeof(filename), TCP_CC_FILENAME,
		    (int)mypid, i);
		instance[i].fd = open(filename, O_CREAT | O_TRUNC | O_RDWR,
		    S_IWUSR | S_IRUSR);
		if (instance[i].fd < 0) {
			fprintf(stderr, "open %s failed: %d\n",
			    filename, errno);
			exit(1);
		}
	}

	for (i = 0; i < ninst; ++i) {
		pid_t pid;

		pid = vfork();
		if (pid == 0) {
			int ret;

			dup2(instance[i].fd, STDOUT_FILENO);
			dup2(null_fd, STDERR_FILENO);
			ret = execv(NETPERF_PATH, args);
			if (ret < 0) {
				fprintf(stderr, "execv %d failed: %d\n",
				    i, errno);
				_exit(1);
			}
			/* Never reached */
			abort();
		} else if (pid < 0) {
			fprintf(stderr, "vfork %d failed: %d\n", i, errno);
			exit(1);
		}
	}

	ninst_done = 0;
	while (ninst_done < ninst) {
		pid_t pid;

		pid = waitpid(-1, NULL, 0);
		if (pid < 0) {
			fprintf(stderr, "waitpid failed: %d\n", errno);
			exit(1);
		}
		++ninst_done;
	}

	result = 0.0;
	for (i = 0; i < ninst; ++i) {
		char line[128], filename[128];
		FILE *fp;

		close(instance[i].fd);
		snprintf(filename, sizeof(filename), TCP_CC_FILENAME,
		    (int)mypid, i);
		fp = fopen(filename, "r");
		if (fp == NULL) {
			fprintf(stderr, "fopen %s failed\n", filename);
			exit(1);
		}

		while (fgets(line, sizeof(line), fp) != NULL) {
			int n, arg1, arg2, arg3, arg4;
			double res, arg5;

			n = sscanf(line, "%d%d%d%d%lf%lf",
			    &arg1, &arg2, &arg3, &arg4, &arg5, &res);
			if (n == 6) {
				result += res;
				break;
			}
		}
		fclose(fp);
		unlink(filename);
	}
	printf("TCP_CC %f conns/s\n", result);

	exit(0);
}
Exemplo n.º 20
0
int main()
{
    pid_t pid;
    pid_t wait_pid;
    int status;
    char *argv[] = { "Delay", "50", NULL };
    char *envp[] = { NULL };

    wait_pid = waitpid(666, NULL, 0);
    TEST(wait_pid == -1);
    TEST(errno == ECHILD);
    
    pid = vfork();
    if((int) pid > 0)
    {
	printf("Created child with pid %d\n", (int) pid);
	printf("Waiting for child with pid %d to exit.\n", (int) pid);
	wait_pid = waitpid(pid, &status, 0);
	TEST((wait_pid == pid));
	printf("Child %d exited with exit status %d\n", (int) wait_pid, status);
	TEST((status == EXIT_STATUS));
    }
    else if(pid == 0)
    {
	printf("Exiting with status %d\n", EXIT_STATUS);
	_exit(EXIT_STATUS);
    }
    else
    {
	TEST(0);
    }
    
    pid = vfork();
    if((int) pid > 0)
    {
	printf("Created child with pid %d\n", (int) pid);
	printf("Waiting for any child to exit.\n");
	wait_pid = waitpid(-1, &status, 0);
	TEST((wait_pid == pid));
	printf("Child %d exited with exit status %d\n", (int) wait_pid, status);
	TEST((status == EXIT_STATUS));
    }
    else if(pid == 0)
    {
	printf("Exiting with status %d\n", EXIT_STATUS);
	_exit(EXIT_STATUS);
    }
    else
    {
	TEST(0);
    }
    
    pid = vfork();
    if((int) pid > 0)
    {
	printf("Created child with pid %d\n", (int) pid);
	printf("Waiting for any child to exit without hang.\n");
	wait_pid = waitpid(-1, &status, WNOHANG);
	if(wait_pid == 0) 
	    wait_pid = waitpid(-1, &status, 0);
	TEST((wait_pid == pid));
	printf("Child %d exited with exit status %d\n", (int) wait_pid, status);
	TEST((status == EXIT_STATUS));
    }
    else if(pid == 0)
    {
	printf("Exiting with status %d\n", EXIT_STATUS);
	_exit(EXIT_STATUS);
    }
    else
    {
	TEST(0);
    }

    pid = vfork();
    if((int) pid > 0)
    {
	printf("Created child with pid %d\n", (int) pid);
	printf("Waiting for any child to exit without hang.\n");
	wait_pid = waitpid(-1, &status, WNOHANG);
	TEST((wait_pid == 0));
	printf("Child didn't exit yet\n");
	wait_pid = waitpid(-1, &status, 0);
	TEST((wait_pid == pid));
	printf("Child %d exited with exit status %d\n", (int) wait_pid, status);
	TEST((status == 0));

    }
    else if(pid == 0)
    {
	execve("C:Delay", argv, envp);
	_exit(-1);
    }
    else
    {
	TEST(0);
    }
}
Exemplo n.º 21
0
void Subprocess::spawnInternal(
    std::unique_ptr<const char*[]> argv,
    const char* executable,
    Options& options,
    const std::vector<std::string>* env,
    int errFd) {
  // Parent work, pre-fork: create pipes
  std::vector<int> childFds;
  // Close all of the childFds as we leave this scope
  SCOPE_EXIT {
    // These are only pipes, closing them shouldn't fail
    for (int cfd : childFds) {
      CHECK_ERR(::close(cfd));
    }
  };

  int r;
  for (auto& p : options.fdActions_) {
    if (p.second == PIPE_IN || p.second == PIPE_OUT) {
      int fds[2];
      r = ::pipe(fds);
      checkUnixError(r, "pipe");
      PipeInfo pinfo;
      pinfo.direction = p.second;
      int cfd;
      if (p.second == PIPE_IN) {
        // Child gets reading end
        pinfo.parentFd = fds[1];
        cfd = fds[0];
      } else {
        pinfo.parentFd = fds[0];
        cfd = fds[1];
      }
      p.second = cfd;  // ensure it gets dup2()ed
      pinfo.childFd = p.first;
      childFds.push_back(cfd);
      pipes_.push_back(pinfo);
    }
  }

  // This should already be sorted, as options.fdActions_ is
  DCHECK(std::is_sorted(pipes_.begin(), pipes_.end()));

  // Note that the const casts below are legit, per
  // http://pubs.opengroup.org/onlinepubs/009695399/functions/exec.html

  char** argVec = const_cast<char**>(argv.get());

  // Set up environment
  std::unique_ptr<const char*[]> envHolder;
  char** envVec;
  if (env) {
    envHolder = cloneStrings(*env);
    envVec = const_cast<char**>(envHolder.get());
  } else {
    envVec = environ;
  }

  // Block all signals around vfork; see http://ewontfix.com/7/.
  //
  // As the child may run in the same address space as the parent until
  // the actual execve() system call, any (custom) signal handlers that
  // the parent has might alter parent's memory if invoked in the child,
  // with undefined results.  So we block all signals in the parent before
  // vfork(), which will cause them to be blocked in the child as well (we
  // rely on the fact that Linux, just like all sane implementations, only
  // clones the calling thread).  Then, in the child, we reset all signals
  // to their default dispositions (while still blocked), and unblock them
  // (so the exec()ed process inherits the parent's signal mask)
  //
  // The parent also unblocks all signals as soon as vfork() returns.
  sigset_t allBlocked;
  r = sigfillset(&allBlocked);
  checkUnixError(r, "sigfillset");
  sigset_t oldSignals;

  r = pthread_sigmask(SIG_SETMASK, &allBlocked, &oldSignals);
  checkPosixError(r, "pthread_sigmask");
  SCOPE_EXIT {
    // Restore signal mask
    r = pthread_sigmask(SIG_SETMASK, &oldSignals, nullptr);
    CHECK_EQ(r, 0) << "pthread_sigmask: " << errnoStr(r);  // shouldn't fail
  };

  pid_t pid = vfork();
  if (pid == 0) {
    int errnoValue = prepareChild(options, &oldSignals);
    if (errnoValue != 0) {
      childError(errFd, kChildFailure, errnoValue);
    }

    errnoValue = runChild(executable, argVec, envVec, options);
    // If we get here, exec() failed.
    childError(errFd, kExecFailure, errnoValue);
  }
  // In parent.  Make sure vfork() succeeded.
  checkUnixError(pid, errno, "vfork");

  // Child is alive.  We have to be very careful about throwing after this
  // point.  We are inside the constructor, so if we throw the Subprocess
  // object will have never existed, and the destructor will never be called.
  //
  // We should only throw if we got an error via the errFd, and we know the
  // child has exited and can be immediately waited for.  In all other cases,
  // we have no way of cleaning up the child.
  pid_ = pid;
  returnCode_ = ProcessReturnCode(RV_RUNNING);
}
Exemplo n.º 22
0
pid_t
__archive_create_child(const char *path, int *child_stdin, int *child_stdout)
{
	pid_t child;
	int stdin_pipe[2], stdout_pipe[2], tmp;

	if (pipe(stdin_pipe) == -1)
		goto state_allocated;
	if (stdin_pipe[0] == 1 /* stdout */) {
		if ((tmp = dup(stdin_pipe[0])) == -1)
			goto stdin_opened;
		close(stdin_pipe[0]);
		stdin_pipe[0] = tmp;
	}
	if (pipe(stdout_pipe) == -1)
		goto stdin_opened;
	if (stdout_pipe[1] == 0 /* stdin */) {
		if ((tmp = dup(stdout_pipe[1])) == -1)
			goto stdout_opened;
		close(stdout_pipe[1]);
		stdout_pipe[1] = tmp;
	}

#if HAVE_VFORK
	switch ((child = vfork())) {
#else
	switch ((child = fork())) {
#endif
	case -1:
		goto stdout_opened;
	case 0:
		close(stdin_pipe[1]);
		close(stdout_pipe[0]);
		if (dup2(stdin_pipe[0], 0 /* stdin */) == -1)
			_exit(254);
		if (stdin_pipe[0] != 0 /* stdin */)
			close(stdin_pipe[0]);
		if (dup2(stdout_pipe[1], 1 /* stdout */) == -1)
			_exit(254);
		if (stdout_pipe[1] != 1 /* stdout */)
			close(stdout_pipe[1]);
		execlp(path, path, (char *)NULL);
		_exit(254);
	default:
		close(stdin_pipe[0]);
		close(stdout_pipe[1]);

		*child_stdin = stdin_pipe[1];
		fcntl(*child_stdin, F_SETFL, O_NONBLOCK);
		*child_stdout = stdout_pipe[0];
		fcntl(*child_stdout, F_SETFL, O_NONBLOCK);
	}

	return child;

stdout_opened:
	close(stdout_pipe[0]);
	close(stdout_pipe[1]);
stdin_opened:
	close(stdin_pipe[0]);
	close(stdin_pipe[1]);
state_allocated:
	return -1;
}

void
__archive_check_child(int in, int out)
{
#if defined(HAVE_POLL)
	struct pollfd fds[2];
	int idx;

	idx = 0;
	if (in != -1) {
		fds[idx].fd = in;
		fds[idx].events = POLLOUT;
		++idx;
	}
	if (out != -1) {
		fds[idx].fd = out;
		fds[idx].events = POLLIN;
		++idx;
	}

	poll(fds, idx, -1); /* -1 == INFTIM, wait forever */
#elif defined(HAVE_SELECT)
	fd_set fds_in, fds_out, fds_error;

	FD_ZERO(&fds_in);
	FD_ZERO(&fds_out);
	FD_ZERO(&fds_error);
	if (out != -1) {
		FD_SET(out, &fds_in);
		FD_SET(out, &fds_error);
	}
	if (in != -1) {
		FD_SET(in, &fds_out);
		FD_SET(in, &fds_error);
	}
	select(in < out ? out + 1 : in + 1, &fds_in, &fds_out, &fds_error, NULL);
#else
	sleep(1);
#endif
}
Exemplo n.º 23
0
/* ARGSUSED */
int
util_pipefork(
  char * const *argv,		/* normal argv argument list */
  FILE **toCommand,	/* pointer to the sending stream */
  FILE **fromCommand,	/* pointer to the reading stream */
  int *pid)
{
#ifdef UNIX
    int forkpid, waitPid;
    int topipe[2], frompipe[2];
    char buffer[1024];
    int status;

    /* create the PIPES...
     * fildes[0] for reading from command
     * fildes[1] for writing to command
     */
    if (pipe(topipe)) return(0);
    if (pipe(frompipe)) return(0);

#ifdef __CYGWIN32__
    if ((forkpid = fork()) == 0) {
#else
    if ((forkpid = vfork()) == 0) {
#endif
	/* child here, connect the pipes */
	(void) dup2(topipe[0], fileno(stdin));
	(void) dup2(frompipe[1], fileno(stdout));

	(void) close(topipe[0]);
	(void) close(topipe[1]);
	(void) close(frompipe[0]);
	(void) close(frompipe[1]);

	(void) execvp(argv[0], argv);
	(void) sprintf(buffer, "util_pipefork: can not exec %s", argv[0]);
	perror(buffer);
	(void) _exit(1);
    }

    if (pid) {
        *pid = forkpid;
    }

#ifdef __CYGWIN32__
    waitPid = waitpid(-1, &status, WNOHANG);
#else
    waitPid = wait3(&status, WNOHANG, NULL);
#endif

    /* parent here, use slimey vfork() semantics to get return status */
    if (waitPid == forkpid && WIFEXITED(status)) {
	return 0;
    }
    if ((*toCommand = fdopen(topipe[1], "w")) == NULL) {
	return 0;
    }
    if ((*fromCommand = fdopen(frompipe[0], "r")) == NULL) {
	return 0;
    }
    (void) close(topipe[0]);
    (void) close(frompipe[1]);
    return 1;
#else
    (void) fprintf(stderr, 
	"util_pipefork: not implemented on your operating system\n");
    return 0;
#endif
}
Exemplo n.º 24
0
int koo_process::_open_process()
{
	std::string cmd = m_execname;
	if (!m_arguments.empty())
		cmd += " " + m_arguments;

#ifdef _WIN32
    STARTUPINFO si = {sizeof (si)};
    si.dwFlags = STARTF_USESHOWWINDOW;

    DWORD creationFlag = 0;
    if (m_create_new_window)
    {
		si.wShowWindow = SW_SHOWDEFAULT;
        creationFlag |= CREATE_NEW_CONSOLE;
    }
	else
	{
		//si.dwFlags |= STARTF_USESTDHANDLES;
	}
#ifdef _DEBUG
	std::cout << "DEBUG_INFO: begin to exec command: " << cmd << std::endl;
#endif
	bool result = CreateProcess(NULL, (LPSTR)cmd.c_str(), NULL, NULL, FALSE, creationFlag, NULL, m_workpath.empty() ? NULL : m_workpath.c_str(), &si, &m_proc_info);
    if (result)
    {
        return K_OK;
    }
    else
    {
		DWORD e = GetLastError();
        return K_ERR_PROCESS_OPEN_FAILURE;
    }
#else
    std::vector<std::string> arg_list;
    arg_list.push_back(m_execname);
    k_str_split(m_arguments, arg_list, " ");
    char* argv[64] = {0};

    for (int i = 0; i < arg_list.size(); i++)
    {
        argv[i] = (char*) arg_list[i].c_str();
    }
    __pid_t pid = vfork();
    if (pid < 0)
    {
	    std::cout << "fork error; failed to create process;";
        _exit(0);
    }
    else if (pid == 0)
    {
        chdir(m_workpath.c_str());
        execv(m_execname.c_str(), argv);
    }
    else
    {
        m_pid = pid;
	std::cout << "process: " << m_pid << " has been created...";
        return K_OK;
    }
#endif
    return K_ERR_Not_Supported;
}
Exemplo n.º 25
0
CGrapher::CGrapher(Parameters* param, char* title){
#ifndef WIN32
  int toFils[2];
  int toPere[2];
  int sonPid;
  this->valid=1;

  if(pipe(toFils)<0){
    perror("PipeComOpen: Creating pipes");
    this->valid=0;	
    return;
  }
  if(pipe(toPere)<0){
    perror("PipeComOpen: Creating pipes");
    this->valid=0;
    return;
  }
  switch((sonPid=vfork())){
    case -1:
      perror("PipeComOpen: fork failed");
      this->valid=0;
      break;
    case 0:
      /* --- here's the son --- */
      if(dup2(toFils[0], fileno(stdin))<0){
        perror("PipeComOpen(son): could not connect\n");
        this->valid=0;
        abort();
      }
      if(dup2(toPere[1], fileno(stdout))<0){
        perror("PipeComOpen(son): could not connect\n");
        this->valid=0;
        abort();
      }
      char* pPath;
      pPath = getenv("EZ_PATH");
      if(pPath != NULL){
        pPath = strcat(pPath, "easeagrapher/EaseaGrapher.jar");
      }
      else{
        pPath = (char*)"../../easeagrapher/EaseaGrapher.jar";
      }
      char *arg[4];
      arg[0] = (char*)"java";
      arg[1] = (char*)"-jar";
      arg[2] = pPath;
      arg[3] = (char*)0;
      if(execvp("java",arg)<0){
        perror("java not installed, please change plotStats parameter\n");
        abort();
        this->valid=0;
      }
      break;
    default	:
      if(this->valid){
        this->fWrit = (FILE *)fdopen(toFils[1],"w");
        this->fRead = (FILE *)fdopen(toPere[0],"r");
        this->pid = sonPid;
        fprintf(this->fWrit,"set term wxt persist\n");
        fprintf(this->fWrit,"set grid\n");
        fprintf(this->fWrit,"set xlabel	\"Number of Evaluations\"\n");
        fprintf(this->fWrit,"set ylabel \"Fitness\"\n");
        int nbEval = param->offspringPopulationSize*param->nbGen + param->parentPopulationSize;
        fprintf(this->fWrit,"set xrange[0:%d]\n",nbEval);
        fprintf(this->fWrit,"set max eval:%d\n",nbEval);
        fprintf(this->fWrit,"set title:%s\n",title);
        if(param->remoteIslandModel){
          fprintf(this->fWrit,"set island model\n");
          fprintf(this->fWrit,"set max generation:%d\n",param->nbGen);
        }
        fflush(this->fWrit);
      }
  }
#endif
}
Exemplo n.º 26
0
static int do_listen(void)
{
	struct sockaddr_rc sa;
	int sk, lm;

	if (type == MROUTER) {
		if (!cache.valid)
			return -1;

		if (create_connection(cache.dst, &cache.bdaddr, type) < 0) {
			syslog(LOG_ERR, "Cannot connect to mRouter device. %s(%d)",
								strerror(errno), errno);
			return -1;
		}
	}

	if (!channel)
		channel = DUN_DEFAULT_CHANNEL;

	if (use_sdp)
		dun_sdp_register(&src_addr, channel, type);

	if (type == MROUTER)
		syslog(LOG_INFO, "Waiting for mRouter callback on channel %d", channel);

	/* Create RFCOMM socket */
	sk = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
	if (sk < 0) {
		syslog(LOG_ERR, "Cannot create RFCOMM socket. %s(%d)",
				strerror(errno), errno);
		return -1;
	}

	sa.rc_family  = AF_BLUETOOTH;
	sa.rc_channel = channel;
	sa.rc_bdaddr  = src_addr;

	if (bind(sk, (struct sockaddr *) &sa, sizeof(sa))) {
		syslog(LOG_ERR, "Bind failed. %s(%d)", strerror(errno), errno);
		return -1;
	}

	/* Set link mode */
	lm = 0;
	if (master)
		lm |= RFCOMM_LM_MASTER;
	if (auth)
		lm |= RFCOMM_LM_AUTH;
	if (encrypt)
		lm |= RFCOMM_LM_ENCRYPT;
	if (secure)
		lm |= RFCOMM_LM_SECURE;

	if (lm && setsockopt(sk, SOL_RFCOMM, RFCOMM_LM, &lm, sizeof(lm)) < 0) {
		syslog(LOG_ERR, "Failed to set link mode. %s(%d)", strerror(errno), errno);
		return -1;
	}

	listen(sk, 10);

	while (!terminate) {
		socklen_t alen = sizeof(sa);
		int nsk;
		char ba[40];
		char ch[10];

		nsk = accept(sk, (struct sockaddr *) &sa, &alen);
		if (nsk < 0) {
			syslog(LOG_ERR, "Accept failed. %s(%d)", strerror(errno), errno);
			continue;
		}

		switch (vfork()) {
		case 0:
			break;
		case -1:
			syslog(LOG_ERR, "Fork failed. %s(%d)", strerror(errno), errno);
		default:
			close(nsk);
			if (type == MROUTER) {
				close(sk);
				terminate = 1;
			}
			continue;
		}

		close(sk);

		if (msdun && ms_dun(nsk, 1, msdun) < 0) {
			syslog(LOG_ERR, "MSDUN failed. %s(%d)", strerror(errno), errno);
			exit(0);
		}

		ba2str(&sa.rc_bdaddr, ba);
		sprintf(ch, "%d", channel);

		/* Setup environment */
		setenv("DUN_BDADDR",  ba, 1);
		setenv("DUN_CHANNEL", ch, 1);

		if (!dun_open_connection(nsk, pppd, pppd_opts, 0))
			syslog(LOG_INFO, "New connection from %s", ba);

		close(nsk);
		exit(0);
	}

	if (use_sdp)
		dun_sdp_unregister();
	return 0;
}
Exemplo n.º 27
0
int main(int argc, char **argv)
{
	char *dst = NULL, *src = NULL;
	struct sigaction sa;
	int mode = NONE;
	int opt;

	while ((opt=getopt_long(argc, argv, main_sopts, main_lopts, NULL)) != -1) {
		switch(opt) {
		case 'l':
			mode = SHOW;
			detach = 0;
			break;

		case 's':
			mode = LISTEN;
			break;

		case 'c':
			mode = CONNECT;
			dst  = strdup(optarg);
			break;

		case 'Q':
			mode = CONNECT;
			dst  = NULL;
			if (optarg)
				search_duration = atoi(optarg);
			break;

		case 'k':
			mode = KILL;
			detach = 0;
			dst  = strdup(optarg);
			break;

		case 'K':
			mode = KILL;
			detach = 0;
			dst  = NULL;
			break;

		case 'P':
			channel = atoi(optarg);
			break;

		case 'i':
			src = strdup(optarg);
			break;

		case 'D':
			use_sdp = 0;
			break;

		case 'A':
			auth = 1;
			break;

		case 'E':
			encrypt = 1;
			break;

		case 'S':
			secure = 1;
			break;

		case 'M':
			master = 1;
			break;

		case 'n':
			detach = 0;
			break;

		case 'p':
			if (optarg)
				persist = atoi(optarg);
			else
				persist = 5;
			break;

		case 'C':
			if (optarg)
				use_cache = atoi(optarg);
			else
				use_cache = 2;
			break;

		case 'd':
			pppd  = strdup(optarg);
			break;

		case 'X':
			if (optarg)
				msdun = atoi(optarg);
			else
				msdun = 10;
			break;

		case 'a':
			msdun = 10;
			type = ACTIVESYNC;
			break;

		case 'm':
			mode = LISTEN;
			dst  = strdup(optarg);
			type = MROUTER;
			break;

		case 'u':
			mode = LISTEN;
			type = DIALUP;
			break;

		case 'h':
		default:
			printf(main_help);
			exit(0);
		}
	}

	argc -= optind;
	argv += optind;

	/* The rest is pppd options */
	if (argc > 0) {
		for (opt = 3; argc && opt < DUN_MAX_PPP_OPTS; argc--, opt++)
			pppd_opts[opt] = *argv++;
		pppd_opts[opt] = NULL;
	}

	io_init();

	if (dun_init())
		return -1;

	/* Check non daemon modes first */
	switch (mode) {
	case SHOW:
		do_show();
		return 0;

	case KILL:
		do_kill(dst);
		return 0;

	case NONE:
		printf(main_help);
		return 0;
	}

	/* Initialize signals */
	memset(&sa, 0, sizeof(sa));
	sa.sa_flags   = SA_NOCLDSTOP;
	sa.sa_handler = SIG_IGN;
	sigaction(SIGCHLD, &sa, NULL);
	sigaction(SIGPIPE, &sa, NULL);

	sa.sa_handler = sig_term;
	sigaction(SIGTERM, &sa, NULL);
	sigaction(SIGINT,  &sa, NULL);

	sa.sa_handler = sig_hup;
	sigaction(SIGHUP, &sa, NULL);

	if (detach) {
		int fd;

		if (vfork()) exit(0);

		/* Direct stdin,stdout,stderr to '/dev/null' */
		fd = open("/dev/null", O_RDWR);
		dup2(fd, 0); dup2(fd, 1); dup2(fd, 2);
		close(fd);

		setsid();
		chdir("/");
	}

	openlog("dund", LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_DAEMON);
	syslog(LOG_INFO, "Bluetooth DUN daemon version %s", VERSION);

	if (src) {
		src_dev = hci_devid(src);
		if (src_dev < 0 || hci_devba(src_dev, &src_addr) < 0) {
			syslog(LOG_ERR, "Invalid source. %s(%d)", strerror(errno), errno);
			return -1;
		}
	}

	if (dst) {
		strncpy(cache.dst, dst, sizeof(cache.dst) - 1);
		str2ba(dst, &cache.bdaddr);

		/* Disable cache invalidation */
		use_cache = cache.valid = ~0;
	}

	switch (mode) {
	case CONNECT:
		do_connect();
		break;

	case LISTEN:
		do_listen();
		break;
	}

	return 0;
}
Exemplo n.º 28
0
int setup_vlan(char *name)
{
	char *index;
	char *eth;
	char *cpy;
	char *state;
	char *argv[5];
	int argc = 0;
	int pid;
	int status;

	cpy = strdup(name);

	if (!cpy) {
		return -1;
	}

	eth = strtok_r(cpy, ".", &state);

	if (!eth) {
		return -1;
	}

	index = strtok_r(NULL, ".", &state);

	if (!index) {
		return -1;
	}

	bzero(argv, sizeof(argv));

	argv[argc++] = "vconfig";
	argv[argc++] = "add";
	argv[argc++] = eth;
	argv[argc++] = index;
	argv[argc] = NULL;

#ifdef __uClinux__
	if ((pid = vfork()) == 0) {
#else
	if ((pid = fork()) == 0) {
#endif
		if (execvp(argv[0], argv) < 0) {
#ifdef __uClinux__
			_exit(1);
#else
			exit(1);
#endif
		}
	} else if (pid < 0) {
		fprintf(stderr, "Couldn't fork\n");
		exit(1);
	}

	if (waitpid(pid, &status, 0) < 0) {
		fprintf(stderr, "Error waiting for vconfig - %m\n");
		return -1;
	}

	if (WEXITSTATUS(status) != 0) {
		return -1;
	}

	return 0;
}
Exemplo n.º 29
0
static BOOL chat_with_program(char *passwordprogram,char *name,char *chatsequence, BOOL as_root)
{
  char *slavedev;
  int master;
  pid_t pid, wpid;
  int wstat;
  BOOL chstat = False;    

  /* allocate a pseudo-terminal device */
  if ((master = findpty (&slavedev)) < 0) {
    DEBUG(3,("Cannot Allocate pty for password change: %s\n",name));
    return(False);
  }

  /*
   * We need to temporarily stop CatchChild from eating
   * SIGCLD signals as it also eats the exit status code. JRA.
   */

  CatchChildLeaveStatus();

#ifdef __uClinux__
  /* Hmmm, need to check this one further... */
  DEBUG(0,("%s(%d): vfork()ing\n",__FILE__,__LINE__));
  if ((pid = vfork()) < 0) {
#else
  if ((pid = fork()) < 0) {
#endif
    DEBUG(3,("Cannot fork() child for password change: %s\n",name));
    close(master);
    CatchChild();
    return(False);
  }

  /* we now have a pty */
  if (pid > 0){			/* This is the parent process */
    if ((chstat = talktochild(master, chatsequence)) == False) {
      DEBUG(3,("Child failed to change password: %s\n",name));
      kill(pid, SIGKILL); /* be sure to end this process */
    }

	while((wpid = sys_waitpid(pid, &wstat, 0)) < 0) {
      if(errno == EINTR) {
        errno = 0;
        continue;
      }
	  break;
    }

    if (wpid < 0) {
      DEBUG(3,("The process is no longer waiting!\n\n"));
      close(master);
      CatchChild();
      return(False);
    }

    /*
     * Go back to ignoring children.
     */
    CatchChild();

    close(master);

    if (pid != wpid) {
      DEBUG(3,("We were waiting for the wrong process ID\n"));	
      return(False);
    }
    if (WIFEXITED(wstat) == 0) {
      DEBUG(3,("The process exited while we were waiting\n"));
      return(False);
    }
    if (WEXITSTATUS(wstat) != 0) {
      DEBUG(3,("The status of the process exiting was %d\n", wstat));
      return(False);
    }
    
  } else {
    /* CHILD */

    /*
     * Lose any oplock capabilities.
     */
    set_process_capability(KERNEL_OPLOCK_CAPABILITY, False);
    set_inherited_process_capability(KERNEL_OPLOCK_CAPABILITY, False);

    /* make sure it doesn't freeze */
    alarm(20);

    if (as_root)
      become_root(False);
    DEBUG(3,("Dochild for user %s (uid=%d,gid=%d)\n",name,(int)getuid(),(int)getgid()));
    chstat = dochild(master, slavedev, name, passwordprogram, as_root);

	/*
	 * The child should never return from dochild() ....
	 */

	DEBUG(0,("chat_with_program: Error: dochild() returned %d\n", chstat ));
	exit(1);
  }

  if (chstat)
    DEBUG(3,("Password change %ssuccessful for user %s\n", (chstat?"":"un"), name));
  return (chstat);
}


BOOL chgpasswd(char *name,char *oldpass,char *newpass, BOOL as_root)
{
  pstring passwordprogram;
  pstring chatsequence;
  size_t i;
  size_t len;

  strlower(name); 
  DEBUG(3,("Password change for user: %s\n",name));

#if DEBUG_PASSWORD
  DEBUG(100,("Passwords: old=%s new=%s\n",oldpass,newpass)); 
#endif

  /* Take the passed information and test it for minimum criteria */
  /* Minimum password length */
  if (strlen(newpass) < lp_min_passwd_length()) /* too short, must be at least MINPASSWDLENGTH */ 
    {
      DEBUG(0,("Password Change: user %s, New password is shorter than minimum password length = %d\n",
            name, lp_min_passwd_length()));
      return (False);		/* inform the user */
    }
  
  /* Password is same as old password */
  if (strcmp(oldpass,newpass) == 0) /* don't allow same password */
    {
      DEBUG(2,("Password Change: %s, New password is same as old\n",name)); /* log the attempt */
      return (False);		/* inform the user */
    }

  pstrcpy(passwordprogram,lp_passwd_program());
  pstrcpy(chatsequence,lp_passwd_chat());

  if (!*chatsequence) {
    DEBUG(2,("Null chat sequence - no password changing\n"));
    return(False);
  }

  if (!*passwordprogram) {
    DEBUG(2,("Null password program - no password changing\n"));
    return(False);
  }

  /* 
   * Check the old and new passwords don't contain any control
   * characters.
   */

  len = strlen(oldpass); 
  for(i = 0; i < len; i++) {
    if (iscntrl((int)oldpass[i])) {
      DEBUG(0,("chat_with_program: oldpass contains control characters (disallowed).\n"));
      return False;
    }
  }

  len = strlen(newpass);
  for(i = 0; i < len; i++) {
    if (iscntrl((int)newpass[i])) {
      DEBUG(0,("chat_with_program: newpass contains control characters (disallowed).\n"));
      return False;
    }
  }

  pstring_sub(passwordprogram,"%u",name);
  /* note that we do NOT substitute the %o and %n in the password program
     as this would open up a security hole where the user could use
     a new password containing shell escape characters */

  pstring_sub(chatsequence,"%u",name);
  all_string_sub(chatsequence,"%o",oldpass,sizeof(pstring));
  all_string_sub(chatsequence,"%n",newpass,sizeof(pstring));
  return(chat_with_program(passwordprogram,name,chatsequence, as_root));
}
Exemplo n.º 30
0
int
main(int argc, char *argv[])
{
	FILE *fp;
	struct stat sb;
	size_t fplen, fptlen, len;
	off_t offset;
	int ch, debug, i, pdes[2], pid, status;
	char *addrp, *domain, *p, *t;
	char *from_path, *from_sys, *from_user;
	char *args[100], buf[2048], lbuf[2048];

#ifdef lint
	fplen = fptlen = 0;
	addrp = NULL;
#endif

	debug = 0;
	domain = "UUCP";		/* Default "domain". */
	while ((ch = getopt(argc, argv, "D:T")) != -1)
		switch (ch) {
		case 'T':
			debug = 1;
			break;
		case 'D':
			domain = optarg;
			break;
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if (argc < 1)
		usage();

	from_path = from_sys = from_user = NULL;
	for (offset = 0;;) {

		/* Get and nul-terminate the line. */
		if (fgets(lbuf, sizeof(lbuf), stdin) == NULL)
			exit (EX_DATAERR);
		if ((p = strchr(lbuf, '\n')) == NULL)
			err(EX_DATAERR, "line too long");
		*p = '\0';

		/* Parse lines until reach a non-"From" line. */
		if (!strncmp(lbuf, "From ", 5))
			addrp = lbuf + 5;
		else if (!strncmp(lbuf, ">From ", 6))
			addrp = lbuf + 6;
		else if (offset == 0)
			err(EX_DATAERR,
			    "missing or empty From line: %s", lbuf);
		else {
			*p = '\n';
			break;
		}

		if (*addrp == '\0')
			err(EX_DATAERR, "corrupted From line: %s", lbuf);

		/* Use the "remote from" if it exists. */
		for (p = addrp; (p = strchr(p + 1, 'r')) != NULL;)
			if (!strncmp(p, "remote from ", 12)) {
				for (t = p += 12; *t && !isspace(*t); ++t);
				*t = '\0';
				if (debug)
					(void)fprintf(stderr,
					    "remote from: %s\n", p);
				break;
			}

		/* Else use the string up to the last bang. */
		if (p == NULL) {
			if (*addrp == '!')
				err(EX_DATAERR,
				    "bang starts address: %s", addrp);
			else if ((t = strrchr(addrp, '!')) != NULL) {
				*t = '\0';
				p = addrp;
				addrp = t + 1;
				if (*addrp == '\0')
					err(EX_DATAERR,
					    "corrupted From line: %s", lbuf);
				if (debug)
					(void)fprintf(stderr, "bang: %s\n", p);
			}
		}

		/* 'p' now points to any system string from this line. */
		if (p != NULL) {
			/* Nul terminate it as necessary. */
			for (t = p; *t && !isspace(*t); ++t);
			*t = '\0';

			/* If the first system, copy to the from_sys string. */
			if (from_sys == NULL) {
				if ((from_sys = strdup(p)) == NULL)
					err(EX_TEMPFAIL, NULL);
				if (debug)
					(void)fprintf(stderr,
					    "from_sys: %s\n", from_sys);
			}

			/* Concatenate to the path string. */
			len = t - p;
			if (from_path == NULL) {
				fplen = 0;
				if ((from_path = malloc(fptlen = 256)) == NULL)
					err(EX_TEMPFAIL, NULL);
			}
			if (fplen + len + 2 > fptlen) {
				size_t newfptlen = fptlen +
				    MAX(fplen + len + 2, 256);
				char *np;

				if ((np = realloc(from_path, newfptlen)) == NULL)
					err(EX_TEMPFAIL, NULL);
				from_path = np;
				fptlen = newfptlen;
			}
			memmove(from_path + fplen, p, len);
			fplen += len;
			from_path[fplen++] = '!';
			from_path[fplen] = '\0';
		}

		/* Save off from user's address; the last one wins. */
		for (p = addrp; *p && !isspace(*p); ++p);
		*p = '\0';
		if (*addrp == '\0')
			addrp = "<>";
		free(from_user);
		if ((from_user = strdup(addrp)) == NULL)
			err(EX_TEMPFAIL, NULL);

		if (debug) {
			if (from_path != NULL)
				(void)fprintf(stderr,
				    "from_path: %s\n", from_path);
			(void)fprintf(stderr, "from_user: %s\n", from_user);
		}

		if (offset != -1)
			offset = ftello(stdin);
	}

	i = 0;
	args[i++] = _PATH_SENDMAIL;	/* Build sendmail's argument list. */
	args[i++] = "-G";		/* Relay submission. */
	args[i++] = "-oee";		/* No errors, just status. */
	args[i++] = "-odi";		/* Deliver in foreground. */
	args[i++] = "-oi";		/* Ignore '.' on a line by itself. */

	/* set from system and protocol used */
#ifdef TAYLOR_ENV
	{
		char *uu_machine;
		uu_machine = getenv("UU_MACHINE");
		/* set by Taylor UUCP's uuxqt */
		if (uu_machine)
			from_sys = uu_machine;
	}
#endif
	if (from_sys == NULL)
		(void)snprintf(buf, sizeof(buf), "-p%s", domain);
	else if (strchr(from_sys, '.') == NULL)
		(void)snprintf(buf, sizeof(buf), "-p%s:%s.%s",
			domain, from_sys, domain);
	else
		(void)snprintf(buf, sizeof(buf), "-p%s:%s", domain, from_sys);
	if ((args[i++] = strdup(buf)) == NULL)
		err(EX_TEMPFAIL, NULL);

					/* Set name of ``from'' person. */
	(void)snprintf(buf, sizeof(buf), "-f%s%s",
	    from_path ? from_path : "", from_user);
	if ((args[i++] = strdup(buf)) == NULL)
		err(EX_TEMPFAIL, NULL);

	/*
	 * Don't copy arguments beginning with - as they will be
	 * passed to sendmail and could be interpreted as flags.
	 * To prevent confusion of sendmail wrap < and > around
	 * the address (helps to pass addrs like @gw1,@gw2:aa@bb)
	 */
	while (*argv) {
		if (**argv == '-')
			err(EX_USAGE, "dash precedes argument: %s", *argv);
		if (strchr(*argv, ',') == NULL || strchr(*argv, '<') != NULL)
			args[i++] = *argv;
		else {
			if (asprintf(&args[i++], "<%s>", *argv) == -1)
				err(EX_TEMPFAIL, "Cannot malloc");
		}
		argv++;
	}
	args[i] = 0;

	if (debug) {
		(void)fprintf(stderr, "sendmail arguments:\n");
		for (i = 0; args[i]; i++)
			(void)fprintf(stderr, "\t%s\n", args[i]);
	}

	/*
	 * If called with a regular file as standard input, seek to the right
	 * position in the file and just exec sendmail.  Could probably skip
	 * skip the stat, but it's not unreasonable to believe that a failed
	 * seek will cause future reads to fail.
	 */
	if (!fstat(STDIN_FILENO, &sb) && S_ISREG(sb.st_mode)) {
		if (lseek(STDIN_FILENO, offset, SEEK_SET) != offset)
			err(EX_TEMPFAIL, "stdin seek");
		execv(_PATH_SENDMAIL, args);
		err(EX_OSERR, "%s", _PATH_SENDMAIL);
	}

	if (pipe(pdes) < 0)
		err(EX_OSERR, NULL);

	switch (pid = vfork()) {
	case -1:				/* Err. */
		err(EX_OSERR, NULL);
	case 0:					/* Child. */
		if (pdes[0] != STDIN_FILENO) {
			(void)dup2(pdes[0], STDIN_FILENO);
			(void)close(pdes[0]);
		}
		(void)close(pdes[1]);
		execv(_PATH_SENDMAIL, args);
		_exit(127);
		/* NOTREACHED */
	}

	if ((fp = fdopen(pdes[1], "w")) == NULL)
		err(EX_OSERR, NULL);
	(void)close(pdes[0]);

	/* Copy the file down the pipe. */
	do {
		(void)fprintf(fp, "%s", lbuf);
	} while (fgets(lbuf, sizeof(lbuf), stdin) != NULL);

	if (ferror(stdin))
		err(EX_TEMPFAIL, "stdin");

	if (fclose(fp))
		err(EX_OSERR, NULL);

	if ((waitpid(pid, &status, 0)) == -1)
		err(EX_OSERR, "%s", _PATH_SENDMAIL);

	if (!WIFEXITED(status))
		err(EX_OSERR,
		    "%s: did not terminate normally", _PATH_SENDMAIL);

	if (WEXITSTATUS(status))
		err(status, "%s: terminated with %d (non-zero) status",
		    _PATH_SENDMAIL, WEXITSTATUS(status));
	exit(EX_OK);
}