예제 #1
0
int main(int argc, char **argv)
{
	if(isArgumentForShowingVersion(argv)) showVersionAndExit();
	char	   *buf;
	char       *bufCopy;
	pid_t	   pid = getpid();
	pid_t      backgroundJob;
	int		   status = 0;
	char       *prompt = getPrompt();
	int  	   bg;
	int        jobNumber = 1;
	int counts;
	int jumpSet = 0;
	char *arguments[2048];
	initialize();
	printf("\n");
	setPrompt(prompt);
	while ((buf = readline(prompt))) {
		if(strlen(buf) != 0) {
			bufCopy = buddy_malloc((strlen(buf)+1)*sizeof(char));
			strcpy(bufCopy, buf);
			add_history(bufCopy);
		}
		else
		{
			 printFinishedJobs(jobList);
			 free(buf);
			 continue;
		}
		free(buf);
		if(isCommandNotEmpty(bufCopy)) bg = isBackgroundCommand(bufCopy);
		getArgument(arguments, bufCopy, &counts);
		if(isExitCommand(bufCopy)){
			buddy_free(bufCopy);
			freeList(jobList);
			if(arguments != NULL){
				freeArguments(counts, arguments, NULL);
			}
			exit(0);
		}
		if(isCdCommand(bufCopy, arguments)){
			changeDir(arguments);
		    freeArguments(counts, arguments, bufCopy);		
		}
		else if(isJobsCommand(bufCopy)) {
			printList(jobList);
			freeArguments(counts, arguments, bufCopy);
		}
		else if(isFgCommand(bufCopy, arguments)){			
			fg(arguments, jobList, counts, bufCopy);
		}
		else if(isBgCommand(bufCopy, arguments)){
			bgS(arguments, jobList, counts, bufCopy);
		}
		else if (isCommandNotEmpty(bufCopy)) 
		{
			if(bg == 1)
			{
				backgroundJob = fork();
				if(backgroundJob == 0) {
					ignoreSignals();
					runCommand(arguments, bufCopy);
				}
				else{
					NodePtr n = createAndSetNode(&jobNumber, backgroundJob, bufCopy, bg);
					recordCommand(n, jobNumber, bg);
					freeArguments(counts, arguments, bufCopy);
				}
			}
			else
			{		
				pid = fork();
				if(pid == 0){
					runCommand(arguments, bufCopy);
				}
				else {
					NodePtr n = createAndSetNode(&jobNumber, pid, bufCopy, bg);
					ignoreSignals();
					if((waitpid(pid,&status,WUNTRACED))<0) err_sys("waitpid error");
					freeArguments(counts, arguments, bufCopy);
					restoreSignalsAndDetermineStatus(status, jobList, n);
				}
			}
		}
		else
		{
			freeArguments(counts, arguments, bufCopy);
		}
		if(jumpSet == 0){
			sigsetjmp(env, 1);
			jumpSet = 1;
		}
		continue;
	}
	if(buf == NULL) printf("\n");
	exit(0);
}
예제 #2
0
파일: littler.c 프로젝트: mdavy86/littler
int main(int argc, char **argv){

    /* R embedded arguments, and optional arguments to be picked via cmdline switches */
    char *R_argv[] = {(char*)programName, "--gui=none", "--no-restore", "--no-save", "--no-readline", "--silent", "", ""};
    char *R_argv_opt[] = {"--vanilla", "--slave"};
    int R_argc = (sizeof(R_argv) - sizeof(R_argv_opt) ) / sizeof(R_argv[0]);
    int i, nargv, c, optpos=0, vanilla=0, quick=0, interactive=0, datastdin=0;
    char *evalstr = NULL;
    char *libstr = NULL;
    char *libpathstr = NULL;
    SEXP s_argv;
    structRstart Rst;
    char *datastdincmd = "X <- read.csv(file(\"stdin\"), stringsAsFactors=FALSE);";

    static struct option optargs[] = {
        {"help",         no_argument,       NULL, 'h'}, 
        {"usage",        no_argument,       0,    0},
        {"version",      no_argument,       NULL, 'V'},
        {"vanilla",      no_argument,       NULL, 'v'},
        {"eval",         required_argument, NULL, 'e'},
        {"packages",     required_argument, NULL, 'l'},
        {"verbose",      no_argument,       NULL, 'p'},
        {"rtemp",        no_argument,       NULL, 't'},
        {"quick",        no_argument,       NULL, 'q'},
        {"interactive",  no_argument,       NULL, 'i'},
        {"datastdin",    no_argument,       NULL, 'd'},
        {"libpath",      required_argument, NULL, 'L'},
        {0, 0, 0, 0}
    };
    while ((c = getopt_long(argc, argv, "+hVve:npl:L:tqid", optargs, &optpos)) != -1) {
        switch (c) {	
        case 0:				/* numeric 0 is code for a long option */
            /* printf ("Got option %s %d", optargs[optpos].name, optpos);*/
            switch (optpos) {		/* so switch on the position in the optargs struct */
					/* cases 0, 2, and 3 can't happen as they are covered by the '-h', */ 
					/* '-V', and '-v' equivalences */
            case 1:
                showUsageAndExit();
                break;				/* never reached */
            case 5:
                verbose = 1;
                break;
            default:
                printf("Uncovered option position '%d'. Try `%s --help' for help\n", 
                       optpos, programName);
                exit(-1);
            }
            break;
        case 'h':			/* -h is the sole short option, cf getopt_long() call */
            showHelpAndExit();
            break;  			/* never reached */
        case 'e':
            evalstr = optarg;
            break;
        case 'l':
            libstr = optarg;
            break;
        case 'v':	
            vanilla=1;
            break;
        case 'p':	
            verbose=1;
            break;
        case 'V':
            showVersionAndExit();
            break;  			/* never reached */
        case 't':
            perSessionTempDir=TRUE;
            break;
        case 'q':
            quick=1;
            break;
        case 'i':
            interactive=1;
            break;
        case 'd':
            datastdin=1;
            break;
        case 'L':
            libpathstr = optarg;
            break;
        default:
            printf("Unknown option '%c'. Try `%s --help' for help\n",(char)c, programName);
            exit(-1);
        }
    }
    if (vanilla) {
        R_argv[R_argc++] = R_argv_opt[0];
    }
    if (!verbose) {
        R_argv[R_argc++] = R_argv_opt[1];
    }

#ifdef DEBUG
    printf("R_argc %d sizeof(R_argv) \n", R_argc, sizeof(R_argv));
    for (i=0; i<7; i++) {
        printf("R_argv[%d] = %s\n", i, R_argv[i]);
    }
    printf("optind %d, argc %d\n", optind, argc);
    for (i=0; i<argc; i++) {
        printf("argv[%d] = %s\n", i, argv[i]);
    }
#endif

    /* Now, argv[optind] could be a file we want to source -- if we're
     * in the 'shebang' case -- or it could be an expression from stdin.
     * So call stat(1) on it, and if its a file we will treat it as such.
     */
    struct stat sbuf;
    if (optind < argc && evalstr==NULL) { 
        if ((strcmp(argv[optind],"-") != 0) && (stat(argv[optind],&sbuf) != 0)) {
            perror(argv[optind]);
            exit(1);
        }
    }

    /* Setenv R_* env vars: insert or replace into environment.  */
    for (i = 0; R_VARS[i] != NULL; i+= 2){
        if (setenv(R_VARS[i],R_VARS[i+1],1) != 0){
            perror("ERROR: couldn't set/replace an R environment variable");
            exit(1);
        }
    }

    /* We don't require() default packages upon startup; rather, we
     * set up delayedAssign's instead. see autoloads().
     */
    if (setenv("R_DEFAULT_PACKAGES","NULL",1) != 0) {
        perror("ERROR: couldn't set/replace R_DEFAULT_PACKAGES");
        exit(1);
    }

    R_SignalHandlers = 0;			/* Don't let R set up its own signal handlers */

#ifdef CSTACK_DEFNS
    R_CStackLimit = (uintptr_t)-1;		/* Don't do any stack checking, see R Exts, '8.1.5 Threading issues' */
#endif

    littler_InitTempDir();			/* Set up temporary directoy */
    
    Rf_initEmbeddedR(R_argc, R_argv);	/* Initialize the embedded R interpreter */

    R_ReplDLLinit(); 			/* this is to populate the repl console buffers */

    if (!interactive) {			/* new in littler 0.1.3 */
        R_DefParams(&Rst);
        Rst.R_Interactive = 0;		/* sets interactive() to eval to false */
        R_SetParams(&Rst);
    }

    ptr_R_CleanUp = littler_CleanUp; 	/* R Exts, '8.1.2 Setting R callbacks */

    if (quick != 1) {			/* Unless user chose not to load libraries */
        autoloads();			/* Force all default package to be dynamically required */
    }

    /* Place any argv arguments into argv vector in Global Environment */
    /* if we have an evalstr supplied from -e|--eval, correct for it */
    if ((argc - optind - (evalstr==NULL)) >= 1) {
        int offset = (evalstr==NULL) + (strcmp(argv[optind],"-") == 0);
        /* Build string vector */
        nargv = argc - optind - offset;
        PROTECT(s_argv = allocVector(STRSXP,nargv));
        for (i = 0; i <nargv; i++){
            STRING_PTR(s_argv)[i] = mkChar(argv[i+offset+optind]);
#ifdef DEBUG
            printf("Passing %s to R\n", argv[i+offset+optind]);
#endif
        }
        UNPROTECT(1);
        setVar(install("argv"),s_argv,R_GlobalEnv);
    } else {
        setVar(install("argv"),R_NilValue,R_GlobalEnv);
    }

    init_rand();				/* for tempfile() to work correctly */

    if (!vanilla) {
        FILE *fp;

        char rprofilesite[128]; 
        snprintf(rprofilesite, 110, "%s/etc/Rprofile.site", getenv("R_HOME"));
        if (fp = fopen(rprofilesite, "r")) {
            fclose(fp);             		/* don't actually need it */
#ifdef DEBUG
            printf("Sourcing %s\n", rprofilesite);
#endif
            source(rprofilesite);
        }

        char dotrprofile[128]; 
        snprintf(dotrprofile, 110, "%s/.Rprofile", getenv("HOME"));
        if (fp = fopen(dotrprofile, "r")) {
            fclose(fp);             		/* don't actually need it */
#ifdef DEBUG
            printf("Sourcing %s\n", dotrprofile);
#endif
            source(dotrprofile);
        }

        char *etclittler = "/etc/littler.r";	/* load /etc/litter.r if it exists */
        if (fp = fopen(etclittler, "r")) {
            fclose(fp);        			/* don't actually need it */
#ifdef DEBUG
            printf("Sourcing %s\n", etclittler);
#endif
            source(etclittler);
        }

        char dotlittler[128];			/* load ~/.litter.r if it exists */
        snprintf(dotlittler, 110, "%s/.littler.r", getenv("HOME"));
        if (fp = fopen(dotlittler, "r")) {
            fclose(fp);             		/* don't actually need it */
#ifdef DEBUG
            printf("Sourcing %s\n", dotlittler);
#endif
            source(dotlittler);
        }
    }

    if (libpathstr != NULL) {			/* if requested by user, set libPaths */
        char buf[128];
        membuf_t pb = init_membuf(512);
        snprintf(buf, 127 - 12 - strlen(libpathstr), ".libPaths(\"%s\");", libpathstr); 
        parse_eval(&pb, buf, 1);
        destroy_membuf(pb);
    }

    if (libstr != NULL) {			/* if requested by user, load libraries */
        char *ptr, *token, *strptr;
        char buf[128];
        
        ptr = token = libstr;
        membuf_t pb = init_membuf(512);
        while (token != NULL) {
            token = strtok_r(ptr, ",", &strptr);
            ptr = NULL; 			/* after initial call strtok expects NULL */
            if (token != NULL) {
                snprintf(buf, 127 - 27 - strlen(token), "suppressMessages(library(%s));", token); 
                parse_eval(&pb, buf, 1);
            }
        } 
        destroy_membuf(pb);
    }

    if (datastdin) {				/* if req. by user, read 'dat' from stdin */
        membuf_t pb = init_membuf(512);
        parse_eval(&pb, datastdincmd, 1);
        destroy_membuf(pb);
    }

    /* Now determine which R code to evaluate */
    int exit_val = 0;
    if (evalstr != NULL) {			
        /* we have a command line expression to evaluate */
        membuf_t pb = init_membuf(1024);
        exit_val = parse_eval(&pb, evalstr, 1);
        destroy_membuf(pb);
    } else if (optind < argc && (strcmp(argv[optind],"-") != 0)) {	
        /* call R function source(filename) */
        exit_val = source(argv[optind]);
    } else {
        /* Or read from stdin */
        membuf_t lb = init_membuf(1024);
        membuf_t pb = init_membuf(1024);
        int lineno = 1;
        while(readline_stdin(&lb)){
            exit_val = parse_eval(&pb,(char*)lb->buf,lineno++);
            if (exit_val) break;
        }
        destroy_membuf(lb);
        destroy_membuf(pb);
    }
    littler_CleanUp(SA_NOSAVE, exit_val, 0);
    return(0); /* not reached, but making -Wall happy */
}