void __start(void) { int argc; char *ro_args, *args, **argv; /* Clear BSS */ memset(edata, 0, end - edata); /* Define heap. */ setheap(end, (void *)(HIMEM - 0x1000)); ro_args = os_get_env(NULL, NULL); args = alloc(strlen(ro_args)+10); /* some spare extra */ strcpy(args, ro_args); argc = splitargs(args, 0, NULL); argv = alloc(argc * sizeof(*argv)); if (argv == NULL) panic("alloc of argv failed"); argc = splitargs(args, 1, argv); /* start real main() */ os_exit(NULL, main(argc, argv)); }
static int nsfile(char *fn, Biobuf *b, AuthRpc *rpc) { int argc; char *cmd, *argv[NARG+1], argbuf[MAXARG*NARG]; int cdroot; cdroot = 0; atnotify(catch, 1); while(cmd = Brdline(b, '\n')){ cmd[Blinelen(b)-1] = '\0'; while(*cmd==' ' || *cmd=='\t') cmd++; if(*cmd == '#') continue; argc = splitargs(cmd, argv, argbuf, NARG); if(argc) cdroot |= nsop(fn, argc, argv, rpc); } atnotify(catch, 0); return cdroot; }
/** * Launches a program and wait for it to finish. * * If uid is not UID_MASTER, the standard input and output will be redirected * to /dev/null. * * If uid is UID_MASTER and the program exits with non-zero status (or an error * occurs during the setup of the child process), the vm will be shut down. * * The umask also depends on uid. For UID_MASTER, files will be private by * default. For other users, files will be public by default. * * @param cmd the command to execute (will be modified) * @param uid the user id that will execute the program */ static void launch(char *cmd, uid_t uid) { char *argv[CONTROL_MAXARGS+1]; pid_t pid; int status; splitargs(cmd, argv); pid = fork(); if(pid < 0) { // Error die("fork", NULL); } else if(pid > 0) { // Parent wait(&status); if(uid == UID_MASTER && (!WIFEXITED(status) || WEXITSTATUS(status) != 0)) shutdown(); } else { // Child childcheck("close /task/control", fclose(fcontrol)); if(uid == UID_MASTER) { childcheck("set gid", setgid(0)); childcheck("set uid", setuid(uid)); // Make new files private to master by default umask(077); } else { childcheck("set gid", setgid(2)); childcheck("set uid", setuid(uid)); // Make new files public by default umask(000); // Deny access to input and output if(freopen("/dev/null", "r", stdin) == NULL || freopen("/dev/null", "w", stdout) == NULL || freopen("/dev/null", "w", stderr) == NULL) childcheck("reopen std streams", 1); } execve(argv[0], argv, ENVIRONMENT); childcheck("execve", 1); // if we arrive here, there was an error launching cmd. } }
int main(int argc, char **argv) { int c; char fname[MAX_IMAGE_FNAME]; const char *software_select = NULL; int opt_i = 0; int opt_e = 0; int opt_s = 0; int opt_w = 0; struct hw_type hwrev; char image_url[MAX_URL]; int opt_d = 0; RECOVERY_STATUS result; #ifdef CONFIG_WEBSERVER char weboptions[1024]; char **av = NULL; int ac = 0; #endif memset(&flashdesc, 0, sizeof(flashdesc)); memset(main_options, 0, sizeof(main_options)); strcpy(main_options, "vhi:se:"); #ifdef CONFIG_MTD strcat(main_options, "b:"); #endif #ifdef CONFIG_DOWNLOAD strcat(main_options, "d:"); #endif #ifdef CONFIG_WEBSERVER strcat(main_options, "w:"); #endif memset(fname, 0, sizeof(fname)); printf("%s\n", BANNER); printf("Licensed under GPLv2. See source distribution for detailed " "copyright notices.\n\n"); /* Process options with getopt */ while ((c = getopt_long(argc, argv, main_options, long_options, NULL)) != EOF) { switch (c) { case 'v': verbose++; break; #ifdef CONFIG_MTD case 'b': mtd_set_ubiblacklist(optarg); break; #endif case 'i': strncpy(fname, optarg, sizeof(fname)); opt_i = 1; break; case 'e': software_select = optarg; opt_e = 1; break; case 'h': usage(argv[0]); exit(0); break; #ifdef CONFIG_DOWNLOAD case 'd': strncpy(image_url, optarg, sizeof(image_url)); opt_d = 1; break; #endif case 's': /* run as server */ opt_s = 1; break; #ifdef CONFIG_WEBSERVER case 'w': snprintf(weboptions, sizeof(weboptions), "%s %s", argv[0], optarg); av = splitargs(weboptions, &ac); opt_w = 1; break; #endif default: usage(argv[0]); exit(1); break; } } swupdate_init(&swcfg); lua_handlers_init(); if(!get_hw_revision(&hwrev)) printf("Running on %s Revision %s\n", hwrev.boardname, hwrev.revision); print_registered_handlers(); notify_init(); if (opt_e) { if (parse_image_selector(software_select, &swcfg)) { fprintf(stderr, "Incorrect select option format\n"); exit(1); } fprintf(stderr, "software set: %s mode: %s\n", swcfg.software_set, swcfg.running_mode); } network_daemon = start_thread(network_initializer, &swcfg); if (opt_i) { install_from_file(fname); cleanup_files(&swcfg); notify(SUCCESS, 0, 0); } if (opt_d) { result =download_from_url(image_url); if (result == SUCCESS) exit(0); else exit(1); } /* Start embedded web server */ #if defined(CONFIG_MONGOOSE) if (opt_w) start_mongoose(ac, av); #endif if (opt_w || opt_s) pthread_join(network_daemon, NULL); }