/*! * Daemonize * * Fork, exit parent, setsid(), optionally chdir("/"), optionally close all fds * * returns -1 on failure, but you can't do much except exit in that case * since we may already have forked */ int daemonize(int nochdir, int noclose) { switch (fork()) { case 0: break; case -1: return -1; default: _exit(0); } if (setsid() < 0) return -1; switch (fork()) { case 0: break; case -1: return -1; default: _exit(0); } if (!nochdir) chdir("/"); if (!noclose) { closeall(0); open("/dev/null",O_RDWR); dup(0); dup(0); } return 0; }
static int ppp_load_kext(void) { int pid = fork(); if (pid < 0) { tun_error("fork for ppp kext: %s", strerror(errno)); return -1; } if (pid == 0) { closeall(); execle("/sbin/kextload", "kextload", PPP_KEXT_PATH, NULL, NULL); exit(1); } int status; while (waitpid(pid, &status, 0) < 0) { if (errno == EINTR) continue; tun_error("waitpid for ppp kext: %s", strerror(errno)); return -1; } if (WEXITSTATUS(status) != 0) { tun_error("could not load ppp kext \"%s\"", PPP_KEXT_PATH); return -1; } tun_noerror(); return 0; }
main() { register got; request(KBD|MOUSE|RCV|SEND); newlnsz=defont.height; init(); strzero(&snarfbuf); waitunix(&diagdone); /* when menu is loaded */ for(got=0; ; got=wait(MOUSE|KBD|RCV)){ if(P->state&RESHAPED){ rectf(&display, Drect, F_CLR); closeall(); init(); P->state&=~RESHAPED; } /* NOTE: cursor is OFF at all times... */ if((got&RCV) && rcv()){ curse(current->frame); (void)message(); curse(current->frame); } if((got&MOUSE) && bttn123() && ptinrect(mouse.xy, display.rect)){ curse(current->frame); buttonhit(mouse.xy, mouse.buttons); curse(current->frame); } if((got&KBD) && current) /* ...except in type */ type(current); /* manages cursor itself */ } }
/*ARGSUSED*/ int bootprog(char *bpath, char *bargs, boolean_t user_specified_filename) { boolean_t once = B_FALSE; systype = set_fstype(v2path, bpath); loop: /* * Beware: the following code may be executed twice, with different * bpath's if we discover a redirection file. */ if (verbosemode) { printf("device path '%s'\n", bpath); if (strcmp(bpath, v2path) != 0) printf("client path '%s'\n", v2path); } if (mountroot(bpath) != SUCCESS) prom_panic("Could not mount filesystem."); /* * kernname (default-name) might have changed if mountroot() called * boot_nfs_mountroot(), and it called set_default_filename(). */ if (!user_specified_filename) (void) strcpy(filename, kernname); if (verbosemode) printf("standalone = `%s', args = `%s'\n", filename, bargs); set_client_bootargs(filename, bargs); if (!once && (strcmp(systype, "ufs") == 0 || strcmp(systype, "hsfs") == 0)) { char redirect[OBP_MAXPATHLEN]; post_mountroot(filename, redirect); /* * If we return at all, it's because we discovered * a redirection file - the 'redirect' string now contains * the name of the disk slice we should be looking at. * * Unmount the filesystem, tweak the boot path and retry * the whole operation one more time. */ closeall(1); once = B_TRUE; redirect_boot_path(bpath, redirect); if (verbosemode) printf("%sboot: using '%s'\n", systype, bpath); goto loop; /*NOTREACHED*/ } return (0); }
/* Execute external script/program */ int notify_exec(char *cmd) { pid_t pid; int ret; pid = fork(); /* In case of fork is error. */ if (pid < 0) { log_message(LOG_INFO, "Failed fork process"); return -1; } /* In case of this is parent process */ if (pid) return 0; signal_handler_destroy(); closeall(0); open("/dev/null", O_RDWR); ret = dup(0); ret = dup(0); system_call(cmd); exit(0); }
void run(Node *a) /* execution of parse tree starts here */ { extern void stdinit(void); stdinit(); execute(a); closeall(); }
static int elf_exec(struct loaded_module *mp) { static struct bootinfo_v1 bootinfo_v1; struct module_metadata *md; Elf_Ehdr *hdr; int err; int flen; if ((md = mod_findmetadata(mp, MODINFOMD_ELFHDR)) == NULL) return(EFTYPE); /* XXX actually EFUCKUP */ hdr = (Elf_Ehdr *)&(md->md_data); /* XXX ffp_save does not appear to be used in the kernel.. */ bzero(&bootinfo_v1, sizeof(bootinfo_v1)); err = bi_load(&bootinfo_v1, &ffp_save, mp); if (err) return(err); /* * Fill in the bootinfo for the kernel. */ strncpy(bootinfo_v1.booted_kernel, mp->m_name, sizeof(bootinfo_v1.booted_kernel)); flen = prom_getenv(PROM_E_BOOTED_OSFLAGS, bootinfo_v1.boot_flags, sizeof(bootinfo_v1.boot_flags)); bootinfo_v1.hwrpb = (void *)HWRPB_ADDR; bootinfo_v1.hwrpbsize = ((struct rpb *)HWRPB_ADDR)->rpb_size; bootinfo_v1.cngetc = NULL; bootinfo_v1.cnputc = NULL; bootinfo_v1.cnpollc = NULL; /* * Append the boot command flags. */ if (mp->m_args != NULL && *mp->m_args != '\0') { const char *p = mp->m_args; do { if (*p == '-') { while (*++p != ' ' && *p != '\0') if (flen < sizeof(bootinfo_v1.boot_flags) - 1) bootinfo_v1.boot_flags[flen++] = *p; } else while (*p != ' ' && *p != '\0') p++; while (*p == ' ') p++; } while (*p != '\0'); bootinfo_v1.boot_flags[flen] = '\0'; } printf("Entering %s at 0x%lx...\n", mp->m_name, hdr->e_entry); closeall(); alpha_pal_imb(); (*(void (*)())hdr->e_entry)(ffp_save, ptbr_save, BOOTINFO_MAGIC, &bootinfo_v1, 1, 0); }
/** * popen2 - Open a bidirectional pipe to a process * @path: full path of executable to run * @to_child: return file descriptor for child stdin * @from_child: return file descriptor for child stdout * * Return -1 on error, pid of child process on success. */ pid_t popen2(const char *path, int *to_child, int *from_child, bool no_stderr) { int child_in[2], child_out[2]; pid_t pid; if (access(path, X_OK) < 0) return -1; if (pipe(child_in) < 0 || pipe(child_out) < 0) return -1; pid = fork(); if (pid < 0) return -1; if (pid == 0) { /* * child */ close(child_in[1]); close(child_out[0]); /* * Rationale: by making sure that fd > 2, dup(fd) <= 2, * a new copy is created, allowing to close the pipe end, * and with FD_CLOEXEC to off (on linux). */ if (fd_no_clobber_stdio(&child_in[0]) < 0 || dup2(child_in[0], STDIN_FILENO) != STDIN_FILENO || close(child_in[0]) < 0) _exit(127); if (fd_no_clobber_stdio(&child_out[1]) < 0 || dup2(child_out[1], STDOUT_FILENO) != STDOUT_FILENO || close(child_out[1]) < 0) _exit(127); if (no_stderr && dup_devnull(STDERR_FILENO) < 0) _exit(127); closeall(STDERR_FILENO + 1); if (execl(path, path, NULL) < 0) _exit(1); } /* * parent */ close(child_in[0]); close(child_out[1]); *to_child = child_in[1]; *from_child = child_out[0]; return pid; }
static void mydaemon(int nochdir, int noclose) { int pid, status, tempfd; if (pipe(pipefds) < 0) { printerr(1, "mydaemon: pipe() failed: errno %d (%s)\n", errno, strerror(errno)); exit(1); } if ((pid = fork ()) < 0) { printerr(1, "mydaemon: fork() failed: errno %d (%s)\n", errno, strerror(errno)); exit(1); } if (pid != 0) { /* * Parent. Wait for status from child. */ close(pipefds[1]); if (read(pipefds[0], &status, 1) != 1) exit(1); exit (0); } /* Child. */ close(pipefds[0]); setsid (); if (nochdir == 0) { if (chdir ("/") == -1) { printerr(1, "mydaemon: chdir() failed: errno %d (%s)\n", errno, strerror(errno)); exit(1); } } while (pipefds[1] <= 2) { pipefds[1] = dup(pipefds[1]); if (pipefds[1] < 0) { printerr(1, "mydaemon: dup() failed: errno %d (%s)\n", errno, strerror(errno)); exit(1); } } if (noclose == 0) { tempfd = open("/dev/null", O_RDWR); dup2(tempfd, 0); dup2(tempfd, 1); dup2(tempfd, 2); closeall(3); } return; }
int main(int argc, char **argv) { char s[10000]; int k,sum=0; int fd0; FILE *fd1; initialize(); if (argc < 3) { printf("Usage:\n\ncpfile -o fimage-source host-target\ncpfile host-source fimage-target\n"); exit(0); } if (strcmp(argv[1], "-o") == 0) { fd0 = syscall_open(argv[2],O_RDONLY,0); fd1 = fopen(argv[3],"wb"); if (fd0 < 0 || fd1 < 0) { printf("Error opening input/output files\n"); exit(0); } while ((k=syscall_read(fd0, s, 10000))>0) { fwrite(s,k,1,fd1); sum += k; } syscall_close(fd0); fclose(fd1); } else { fd0 = syscall_open(argv[2],O_WRONLY,0); fd1 = fopen(argv[1],"rb"); if (fd0 < 0 || fd1 < 0) { printf("Error opening input/output files\n"); exit(0); } while ((k=fread(s, 1, 10000, fd1))>0) { syscall_write(fd0,s,k); sum += k; } syscall_close(fd0); fclose(fd1); } closeall(); //printf("Image copied\n"); return 0; }
/* detach and go into background. * caller is responsible for umasks * * if nochdir == 0, will do a chdir to / * if noclose == 0, will close all FDs */ int daemon(int nochdir, int noclose) { switch (fork()) { case 0 : break; /* child */ case -1 : return -1; default : _exit(0); /* exit parent */ } if (setsid() < 0) return -1; switch (fork()) { case 0 : break; /* child */ case -1: return -1; default: _exit(0); /* exit parent */ } if (!nochdir && chdir("/") < 0) { error("chdir(/): %m"); return -1; } /* Close all file descriptors if requested */ if (!noclose) { closeall(0); if (open("/dev/null", O_RDWR) != 0) error("Unable to open /dev/null on stdin: %m"); dup2(0, STDOUT_FILENO); dup2(0, STDERR_FILENO); } else { /* * Otherwise, dup stdin, stdout, and stderr onto /dev/null */ int devnull = open("/dev/null", O_RDWR); if (devnull < 0) error("Unable to open /dev/null: %m"); if (dup2(devnull, STDIN_FILENO) < 0) error("Unable to dup /dev/null onto stdin: %m"); if (dup2(devnull, STDOUT_FILENO) < 0) error("Unable to dup /dev/null onto stdout: %m"); if (dup2(devnull, STDERR_FILENO) < 0) error("Unable to dup /dev/null onto stderr: %m"); if (close(devnull) < 0) error("Unable to close /dev/null: %m"); } return 0; }
void CleanUpMex(void) { if(closeall()) /* close all still open connections...*/ { /* ....if not all alread closed put out a matlab warning*/ /* should an breaking error message be better ??? */ mexWarnMsgTxt("Unloading mex file!\n" "Unclosed tcpip connections will be lost!!!!\n"); } #ifdef WIN32 WSACleanup(); #else signal(SIGPIPE,SIG_DFL); /*reset SIGPIPE to default. Is this good ??? */ #endif }
/* believed to work on all Posix systems */ static pid_t init_daemon (fd_set keepfds) { pid_t pid; switch ((pid = fork ())) { case 0: break; case -1: return -1; default: _exit (0); /* exit the original process */ } closeall (keepfds); if (setsid () < 0) /* shoudn't fail */ return -1; return pid; }
/*! * Run command in a child and wait for it to finish */ int run_cmd(const char *cmd, char **cmd_argv) { EC_INIT; pid_t pid, wpid; sigset_t sigs, oldsigs; int status = 0; sigfillset(&sigs); pthread_sigmask(SIG_SETMASK, &sigs, &oldsigs); if ((pid = fork()) < 0) { LOG(log_error, logtype_default, "run_cmd: fork: %s", strerror(errno)); return -1; } if (pid == 0) { /* child */ closeall(3); execvp("mv", cmd_argv); } /* parent */ while ((wpid = waitpid(pid, &status, 0)) < 0) { if (errno == EINTR) continue; break; } if (wpid != pid) { LOG(log_error, logtype_default, "waitpid(%d): %s", (int)pid, strerror(errno)); EC_FAIL; } if (WIFEXITED(status)) status = WEXITSTATUS(status); else if (WIFSIGNALED(status)) status = WTERMSIG(status); LOG(log_note, logtype_default, "run_cmd(\"%s\"): status: %d", cmd, status); EC_CLEANUP: if (status != 0) ret = status; pthread_sigmask(SIG_SETMASK, &oldsigs, NULL); EC_EXIT; }
__dead void panic(const char *fmt, ...) { extern void closeall(void); va_list ap; static int paniced; if (!paniced) { paniced = 1; closeall(); } va_start(ap, fmt); vprintf(fmt, ap); printf("\n"); va_end(ap); _rtt(); /*NOTREACHED*/ }
/* ----------------------------------------------------------------------------- load_kext ----------------------------------------------------------------------------- */ static u_long load_kext(char *kext) { int pid; if ((pid = fork()) < 0) return 1; if (pid == 0) { closeall(); // PPP kernel extension not loaded, try load it... execl("/sbin/kextload", "kextload", kext, (char *)0); exit(1); } while (waitpid(pid, 0, 0) < 0) { if (errno == EINTR) continue; return 1; } return 0; }
int daemon(int nochdir, int noclose, int asroot) { switch (fork()) { case 0: break; case -1: return -1; default: _exit(0); /* exit the original process */ } if (setsid() < 0) /* shoudn't fail */ return -1; if ( !asroot && (setuid(1) < 0) ) /* shoudn't fail */ return -1; /* dyke out this switch if you want to acquire a control tty in */ /* the future -- not normally advisable for daemons */ switch (fork()) { case 0: break; case -1: return -1; default: _exit(0); } if (!nochdir) chdir("/"); if (!noclose) { closeall(0); dup(0); dup(0); } return 0; }
int main(int argc, char **argv) { int i = 0; int fp; #ifdef f32c setup_f32c(); maxfiles = MAXFILES; #else catchsignal(); #endif startfp(); /* start up the floating point hardware */ setup_fb(); /* video framebuffer */ #ifndef f32c setupfiles(argc,argv); setupmyterm(); /* set up files after processing files */ #endif program = 0; clear(); prints("Rabbit BASIC version 2.1.3 (built " __DATE__ ")\n"); if(setexit() == ERR_RESET){ drop_fns(); execute(); /* execute the line */ } drop_fns(); docont(); stocurlin=0; /* say we are in immeadiate mode */ if(cursor) /* put cursor on a blank line */ prints( (char *)nl); if (firstrun && ( #ifdef f32c (fp = open("d:autoexec.bas",0)) > 0 || #endif (fp = open("autoexec.bas",0)) > 0)) { firstrun = 0; readfi(fp, 0, 0); close(fp); clear(); if (program) { stocurlin=program; point= program->lin; elsecount=0; execute(); } } firstrun = 0; prints("Ready\n"); for(;;){ do{ trapped=0; line[0] = '>'; line[1] = 0; VOID edit( (ival)1, (ival)1, (ival)0); }while( trapped || ( !(i=compile(1, nline, 0)) && !linenumber)); if(!linenumber) break; insert(i); } if(inserted){ inserted=0; clear(); closeall(); } #ifdef MSDOS lcount = 0; #endif clr_stack(bstack); /* reset the gosub stack */ bstack = estack = 0; if(str_used) /* free any spare strings */ FREE_STR(str_used); trap_env.e_stolin = 0; /* disable error traps */ intrap=0; /* say we are not in the error trap */ trapped=0; /* say we haven't got a cntrl-c */ cursor=0; /* cursor is at start of line */ elsecount=0; /* disallow elses as terminators */ point=nline; /* start executing at start of input line */ stocurlin=0; /* start of current line is null- see 'next' */ execute(); /* execute the line */ return(-1); /* see note below */ }
int main(int argc, char *argv[]) { ni_status status; ni_name myname = argv[0]; int create = 0; int log_pri = LOG_NOTICE; ni_name dbsource_name = NULL; ni_name dbsource_addr = NULL; ni_name dbsource_tag = NULL; struct rlimit rlim; char *str; unsigned db_checksum; FILE *logf; int nctoken; logf = NULL; forcedIsRoot = 0; Argv = argv; /* Save program and argument information for setproctitle */ Argc = argc; argc--; argv++; while (argc > 0 && **argv == '-') { if (strcmp(*argv, "-d") == 0) { debug = 1; log_pri = LOG_DEBUG; if (argc < 2) logf = stderr; else { debug = atoi(argv[1]); argc -= 1; argv += 1; } } else if (strcmp(*argv, "-l") == 0) { if (argc < 2) usage(myname); else { log_pri = atoi(argv[1]); argc -= 1; argv += 1; } } else if (strcmp(*argv, "-n") == 0) forcedIsRoot = 1; else if (strcmp(*argv, "-s") == 0) standalone = 1; else if (strcmp(*argv, "-m") == 0) create++; else if (strcmp(*argv, "-c") == 0) { if (argc < 4) usage(myname); create++; dbsource_name = argv[1]; dbsource_addr = argv[2]; dbsource_tag = argv[3]; argc -= 3; argv += 3; } else usage(myname); argc--; argv++; } if (argc != 1) usage(myname); if (debug == 0) { closeall(); if (standalone == 1) daemon(1, 1); } db_tag = malloc(strlen(argv[0]) + 1); strcpy(db_tag, argv[0]); str = malloc(strlen("netinfod ") + strlen(db_tag) + 1); sprintf(str, "netinfod %s", db_tag); system_log_open(str, (LOG_NDELAY | LOG_PID), LOG_NETINFO, logf); free(str); system_log_set_max_priority(log_pri); system_log(LOG_DEBUG, "version %s (pid %d) - starting", _PROJECT_VERSION_, getpid()); rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &rlim); rlim.rlim_cur = rlim.rlim_max = FD_SETSIZE; setrlimit(RLIMIT_NOFILE, &rlim); umask(S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH); srandom(gethostid() ^ time(NULL)); readall_syslock = syslock_new(0); lockup_syslock= syslock_new(0); cleanupwait = CLEANUPWAIT; auth_count[GOOD] = 0; auth_count[BAD] = 0; auth_count[WGOOD] = 0; auth_count[WBAD] = 0; if (create) { if (dbsource_addr == NULL) { system_log(LOG_DEBUG, "creating master"); status = dir_mastercreate(db_tag); } else { system_log(LOG_DEBUG, "creating clone"); status = dir_clonecreate(db_tag, dbsource_name, dbsource_addr, dbsource_tag); } if (status != NI_OK) { system_log_close(); exit(status); } } nctoken = -1; notify_register_signal(NETWORK_CHANGE_NOTIFICATION, SIGHUP, &nctoken); if (standalone == 0) signal(SIGTERM, SIG_IGN); signal(SIGPIPE, SIG_IGN); signal(SIGHUP, (void *)catch_sighup); signal(SIGCHLD, (void *)readall_catcher); if (debug == 0) { signal(SIGINT, (void *)dblock_catcher); if (standalone == 0) { if (setsid() < 0) syslog(LOG_WARNING, "setsid failed: %m"); } } writepid(db_tag); status = start_service(db_tag); if (status != NI_OK) { system_log(LOG_ERR, "start_service failed: %s - exiting", ni_error(status)); system_log_close(); exit(status); } setproctitle("netinfod %s (%s)", db_tag, i_am_clone ? "clone" : "master"); if (i_am_clone) { system_log(LOG_DEBUG, "checking clone"); cloneReadallResponseOK = get_clone_readall(db_ni); dir_clonecheck(); if (get_sanitycheck(db_ni)) sanitycheck(db_tag); system_log(LOG_DEBUG, "finished clone check"); } else { system_log(LOG_DEBUG, "setting up master server"); promote_admins = get_promote_admins(db_ni); get_readall_info(db_ni, &max_readall_proxies, &strict_proxies); max_subthreads = get_max_subthreads(db_ni); update_latency_secs = get_update_latency(db_ni); /* Tracking readall proxy pids uses ObjC, so isolate it */ initialize_readall_proxies(-1 == max_readall_proxies ? MAX_READALL_PROXIES : max_readall_proxies); system_log(LOG_DEBUG, "starting notify thread"); (void) notify_start(); } /* Shutdown gracefully after this point */ if (standalone == 1) signal(SIGTERM, (void *)sig_shutdown); signal(SIGUSR1, (void *)sig_shutdown); system_log(LOG_DEBUG, "starting RPC service"); ni_svc_run(_rpc_dtablesize() - (FD_SLOPSIZE + max_subthreads)); system_log(LOG_DEBUG, "shutting down"); /* * Tell the readall proxies to shut down */ if (readall_proxies > 0) { system_log(LOG_INFO, "killing %d readall prox%s", readall_proxies, 1 == readall_proxies ? "y" : "ies"); if (!kill_proxies()) system_log(LOG_WARNING, "some readall proxies still running"); } db_checksum = ni_getchecksum(db_ni); ni_shutdown(db_ni, db_checksum); system_log(LOG_INFO, "exiting; checksum %u", db_checksum); system_log_close(); exit(0); }
void warmboot(z80info *z80) { int i; closeall(z80); if (silent_exit) { finish(z80); } /* load CCP and BDOS into memory (max 0x1600 in size) */ for (i = 0; i < 0x1600 && i < sizeof cpm_array; i++) SETMEM(CCP + i, cpm_array[i]); /* try to load CCP/BDOS from disk, but ignore any errors */ loadfile(z80, "bdos.hex"); loadfile(z80, "ccp.hex"); /* CP/M system reset via "JP 00" - entry into BIOS warm-boot */ SETMEM(0x0000, 0xC3); /* JP CBIOS+3 */ SETMEM(0x0001, ((CBIOS + 3) & 0xFF)); SETMEM(0x0002, ((CBIOS + 3) >> 8)); /* 0x0003 is the IOBYTE, 0x0004 is the current DISK */ SETMEM(0x0003, 0x00); SETMEM(0x0004, z80->drive); /* CP/M syscall via "CALL 05" - entry into BDOS */ SETMEM(0x0005, 0xC3); /* JP BDOS+6 */ SETMEM(0x0006, ((BDOS+6) & 0xFF)); SETMEM(0x0007, ((BDOS+6) >> 8)); /* fake BIOS entry points */ for (i = 0; i < NENTRY; i++) { /* JP <bios-entry> */ SETMEM(CBIOS + 3 * i, 0xC3); SETMEM(CBIOS + 3 * i + 1, (CBIOS + NENTRY * 3 + i * 5) & 0xFF); SETMEM(CBIOS + 3 * i + 2, (CBIOS + NENTRY * 3 + i * 5) >> 8); /* LD A,<bios-call> - start of bios-entry */ SETMEM(CBIOS + NENTRY * 3 + i * 5, 0x3E); SETMEM(CBIOS + NENTRY * 3 + i * 5 + 1, i); /* OUT A,0FFH - we use port 0xFF to fake the BIOS call */ SETMEM(CBIOS + NENTRY * 3 + i * 5 + 2, 0xD3); SETMEM(CBIOS + NENTRY * 3 + i * 5 + 3, 0xFF); /* RET - end of bios-entry */ SETMEM(CBIOS + NENTRY * 3 + i * 5 + 4, 0xC9); } /* disc parameter block - a 5Mb ST-506 hard disc */ SETMEM(HDPBLOCK, HDSECTORSPERTRACK & 0xFF);/* SPT - sectors per track */ SETMEM(HDPBLOCK + 1, HDSECTORSPERTRACK >> 8); SETMEM(HDPBLOCK + 2, 4); /* BSH - data block shift factor */ SETMEM(HDPBLOCK + 3, 15); /* BLM - data block mask */ SETMEM(HDPBLOCK + 4, 0); /* EXM - extent mask */ SETMEM(HDPBLOCK + 5, 2441 & 0xFF); /* DSM - total drive capacity */ SETMEM(HDPBLOCK + 6, 2441 >> 8); SETMEM(HDPBLOCK + 7, 1023 & 0xFF); /* DRM - total dir entries */ SETMEM(HDPBLOCK + 8, 1023 >> 8); SETMEM(HDPBLOCK + 9, 0xFF); /* AL0 - blocks for directory entries */ SETMEM(HDPBLOCK + 10, 0xFF); /* AL1 */ SETMEM(HDPBLOCK + 11, 0x00); /* CKS - directory check vector */ SETMEM(HDPBLOCK + 12, 0x00); SETMEM(HDPBLOCK + 13, RESERVEDTRACKS & 0xFF);/* OFF - reserved tracks */ SETMEM(HDPBLOCK + 14, RESERVEDTRACKS >> 8); /* disk parameter headers for hard disc */ for (i = 0; i < NUMHDISCS; i++) { SETMEM(HDPBASE + DPHSIZE * i, 0x00); /* XLT */ SETMEM(HDPBASE + DPHSIZE * i + 1, 0x00); SETMEM(HDPBASE + DPHSIZE * i + 2, 0x00); /* scratch 1 */ SETMEM(HDPBASE + DPHSIZE * i + 3, 0x00); SETMEM(HDPBASE + DPHSIZE * i + 4, 0x00); /* scratch 2 */ SETMEM(HDPBASE + DPHSIZE * i + 5, 0x00); SETMEM(HDPBASE + DPHSIZE * i + 6, 0x00); /* scratch 3 */ SETMEM(HDPBASE + DPHSIZE * i + 7, 0x00); SETMEM(HDPBASE + DPHSIZE * i + 8, DIRBUF & 0xFF); /* DIRBUF */ SETMEM(HDPBASE + DPHSIZE * i + 9, DIRBUF >> 8); SETMEM(HDPBASE + DPHSIZE * i + 10, HDPBLOCK & 0xFF); /* DPB */ SETMEM(HDPBASE + DPHSIZE * i + 11, HDPBLOCK >> 8); SETMEM(HDPBASE + DPHSIZE * i + 12, 0x00); SETMEM(HDPBASE + DPHSIZE * i + 13, 0x00); SETMEM(HDPBASE + DPHSIZE * i + 14, (HALVBASE + HALVSIZE * i) & 0xFF); SETMEM(HDPBASE + DPHSIZE * i + 15, (HALVBASE + HALVSIZE * i) >> 8); } /* disc parameter block - a single-sided single-density 8" 256k disc */ SETMEM(DPBLOCK, SECTORSPERTRACK & 0xFF); /* SPT - sectors per track */ SETMEM(DPBLOCK + 1, SECTORSPERTRACK >> 8); SETMEM(DPBLOCK + 2, 3); /* BSH - data block shift factor */ SETMEM(DPBLOCK + 3, 7); /* BLM - data block mask */ SETMEM(DPBLOCK + 4, 0); /* EXM - extent mask */ SETMEM(DPBLOCK + 5, 242); /* DSM - total capacity of drive */ SETMEM(DPBLOCK + 6, 0); SETMEM(DPBLOCK + 7, 63); /* DRM - total directory entries */ SETMEM(DPBLOCK + 8, 0); SETMEM(DPBLOCK + 9, 0xC0); /* AL0 - blocks for directory entries */ SETMEM(DPBLOCK + 10, 0x00); /* AL1 */ SETMEM(DPBLOCK + 11, 0x00); /* CKS - directory check vector */ SETMEM(DPBLOCK + 12, 0x00); SETMEM(DPBLOCK + 13, RESERVEDTRACKS & 0xFF); /* OFF - reserved tracks */ SETMEM(DPBLOCK + 14, RESERVEDTRACKS >> 8); /* disc parameter headers */ for (i = 0; i < NUMDISCS; i++) { SETMEM(DPBASE + DPHSIZE * i, 0x00); /* XLT */ SETMEM(DPBASE + DPHSIZE * i + 1, 0x00); SETMEM(DPBASE + DPHSIZE * i + 2, 0x00); /* scratch 1 */ SETMEM(DPBASE + DPHSIZE * i + 3, 0x00); SETMEM(DPBASE + DPHSIZE * i + 4, 0x00); /* scratch 2 */ SETMEM(DPBASE + DPHSIZE * i + 5, 0x00); SETMEM(DPBASE + DPHSIZE * i + 6, 0x00); /* scratch 3 */ SETMEM(DPBASE + DPHSIZE * i + 7, 0x00); SETMEM(DPBASE + DPHSIZE * i + 8, DIRBUF & 0xFF); /* DIRBUF */ SETMEM(DPBASE + DPHSIZE * i + 9, DIRBUF >> 8); SETMEM(DPBASE + DPHSIZE * i + 10, DPBLOCK & 0xFF); /* DPB */ SETMEM(DPBASE + DPHSIZE * i + 11, DPBLOCK >> 8); #if (CVSIZE == 0) SETMEM(DPBASE + DPHSIZE * i + 12, 0x00); SETMEM(DPBASE + DPHSIZE * i + 13, 0x00); #else SETMEM(DPBASE + DPHSIZE * i + 12, (CVBASE + CVSIZE * i) & 0xFF); SETMEM(DPBASE + DPHSIZE * i + 13, (CVBASE + CVSIZE * i) >> 8); #endif SETMEM(DPBASE + DPHSIZE * i + 14, (ALVBASE + ALVSIZE * i) & 0xFF); SETMEM(DPBASE + DPHSIZE * i + 15, (ALVBASE + ALVSIZE * i) >> 8); } /* set up the stack for an 8-level RET to do a system reset */ SP = STACK; for (i = 0; i < 8; i++) { /* push reboot entry (CBIOS + 3) onto stack */ --SP; SETMEM(SP, (CBIOS + 3) >> 8); --SP; SETMEM(SP, (CBIOS + 3) & 0xFF); } /* set up the default disk (A:) and dma address */ z80->dma = 0x0080; /* and all our default drive info */ z80->track = 0; z80->sector = 1; /* make sure the current file/disk is open */ B = 0; C = z80->drive; seldisc(z80); PC = CCP; }
int8_t RogueSD::sync(void) { // procedure: // 1. sync (send ESC, clear prompt) // 2. get version ("v"), and module type // 3. change settings as needed // 4. check status // 5. close files (if needed - E08, or other error, not needed) // 0. empty any data in the serial buffer _comm_flush(); // 1. sync _comm_write(0x1b); // send ESC to clear buffer on uMMC _read_blocked(); // consume prompt // 2. get version (ignore prompt - just drop it) _get_version(); // 3. change settings as needed // OLD: write timeout setting = 10 ms timeout // NEW: listing style = old style (0) if ((_moduletype == uMMC && _fwversion < UMMC_MIN_FW_VERSION_FOR_NEW_COMMANDS) || (_moduletype == uMP3 && _fwversion < UMP3_MIN_FW_VERSION_FOR_NEW_COMMANDS)) { // we need to set the write timeout to allow us to control when a line is finished // in writeln. changesetting('1', 1); // 10 ms timeout } else { // we're using the new version // Let's make sure the Listing Style setting is set to the old style if (getsetting('L') != 0) { changesetting('L', 0); } // get the prompt char print('S'); if (_moduletype != uMMC) { print('T'); }; print('P'); print('\r'); // get our prompt (if possible) _promptchar = _getnumber(10); _read_blocked(); // consume prompt } // 4. check status if (_moduletype != uMMC) { print("FC"); }; print('Z'); print('\r'); // Get status if (_get_response()) return -1; else { // good _read_blocked(); // consume prompt // 5. close all files closeall(); // ensure all handles are closed return 0; } }
void run(Node *a) /* execution of parse tree starts here */ { execute(a); closeall(); }
int main(int argc, char **argv) { char *export_file = _PATH_EXPORTS; char *state_dir = NFS_STATEDIR; int foreground = 0; int port = 0; int descriptors = 0; int c; struct sigaction sa; struct rlimit rlim; /* Parse the command line options and arguments. */ opterr = 0; while ((c = getopt_long(argc, argv, "o:nFd:f:p:P:hH:N:V:vrs:t:g", longopts, NULL)) != EOF) switch (c) { case 'g': manage_gids = 1; break; case 'o': descriptors = atoi(optarg); if (descriptors <= 0) { fprintf(stderr, "%s: bad descriptors: %s\n", argv [0], optarg); usage(argv [0], 1); } break; case 'F': foreground = 1; break; case 'd': xlog_sconfig(optarg, 1); break; case 'f': export_file = optarg; break; case 'H': /* PRC: specify a high-availability callout program */ ha_callout_prog = optarg; break; case 'h': usage(argv [0], 0); break; case 'P': /* XXX for nfs-server compatibility */ case 'p': port = atoi(optarg); if (port <= 0 || port > 65535) { fprintf(stderr, "%s: bad port number: %s\n", argv [0], optarg); usage(argv [0], 1); } break; case 'N': nfs_version &= ~(1 << (atoi (optarg) - 1)); break; case 'n': _rpcfdtype = SOCK_DGRAM; break; case 'r': reverse_resolve = 1; break; case 's': if ((state_dir = xstrdup(optarg)) == NULL) { fprintf(stderr, "%s: xstrdup(%s) failed!\n", argv[0], optarg); exit(1); } break; case 't': num_threads = atoi (optarg); break; case 'V': nfs_version |= 1 << (atoi (optarg) - 1); break; case 'v': printf("kmountd %s\n", VERSION); exit(0); case 0: break; case '?': default: usage(argv [0], 1); } /* No more arguments allowed. * Require at least one valid version (2, 3, or 4) */ if (optind != argc || !(nfs_version & 0xE)) usage(argv [0], 1); if (chdir(state_dir)) { fprintf(stderr, "%s: chdir(%s) failed: %s\n", argv [0], state_dir, strerror(errno)); exit(1); } if (getrlimit (RLIMIT_NOFILE, &rlim) != 0) fprintf(stderr, "%s: getrlimit (RLIMIT_NOFILE) failed: %s\n", argv [0], strerror(errno)); else { /* glibc sunrpc code dies if getdtablesize > FD_SETSIZE */ if ((descriptors == 0 && rlim.rlim_cur > FD_SETSIZE) || descriptors > FD_SETSIZE) descriptors = FD_SETSIZE; if (descriptors) { rlim.rlim_cur = descriptors; if (setrlimit (RLIMIT_NOFILE, &rlim) != 0) { fprintf(stderr, "%s: setrlimit (RLIMIT_NOFILE) failed: %s\n", argv [0], strerror(errno)); exit(1); } } } /* Initialize logging. */ if (!foreground) xlog_stderr(0); xlog_open("mountd"); sa.sa_handler = SIG_IGN; sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sigaction(SIGHUP, &sa, NULL); sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sigaction(SIGPIPE, &sa, NULL); /* WARNING: the following works on Linux and SysV, but not BSD! */ sigaction(SIGCHLD, &sa, NULL); /* Daemons should close all extra filehandles ... *before* RPC init. */ if (!foreground) closeall(3); new_cache = check_new_cache(); if (new_cache) cache_open(); if (nfs_version & 0x1) rpc_init("mountd", MOUNTPROG, MOUNTVERS, mount_dispatch, port); if (nfs_version & (0x1 << 1)) rpc_init("mountd", MOUNTPROG, MOUNTVERS_POSIX, mount_dispatch, port); if (nfs_version & (0x1 << 2)) rpc_init("mountd", MOUNTPROG, MOUNTVERS_NFSV3, mount_dispatch, port); sa.sa_handler = killer; sigaction(SIGINT, &sa, NULL); sigaction(SIGTERM, &sa, NULL); sa.sa_handler = sig_hup; sigaction(SIGHUP, &sa, NULL); auth_init(export_file); if (!foreground) { /* We first fork off a child. */ if ((c = fork()) > 0) exit(0); if (c < 0) { xlog(L_FATAL, "mountd: cannot fork: %s\n", strerror(errno)); } /* Now we remove ourselves from the foreground. Redirect stdin/stdout/stderr first. */ { int fd = open("/dev/null", O_RDWR); (void) dup2(fd, 0); (void) dup2(fd, 1); (void) dup2(fd, 2); if (fd > 2) (void) close(fd); } setsid(); } /* silently bounds check num_threads */ if (foreground) num_threads = 1; else if (num_threads < 1) num_threads = 1; else if (num_threads > MAX_THREADS) num_threads = MAX_THREADS; if (num_threads > 1) fork_workers(); my_svc_run(); xlog(L_ERROR, "Ack! Gack! svc_run returned!\n"); exit(1); }
int kadmin(int cmd, int fcn, void *mdep, cred_t *credp) { int error = 0; char *buf; size_t buflen = 0; boolean_t invoke_cb = B_FALSE; /* * We might be called directly by the kernel's fault-handling code, so * we can't assert that the caller is in the global zone. */ /* * Make sure that cmd is one of the valid <sys/uadmin.h> command codes * and that we have appropriate privileges for this action. */ switch (cmd) { case A_FTRACE: case A_SHUTDOWN: case A_REBOOT: case A_REMOUNT: case A_FREEZE: case A_DUMP: case A_SDTTEST: case A_CONFIG: if (secpolicy_sys_config(credp, B_FALSE) != 0) return (EPERM); break; default: return (EINVAL); } /* * Serialize these operations on ualock. If it is held, the * system should shutdown, reboot, or remount shortly, unless there is * an error. We need a cv rather than just a mutex because proper * functioning of A_REBOOT relies on being able to interrupt blocked * userland callers. * * We only clear ua_shutdown_thread after A_REMOUNT or A_CONFIG. * Other commands should never return. */ if (cmd == A_SHUTDOWN || cmd == A_REBOOT || cmd == A_REMOUNT || cmd == A_CONFIG) { mutex_enter(&ualock); while (ua_shutdown_thread != NULL) { if (cv_wait_sig(&uacond, &ualock) == 0) { /* * If we were interrupted, leave, and handle * the signal (or exit, depending on what * happened) */ mutex_exit(&ualock); return (EINTR); } } ua_shutdown_thread = curthread; mutex_exit(&ualock); } switch (cmd) { case A_SHUTDOWN: { proc_t *p = ttoproc(curthread); /* * Release (almost) all of our own resources if we are called * from a user context, however if we are calling kadmin() from * a kernel context then we do not release these resources. */ if (p != &p0) { proc_is_exiting(p); if ((error = exitlwps(0)) != 0) { /* * Another thread in this process also called * exitlwps(). */ mutex_enter(&ualock); ua_shutdown_thread = NULL; cv_signal(&uacond); mutex_exit(&ualock); return (error); } mutex_enter(&p->p_lock); p->p_flag |= SNOWAIT; sigfillset(&p->p_ignore); curthread->t_lwp->lwp_cursig = 0; curthread->t_lwp->lwp_extsig = 0; if (p->p_exec) { vnode_t *exec_vp = p->p_exec; p->p_exec = NULLVP; mutex_exit(&p->p_lock); VN_RELE(exec_vp); } else { mutex_exit(&p->p_lock); } pollcleanup(); closeall(P_FINFO(curproc)); relvm(); } else { /* * Reset t_cred if not set because much of the * filesystem code depends on CRED() being valid. */ if (curthread->t_cred == NULL) curthread->t_cred = kcred; } /* indicate shutdown in progress */ sys_shutdown = 1; /* * Communcate that init shouldn't be restarted. */ zone_shutdown_global(); killall(ALL_ZONES); /* * If we are calling kadmin() from a kernel context then we * do not release these resources. */ if (ttoproc(curthread) != &p0) { VN_RELE(PTOU(curproc)->u_cdir); if (PTOU(curproc)->u_rdir) VN_RELE(PTOU(curproc)->u_rdir); if (PTOU(curproc)->u_cwd) refstr_rele(PTOU(curproc)->u_cwd); PTOU(curproc)->u_cdir = rootdir; PTOU(curproc)->u_rdir = NULL; PTOU(curproc)->u_cwd = NULL; } /* * Allow the reboot/halt/poweroff code a chance to do * anything it needs to whilst we still have filesystems * mounted, like loading any modules necessary for later * performing the actual poweroff. */ if ((mdep != NULL) && (*(char *)mdep == '/')) { buf = i_convert_boot_device_name(mdep, NULL, &buflen); mdpreboot(cmd, fcn, buf); } else mdpreboot(cmd, fcn, mdep); /* * Allow fsflush to finish running and then prevent it * from ever running again so that vfs_unmountall() and * vfs_syncall() can acquire the vfs locks they need. */ sema_p(&fsflush_sema); (void) callb_execute_class(CB_CL_UADMIN_PRE_VFS, NULL); vfs_unmountall(); (void) VFS_MOUNTROOT(rootvfs, ROOT_UNMOUNT); vfs_syncall(); dump_ereports(); dump_messages(); invoke_cb = B_TRUE; /* FALLTHROUGH */ } case A_REBOOT: if ((mdep != NULL) && (*(char *)mdep == '/')) { buf = i_convert_boot_device_name(mdep, NULL, &buflen); mdboot(cmd, fcn, buf, invoke_cb); } else mdboot(cmd, fcn, mdep, invoke_cb); /* no return expected */ break; case A_CONFIG: switch (fcn) { case AD_UPDATE_BOOT_CONFIG: #ifndef __sparc { extern void fastboot_update_config(const char *); fastboot_update_config(mdep); } #endif break; } /* Let other threads enter the shutdown path now */ mutex_enter(&ualock); ua_shutdown_thread = NULL; cv_signal(&uacond); mutex_exit(&ualock); break; case A_REMOUNT: (void) VFS_MOUNTROOT(rootvfs, ROOT_REMOUNT); /* Let other threads enter the shutdown path now */ mutex_enter(&ualock); ua_shutdown_thread = NULL; cv_signal(&uacond); mutex_exit(&ualock); break; case A_FREEZE: { /* * This is the entrypoint for all suspend/resume actions. */ extern int cpr(int, void *); if (modload("misc", "cpr") == -1) return (ENOTSUP); /* Let the CPR module decide what to do with mdep */ error = cpr(fcn, mdep); break; } case A_FTRACE: { switch (fcn) { case AD_FTRACE_START: (void) FTRACE_START(); break; case AD_FTRACE_STOP: (void) FTRACE_STOP(); break; default: error = EINVAL; } break; } case A_DUMP: { if (fcn == AD_NOSYNC) { in_sync = 1; break; } panic_bootfcn = fcn; panic_forced = 1; if ((mdep != NULL) && (*(char *)mdep == '/')) { panic_bootstr = i_convert_boot_device_name(mdep, NULL, &buflen); } else panic_bootstr = mdep; #ifndef __sparc extern void fastboot_update_and_load(int, char *); fastboot_update_and_load(fcn, mdep); #endif panic("forced crash dump initiated at user request"); /*NOTREACHED*/ } case A_SDTTEST: { DTRACE_PROBE7(test, int, 1, int, 2, int, 3, int, 4, int, 5, int, 6, int, 7); break; } default: error = EINVAL; } return (error); }
void mexFunction( int nlhs, /* number of expected outputs */ mxArray *plhs[], /* array of pointers to output arguments */ int nrhs, /* number of inputs */ const mxArray *prhs[] /* array of pointers to input arguments */ ) { int fun; struct in_addr addr; /* Initialization on first call to the mex file */ if(mex_call_counter==0) { // int i; #ifdef WIN32 { WORD wVersionRequested; WSADATA wsaData; int wsa_err; wVersionRequested = MAKEWORD( 2, 0 ); wsa_err = WSAStartup( wVersionRequested, &wsaData ); if ( wsa_err ) { mexErrMsgTxt("Error starting WINSOCK32."); return; } } #endif mexAtExit(CleanUpMex); /* Init all to free */ for(ipi_index=0;ipi_index<MAX_IPI;ipi_index++) init_ipi(-1,STATUS_FREE); ipi_index=0; } mex_call_counter++; ret_args=0; debug_view_ipi_status("ENTER_MEX"); if(nrhs<2) mexErrMsgTxt("You must specify at least two arguments!"); if(mxGetM(prhs[0])*mxGetN(prhs[0])!=1) mexErrMsgTxt("Error on first argument! should be a function selection number."); fun=(int)mxGetScalar(prhs[0]); /* ---CLOSE ALL---- */ if(fun<0) { closeall(); return; } /* Find given handel */ { int idx; if(mxGetM(prhs[1])*mxGetN(prhs[1])!=1) mexErrMsgTxt("Error on second argument. Specify handler as scalar!"); idx=(int)mxGetScalar(prhs[1]); if(move_ipi(idx)==0) mexErrMsgTxt("Unknown handler!"); } debug_view_ipi_status("IPI_MOVED!!"); switch(fun) { /* ---CLOSE--- */ case 0: { if(ipi[ipi_index].fid<0) /* Already closed?? */ mexPrintf("Cant close already closed fid.\n"); else close_ipi(); break; } /* ---OPEN AS CLIENT--- */ case 1: { char hostname[NAMEBUFF_LEN+1]; int len; int port; debug_view_ipi_status("O1"); if(ipi[ipi_index].fid>=0) mexErrMsgTxt("This handler is already open !!??"); debug_view_ipi_status("O2"); if(nrhs<3) mexErrMsgTxt("Wrong number of arguments for OPEN!"); if(mxIsChar(prhs[2])==0 || mxIsNumeric(prhs[3])==0) mexErrMsgTxt("Wrong argument datatype for OPEN!"); len=mxGetM(prhs[2])*mxGetN(prhs[2])+1; if(len>=NAMEBUFF_LEN) mexErrMsgTxt("To long hostname!"); mxGetString(prhs[2], hostname, len); port=(int)mxGetScalar(prhs[3]); debug_view_ipi_status("O3"); // ipi[ipi_index].he=gethostbyname(hostname); debug_view_ipi_status("O4"); if(ipi[ipi_index].he!=NULL) addr = *((struct in_addr *)ipi[ipi_index].he->h_addr); else { /* Can't lookup hostname, try IP address */ addr.s_addr=inet_addr(hostname); if (addr.s_addr==INADDR_NONE) { my_mexReturnValue(nlhs,plhs,-1); break; } } debug_view_ipi_status("O5"); ipi[ipi_index].fid=socket(AF_INET, SOCK_STREAM, 0); debug_view_ipi_status("O5"); if(ipi[ipi_index].fid== IPI_FREE) { /* Can't make socket for connnection to remote host. */ my_mexReturnValue(nlhs,plhs,-1); break; } debug_view_ipi_status("O6"); ipi[ipi_index].remote_addr.sin_family=AF_INET; ipi[ipi_index].remote_addr.sin_port=htons(port); ipi[ipi_index].remote_addr.sin_addr=addr; ipi[ipi_index].remote_addr.sin_family=AF_INET; memset(&ipi[ipi_index].remote_addr.sin_zero, 0,8); if(connect(ipi[ipi_index].fid,(struct sockaddr *)&ipi[ipi_index].remote_addr, sizeof(struct sockaddr)) == -1) { /*Can't connect to remote host. */ my_mexReturnValue(nlhs,plhs,-1); close_ipi(); break; } debug_view_ipi_status("O7"); init_ipi(ipi[ipi_index].fid,STATUS_CLIENT); nonblockingsocket(ipi[ipi_index].fid); /* Non blocking read! */ debug_view_ipi_status("O8"); my_mexReturnValue(nlhs,plhs,ipi_index); break; } /* ---- WRITESTRING ---- */ case 2: { int retval=100000; int sentlen=0; char *buff; int len; if(nrhs<3) mexErrMsgTxt("You must specify string to write as third argument!"); if(mxIsChar(prhs[2])==0) mexErrMsgTxt("Write string must be array of chars!"); len=mxGetM(prhs[2])*mxGetN(prhs[2]); if(len==0) { my_mexReturnValue(nlhs,plhs,0); break; } if((buff=(char *)mxMalloc(len))==NULL) mexErrMsgTxt("Running out of memory! Can't send string!"); CopymxCharArray2Buff(prhs[2],buff,len); sentlen=writedata(buff,len); my_mexReturnValue(nlhs,plhs,sentlen); mxFree(buff); break; } break; /* ---- READSTRING ---- */ case 3: { int readlen; if(nrhs<3) mexErrMsgTxt("You must specify maximum of characteer to read!"); readlen=(int)mxGetScalar(prhs[2]); read2buff(readlen); if(readlen>ipi[ipi_index].buffdatalen) readlen=ipi[ipi_index].buffdatalen; my_mexReturnCharArray(nlhs,plhs,ipi[ipi_index].buff,readlen); removefrombuff(readlen); } break; /* ---- READSTRING UNTIL (READLINE) ---- */ case 4: { int i; int readlen; int flag=0; int termchar1=13; /* Two default string termination characters */ int termchar2=10; if(nrhs<3) mexErrMsgTxt("You must specify maximum of characters to read!"); if(nrhs>3) termchar1=termchar2=(int)mxGetScalar(prhs[3]); if(nrhs>4) termchar2=(int)mxGetScalar(prhs[4]); readlen=(int)mxGetScalar(prhs[2]); read2buff(readlen); for(i=0; i<readlen, i<ipi[ipi_index].buffdatalen; i++) { if(ipi[ipi_index].buff[i]==termchar1 || ipi[ipi_index].buff[i]==termchar2) { my_mexReturnCharArray(nlhs,plhs,ipi[ipi_index].buff,i+1); removefrombuff(i+1); break; } } if(readlen==ipi[ipi_index].buffdatalen) /*Is read buffer full? */ { /* then wrap line...*/ my_mexReturnCharArray(nlhs,plhs,ipi[ipi_index].buff,ipi[ipi_index].buffdatalen); removefrombuff(ipi[ipi_index].buffdatalen); } else /* else return empty*/ my_mexReturnCharArray(nlhs,plhs,"",0); } break; /* ----- "VIEW" INCOMMING DATA, (NOT DELETE FROM BUFFER)------ */ case 5: { int readlen; readlen=(int)mxGetScalar(prhs[2]); read2buff(readlen); if(readlen>ipi[ipi_index].buffdatalen) readlen=ipi[ipi_index].buffdatalen; my_mexReturnCharArray(nlhs,plhs,ipi[ipi_index].buff,readlen); } break; /* --- RETURN STATUS --- */ case 6: my_mexReturnValue(nlhs,plhs,ipi[ipi_index].status); break; /* --- SET_CALLBACK_FUNCTION --- */ case 7: { if(nrhs<3) mexErrMsgTxt("You must specify a string as callback function name!"); if(mxIsChar(prhs[2])==0) mexErrMsgTxt("You must specify a string as callback function name!"); mxGetString(prhs[2],ipi[ipi_index].callback, CBNAMELEN); break; } break; /* --- EXECUTE_CALLBACK_FUNCTION --- */ case 9: { /*............. Type a lote here ................*/ } break; /* ---- OPEN_AS_SERVER ----*/ /* OLD!!! Remove this ???? */ case 10: { int port; int idx; if(ipi[ipi_index].fid>=0) mexErrMsgTxt("already open??? Always specify handler -1 when open a new!"); if(nrhs<3) mexErrMsgTxt("Wrong number of arguments for OPEN_AS_SERVER!"); port=(int)mxGetScalar(prhs[2]); idx=tcpipserver(port); my_mexReturnValue(nlhs,plhs,idx); } break; /* ---- OPEN_SERVER_SOCKET ---*/ case 20: { int fd; /* File descriptor for socket! */ int port; if(ipi[ipi_index].status!=STATUS_NOCONNECT) mexErrMsgTxt("already open??? Always specify handler -1 when open a new!"); if(nrhs<3) mexErrMsgTxt("Wrong number of arguments. specify port number."); port=(int)mxGetScalar(prhs[2]); fd=tcpipsocket(port); if(fd>=0) { init_ipi(fd,STATUS_SERVSOCKET); my_mexReturnValue(nlhs,plhs,ipi_index); } else { init_ipi(-1,STATUS_FREE); my_mexReturnValue(nlhs,plhs,-1); } } break; /* ---- OPEN_CONNECTED TO SERVER --- Listen for calls and return */ case 21: { int conn_fd; // int sockfd; if(ipi[ipi_index].status!=STATUS_SERVSOCKET) mexErrMsgTxt("Its not a open socket you tries listens to..."); conn_fd=tcpiplisten(ipi[ipi_index].fid); if( conn_fd >=0) { /* Find a new free ipi struct for the new connection.... */ move_ipi(IPI_FREE); init_ipi(conn_fd,STATUS_SERVER); my_mexReturnValue(nlhs,plhs,ipi_index); } else { my_mexReturnValue(nlhs,plhs,-1); } } break; default: mexErrMsgTxt("Unknown number for called function! Not implemented in this verion?"); break; } debug_view_ipi_status("EXIT"); }
int main(int argc, char *argv[]) { SVCXPRT *utransp, *ttransp; struct sockaddr_in addr; DIR *dp; struct direct *d; ni_name tag = NULL; ni_namelist nl; ni_index i; int pid, localonly, nctoken = -1; int log_pri = LOG_NOTICE; struct rlimit rlim; char *netinfod_argv[16]; /* XXX */ int netinfod_argc, x; union wait wait_stat; pid_t child_pid; char *pri; #ifdef _UNIX_BSD_43_ int ttyfd; #endif localonly = 1; netinfod_argc = 0; netinfod_argv[netinfod_argc++] = (char *)NETINFO_PROG; debug = 0; for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-n")) { netinfod_argv[netinfod_argc++] = argv[i]; } if (!strcmp(argv[i], "-d")) { debug = 1; log_pri = LOG_DEBUG; if ((argc > (i+1)) && (argv[i+1][0] != '-')) debug = atoi(argv[++i]); } if (!strcmp(argv[i], "-l")) { if ((argc > (i+1)) && (argv[i+1][0] != '-')) log_pri = atoi(argv[++i]); } if (!strcmp(argv[i], "-D")) { netinfod_argv[netinfod_argc++] = "-d"; if ((argc > (i+1)) && (argv[i+1][0] != '-')) { netinfod_argv[netinfod_argc++] = argv[i]; } } if (!strcmp(argv[i], "-L")) { netinfod_argv[netinfod_argc++] = "-l"; if ((argc > (i+1)) && (argv[i+1][0] != '-')) { netinfod_argv[netinfod_argc++] = argv[i]; } else { pri = malloc(sizeof("999")); sprintf(pri, "%d", LOG_DEBUG); netinfod_argv[netinfod_argc++] = pri; } } } if (debug == 1) { system_log_open("nibindd", LOG_NDELAY | LOG_PID, LOG_NETINFO, stderr); system_log_set_max_priority(log_pri); system_log(LOG_DEBUG, "version %s - debug mode\n", _PROJECT_VERSION_); } else { closeall(); system_log_open("nibindd", LOG_NDELAY | LOG_PID, LOG_NETINFO, NULL); system_log_set_max_priority(log_pri); system_log(LOG_DEBUG, "version %s - starting\n", _PROJECT_VERSION_); child_pid = fork(); if (child_pid == -1) { system_log(LOG_ALERT, "fork() failed: %m, aborting"); system_log_close(); exit(1); } else if (child_pid > 0) { signal(SIGTERM, parentexit); system_log(LOG_DEBUG, "parent waiting for child to start"); wait4(child_pid, (_WAIT_TYPE_ *)&wait_stat, 0, 0); if (WIFEXITED(wait_stat)) { system_log(LOG_DEBUG, "unexpected child exit, status=%d", WEXITSTATUS(wait_stat)); } else { system_log(LOG_DEBUG, "unexpected child exit, received signal=%d", WTERMSIG(wait_stat)); } system_log_close(); exit(1); } } restart = 0; rlim.rlim_cur = rlim.rlim_max = RLIM_INFINITY; setrlimit(RLIMIT_CORE, &rlim); signal(SIGCHLD, catchchild); signal(SIGTERM, killchildren); signal(SIGHUP, catchhup); signal(SIGINT, SIG_IGN); notify_register_signal(NETWORK_CHANGE_NOTIFICATION, SIGHUP, &nctoken); writepid(); /* * cd to netinfo directory, find out which databases should * be served and lock the directory before registering service. */ if (chdir(NETINFO_DIR) < 0) { killparent(); system_log(LOG_ALERT, "cannot chdir to netinfo directory"); exit(1); } dp = opendir(NETINFO_DIR); if (dp == NULL) { killparent(); system_log(LOG_ALERT, "cannot open netinfo directory"); exit(1); } MM_ZERO(&nl); while ((d = readdir(dp))) { if (isnidir(d->d_name, &tag)) { if (ni_namelist_match(nl, tag) == NI_INDEX_NULL) { system_log(LOG_DEBUG, "found database: %s", tag); ni_namelist_insert(&nl, tag, NI_INDEX_NULL); if (strcmp(tag, "local")) localonly = 0; } ni_name_free(&tag); } } #ifdef _NETINFO_FLOCK_ /* * Do not close the directory: keep it locked so another nibindd * won't run. */ if (flock(dp->dd_fd, LOCK_EX|LOCK_NB) < 0) { killparent(); system_log(LOG_ALERT, "nibindd already running"); exit(1); } fcntl(dp->dd_fd, F_SETFD, 1); #else closedir(dp); #endif /* * Register as a SUNRPC service */ memset(&addr, 0, sizeof(struct sockaddr_in)); addr.sin_family = AF_INET; if (localonly == 1) addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK); pmap_unset(NIBIND_PROG, NIBIND_VERS); utransp = svcudp_bind(RPC_ANYSOCK, addr); if (utransp == NULL) { killparent(); system_log(LOG_ALERT, "cannot start udp service"); exit(1); } if (!svc_register(utransp, NIBIND_PROG, NIBIND_VERS, nibind_prog_1, IPPROTO_UDP)) { killparent(); system_log(LOG_ALERT, "cannot register udp service"); exit(1); } udp_sock = utransp->xp_sock; ttransp = svctcp_bind(RPC_ANYSOCK, addr, 0, 0); if (ttransp == NULL) { killparent(); system_log(LOG_ALERT, "cannot start tcp service"); exit(1); } if (!svc_register(ttransp, NIBIND_PROG, NIBIND_VERS, nibind_prog_1, IPPROTO_TCP)) { killparent(); system_log(LOG_ALERT, "cannot register tcp service"); exit(1); } waitreg = 0; for (i = 0; i < nl.ninl_len; i++) { netinfod_argv[netinfod_argc] = nl.ninl_val[i]; netinfod_argv[netinfod_argc + 1] = NULL; system_log(LOG_DEBUG, "starting netinfod %s", nl.ninl_val[i]); system_log(LOG_DEBUG, "execv debug 0: %s", NETINFO_PROG); for (x = 0; netinfod_argv[x] != NULL; x++) { system_log(LOG_DEBUG, "execv debug %d: %s", x, netinfod_argv[x]); } pid = fork(); if (pid == 0) { /* child */ execv(NETINFO_PROG, netinfod_argv); exit(-1); } #ifdef DEBUG system_log(LOG_DEBUG, "netinfod %s pid = %d", nl.ninl_val[i], pid); #endif if (pid > 0) { waitreg++; storepid(pid, nl.ninl_val[i]); } else { system_log(LOG_ERR, "server for tag %s failed to start", nl.ninl_val[i]); } } ni_namelist_free(&nl); /* * Detach from controlling tty. * Do this AFTER starting netinfod so "type c to continue..." works. */ #ifdef _UNIX_BSD_43_ ttyfd = open("/dev/tty", O_RDWR, 0); if (ttyfd > 0) { ioctl(ttyfd, TIOCNOTTY, NULL); close(ttyfd); } setpgrp(0, getpid()); #else if (setsid() < 0) syslog(LOG_ERR, "nibindd: setsid() failed: %m"); #endif system_log(LOG_DEBUG, "starting RPC service"); nibind_svc_run(); system_log(LOG_ALERT, "svc_run returned"); system_log_close(); exit(1); }
int main(int argc, char **argv) { int count = 1, c, error = 0, portnum = 0, fd, found_one; char *p, *progname, *port; char *haddr = NULL; int socket_up = 0; int minorvers4 = NFSD_MAXMINORVERS4; /* nfsv4 minor version */ unsigned int versbits = NFSCTL_ALLBITS; unsigned int protobits = NFSCTL_ALLBITS; unsigned int proto4 = 0; unsigned int proto6 = 0; progname = strdup(basename(argv[0])); if (!progname) { fprintf(stderr, "%s: unable to allocate memory.\n", argv[0]); exit(1); } port = strdup("nfs"); if (!port) { fprintf(stderr, "%s: unable to allocate memory.\n", progname); exit(1); } xlog_syslog(0); xlog_stderr(1); while ((c = getopt_long(argc, argv, "dH:hN:p:P:sTU", longopts, NULL)) != EOF) { switch(c) { case 'd': xlog_config(D_ALL, 1); break; case 'H': /* * for now, this only handles one -H option. Use the * last one specified. */ free(haddr); haddr = strdup(optarg); if (!haddr) { fprintf(stderr, "%s: unable to allocate " "memory.\n", progname); exit(1); } break; case 'P': /* XXX for nfs-server compatibility */ case 'p': /* only the last -p option has any effect */ portnum = atoi(optarg); if (portnum <= 0 || portnum > 65535) { fprintf(stderr, "%s: bad port number: %s\n", progname, optarg); usage(progname); } free(port); port = strdup(optarg); if (!port) { fprintf(stderr, "%s: unable to allocate " "memory.\n", progname); exit(1); } break; case 'N': switch((c = strtol(optarg, &p, 0))) { case 4: if (*p == '.') { minorvers4 = -atoi(p + 1); break; } case 3: case 2: NFSCTL_VERUNSET(versbits, c); break; default: fprintf(stderr, "%s: Unsupported version\n", optarg); exit(1); } break; case 's': xlog_syslog(1); xlog_stderr(0); break; case 'T': NFSCTL_TCPUNSET(protobits); break; case 'U': NFSCTL_UDPUNSET(protobits); break; default: fprintf(stderr, "Invalid argument: '%c'\n", c); case 'h': usage(progname); } } if (optind < argc) { if ((count = atoi(argv[optind])) < 0) { /* insane # of servers */ fprintf(stderr, "%s: invalid server count (%d), using 1\n", argv[0], count); count = 1; } else if (count == 0) { /* * don't bother setting anything else if the threads * are coming down anyway. */ socket_up = 1; goto set_threads; } } xlog_open(progname); nfsd_enable_protos(&proto4, &proto6); if (!NFSCTL_TCPISSET(protobits)) { NFSCTL_TCPUNSET(proto4); NFSCTL_TCPUNSET(proto6); } if (!NFSCTL_UDPISSET(protobits)) { NFSCTL_UDPUNSET(proto4); NFSCTL_UDPUNSET(proto6); } /* make sure that at least one version is enabled */ found_one = 0; for (c = NFSD_MINVERS; c <= NFSD_MAXVERS; c++) { if (NFSCTL_VERISSET(versbits, c)) found_one = 1; } if (!found_one) { xlog(L_ERROR, "no version specified"); exit(1); } if (NFSCTL_VERISSET(versbits, 4) && !NFSCTL_TCPISSET(proto4) && !NFSCTL_TCPISSET(proto6)) { xlog(L_ERROR, "version 4 requires the TCP protocol"); exit(1); } if (chdir(NFS_STATEDIR)) { xlog(L_ERROR, "chdir(%s) failed: %m", NFS_STATEDIR); exit(1); } /* make sure nfsdfs is mounted if it's available */ nfssvc_mount_nfsdfs(progname); /* can only change number of threads if nfsd is already up */ if (nfssvc_inuse()) { socket_up = 1; goto set_threads; } /* * must set versions before the fd's so that the right versions get * registered with rpcbind. Note that on older kernels w/o the right * interfaces, these are a no-op. */ nfssvc_setvers(versbits, minorvers4); error = nfssvc_set_sockets(AF_INET, proto4, haddr, port); if (!error) socket_up = 1; #ifdef IPV6_SUPPORTED error = nfssvc_set_sockets(AF_INET6, proto6, haddr, port); if (!error) socket_up = 1; #endif /* IPV6_SUPPORTED */ set_threads: /* don't start any threads if unable to hand off any sockets */ if (!socket_up) { xlog(L_ERROR, "unable to set any sockets for nfsd"); goto out; } error = 0; /* * KLUDGE ALERT: * Some kernels let nfsd kernel threads inherit open files * from the program that spawns them (i.e. us). So close * everything before spawning kernel threads. --Chip */ fd = open("/dev/null", O_RDWR); if (fd == -1) xlog(L_ERROR, "Unable to open /dev/null: %m"); else { /* switch xlog output to syslog since stderr is being closed */ xlog_syslog(1); xlog_stderr(0); (void) dup2(fd, 0); (void) dup2(fd, 1); (void) dup2(fd, 2); } closeall(3); if ((error = nfssvc_threads(portnum, count)) < 0) xlog(L_ERROR, "error starting threads: errno %d (%m)", errno); out: free(port); free(haddr); free(progname); return (error != 0); }
/* * Called by proc_exit() when a zone's init exits, presumably because * it failed. As long as the given zone is still in the "running" * state, we will re-exec() init, but first we need to reset things * which are usually inherited across exec() but will break init's * assumption that it is being exec()'d from a virgin process. Most * importantly this includes closing all file descriptors (exec only * closes those marked close-on-exec) and resetting signals (exec only * resets handled signals, and we need to clear any signals which * killed init). Anything else that exec(2) says would be inherited, * but would affect the execution of init, needs to be reset. */ static int restart_init(int what, int why) { kthread_t *t = curthread; klwp_t *lwp = ttolwp(t); proc_t *p = ttoproc(t); user_t *up = PTOU(p); vnode_t *oldcd, *oldrd; int i, err; char reason_buf[64]; /* * Let zone admin (and global zone admin if this is for a non-global * zone) know that init has failed and will be restarted. */ zcmn_err(p->p_zone->zone_id, CE_WARN, "init(1M) %s: restarting automatically", exit_reason(reason_buf, sizeof (reason_buf), what, why)); if (!INGLOBALZONE(p)) { cmn_err(CE_WARN, "init(1M) for zone %s (pid %d) %s: " "restarting automatically", p->p_zone->zone_name, p->p_pid, reason_buf); } /* * Remove any fpollinfo_t's for this (last) thread from our file * descriptors so closeall() can ASSERT() that they're all gone. * Then close all open file descriptors in the process. */ pollcleanup(); closeall(P_FINFO(p)); /* * Grab p_lock and begin clearing miscellaneous global process * state that needs to be reset before we exec the new init(1M). */ mutex_enter(&p->p_lock); prbarrier(p); p->p_flag &= ~(SKILLED | SEXTKILLED | SEXITING | SDOCORE); up->u_cmask = CMASK; sigemptyset(&t->t_hold); sigemptyset(&t->t_sig); sigemptyset(&t->t_extsig); sigemptyset(&p->p_sig); sigemptyset(&p->p_extsig); sigdelq(p, t, 0); sigdelq(p, NULL, 0); if (p->p_killsqp) { siginfofree(p->p_killsqp); p->p_killsqp = NULL; } /* * Reset any signals that are ignored back to the default disposition. * Other u_signal members will be cleared when exec calls sigdefault(). */ for (i = 1; i < NSIG; i++) { if (up->u_signal[i - 1] == SIG_IGN) { up->u_signal[i - 1] = SIG_DFL; sigemptyset(&up->u_sigmask[i - 1]); } } /* * Clear the current signal, any signal info associated with it, and * any signal information from contracts and/or contract templates. */ lwp->lwp_cursig = 0; lwp->lwp_extsig = 0; if (lwp->lwp_curinfo != NULL) { siginfofree(lwp->lwp_curinfo); lwp->lwp_curinfo = NULL; } lwp_ctmpl_clear(lwp); /* * Reset both the process root directory and the current working * directory to the root of the zone just as we do during boot. */ VN_HOLD(p->p_zone->zone_rootvp); oldrd = up->u_rdir; up->u_rdir = p->p_zone->zone_rootvp; VN_HOLD(p->p_zone->zone_rootvp); oldcd = up->u_cdir; up->u_cdir = p->p_zone->zone_rootvp; if (up->u_cwd != NULL) { refstr_rele(up->u_cwd); up->u_cwd = NULL; } mutex_exit(&p->p_lock); if (oldrd != NULL) VN_RELE(oldrd); if (oldcd != NULL) VN_RELE(oldcd); /* Free the controlling tty. (freectty() always assumes curproc.) */ ASSERT(p == curproc); (void) freectty(B_TRUE); /* * Now exec() the new init(1M) on top of the current process. If we * succeed, the caller will treat this like a successful system call. * If we fail, we issue messages and the caller will proceed with exit. */ err = exec_init(p->p_zone->zone_initname, NULL); if (err == 0) return (0); zcmn_err(p->p_zone->zone_id, CE_WARN, "failed to restart init(1M) (err=%d): system reboot required", err); if (!INGLOBALZONE(p)) { cmn_err(CE_WARN, "failed to restart init(1M) for zone %s " "(pid %d, err=%d): zoneadm(1M) boot required", p->p_zone->zone_name, p->p_pid, err); } return (-1); }
/* * Return value: * 1 - exitlwps() failed, call (or continue) lwp_exit() * 0 - restarting init. Return through system call path */ int proc_exit(int why, int what) { kthread_t *t = curthread; klwp_t *lwp = ttolwp(t); proc_t *p = ttoproc(t); zone_t *z = p->p_zone; timeout_id_t tmp_id; int rv; proc_t *q; task_t *tk; vnode_t *exec_vp, *execdir_vp, *cdir, *rdir; sigqueue_t *sqp; lwpdir_t *lwpdir; uint_t lwpdir_sz; tidhash_t *tidhash; uint_t tidhash_sz; ret_tidhash_t *ret_tidhash; refstr_t *cwd; hrtime_t hrutime, hrstime; int evaporate; /* * Stop and discard the process's lwps except for the current one, * unless some other lwp beat us to it. If exitlwps() fails then * return and the calling lwp will call (or continue in) lwp_exit(). */ proc_is_exiting(p); if (exitlwps(0) != 0) return (1); mutex_enter(&p->p_lock); if (p->p_ttime > 0) { /* * Account any remaining ticks charged to this process * on its way out. */ (void) task_cpu_time_incr(p->p_task, p->p_ttime); p->p_ttime = 0; } mutex_exit(&p->p_lock); DTRACE_PROC(lwp__exit); DTRACE_PROC1(exit, int, why); /* * Will perform any brand specific proc exit processing, since this * is always the last lwp, will also perform lwp_exit and free brand * data */ if (PROC_IS_BRANDED(p)) { lwp_detach_brand_hdlrs(lwp); brand_clearbrand(p, B_FALSE); } /* * Don't let init exit unless zone_start_init() failed its exec, or * we are shutting down the zone or the machine. * * Since we are single threaded, we don't need to lock the * following accesses to zone_proc_initpid. */ if (p->p_pid == z->zone_proc_initpid) { if (z->zone_boot_err == 0 && zone_status_get(z) < ZONE_IS_SHUTTING_DOWN && zone_status_get(global_zone) < ZONE_IS_SHUTTING_DOWN && z->zone_restart_init == B_TRUE && restart_init(what, why) == 0) return (0); /* * Since we didn't or couldn't restart init, we clear * the zone's init state and proceed with exit * processing. */ z->zone_proc_initpid = -1; } lwp_pcb_exit(); /* * Allocate a sigqueue now, before we grab locks. * It will be given to sigcld(), below. * Special case: If we will be making the process disappear * without a trace because it is either: * * an exiting SSYS process, or * * a posix_spawn() vfork child who requests it, * we don't bother to allocate a useless sigqueue. */ evaporate = (p->p_flag & SSYS) || ((p->p_flag & SVFORK) && why == CLD_EXITED && what == _EVAPORATE); if (!evaporate) sqp = kmem_zalloc(sizeof (sigqueue_t), KM_SLEEP); /* * revoke any doors created by the process. */ if (p->p_door_list) door_exit(); /* * Release schedctl data structures. */ if (p->p_pagep) schedctl_proc_cleanup(); /* * make sure all pending kaio has completed. */ if (p->p_aio) aio_cleanup_exit(); /* * discard the lwpchan cache. */ if (p->p_lcp != NULL) lwpchan_destroy_cache(0); /* * Clean up any DTrace helper actions or probes for the process. */ if (p->p_dtrace_helpers != NULL) { ASSERT(dtrace_helpers_cleanup != NULL); (*dtrace_helpers_cleanup)(); } /* untimeout the realtime timers */ if (p->p_itimer != NULL) timer_exit(); if ((tmp_id = p->p_alarmid) != 0) { p->p_alarmid = 0; (void) untimeout(tmp_id); } /* * Remove any fpollinfo_t's for this (last) thread from our file * descriptors so closeall() can ASSERT() that they're all gone. */ pollcleanup(); if (p->p_rprof_cyclic != CYCLIC_NONE) { mutex_enter(&cpu_lock); cyclic_remove(p->p_rprof_cyclic); mutex_exit(&cpu_lock); } mutex_enter(&p->p_lock); /* * Clean up any DTrace probes associated with this process. */ if (p->p_dtrace_probes) { ASSERT(dtrace_fasttrap_exit_ptr != NULL); dtrace_fasttrap_exit_ptr(p); } while ((tmp_id = p->p_itimerid) != 0) { p->p_itimerid = 0; mutex_exit(&p->p_lock); (void) untimeout(tmp_id); mutex_enter(&p->p_lock); } lwp_cleanup(); /* * We are about to exit; prevent our resource associations from * being changed. */ pool_barrier_enter(); /* * Block the process against /proc now that we have really * acquired p->p_lock (to manipulate p_tlist at least). */ prbarrier(p); sigfillset(&p->p_ignore); sigemptyset(&p->p_siginfo); sigemptyset(&p->p_sig); sigemptyset(&p->p_extsig); sigemptyset(&t->t_sig); sigemptyset(&t->t_extsig); sigemptyset(&p->p_sigmask); sigdelq(p, t, 0); lwp->lwp_cursig = 0; lwp->lwp_extsig = 0; p->p_flag &= ~(SKILLED | SEXTKILLED); if (lwp->lwp_curinfo) { siginfofree(lwp->lwp_curinfo); lwp->lwp_curinfo = NULL; } t->t_proc_flag |= TP_LWPEXIT; ASSERT(p->p_lwpcnt == 1 && p->p_zombcnt == 0); prlwpexit(t); /* notify /proc */ lwp_hash_out(p, t->t_tid); prexit(p); p->p_lwpcnt = 0; p->p_tlist = NULL; sigqfree(p); term_mstate(t); p->p_mterm = gethrtime(); exec_vp = p->p_exec; execdir_vp = p->p_execdir; p->p_exec = NULLVP; p->p_execdir = NULLVP; mutex_exit(&p->p_lock); pr_free_watched_pages(p); closeall(P_FINFO(p)); /* Free the controlling tty. (freectty() always assumes curproc.) */ ASSERT(p == curproc); (void) freectty(B_TRUE); #if defined(__sparc) if (p->p_utraps != NULL) utrap_free(p); #endif if (p->p_semacct) /* IPC semaphore exit */ semexit(p); rv = wstat(why, what); acct(rv & 0xff); exacct_commit_proc(p, rv); /* * Release any resources associated with C2 auditing */ if (AU_AUDITING()) { /* * audit exit system call */ audit_exit(why, what); } /* * Free address space. */ relvm(); if (exec_vp) { /* * Close this executable which has been opened when the process * was created by getproc(). */ (void) VOP_CLOSE(exec_vp, FREAD, 1, (offset_t)0, CRED(), NULL); VN_RELE(exec_vp); } if (execdir_vp) VN_RELE(execdir_vp); /* * Release held contracts. */ contract_exit(p); /* * Depart our encapsulating process contract. */ if ((p->p_flag & SSYS) == 0) { ASSERT(p->p_ct_process); contract_process_exit(p->p_ct_process, p, rv); } /* * Remove pool association, and block if requested by pool_do_bind. */ mutex_enter(&p->p_lock); ASSERT(p->p_pool->pool_ref > 0); atomic_add_32(&p->p_pool->pool_ref, -1); p->p_pool = pool_default; /* * Now that our address space has been freed and all other threads * in this process have exited, set the PEXITED pool flag. This * tells the pools subsystems to ignore this process if it was * requested to rebind this process to a new pool. */ p->p_poolflag |= PEXITED; pool_barrier_exit(); mutex_exit(&p->p_lock); mutex_enter(&pidlock); /* * Delete this process from the newstate list of its parent. We * will put it in the right place in the sigcld in the end. */ delete_ns(p->p_parent, p); /* * Reassign the orphans to the next of kin. * Don't rearrange init's orphanage. */ if ((q = p->p_orphan) != NULL && p != proc_init) { proc_t *nokp = p->p_nextofkin; for (;;) { q->p_nextofkin = nokp; if (q->p_nextorph == NULL) break; q = q->p_nextorph; } q->p_nextorph = nokp->p_orphan; nokp->p_orphan = p->p_orphan; p->p_orphan = NULL; } /* * Reassign the children to init. * Don't try to assign init's children to init. */ if ((q = p->p_child) != NULL && p != proc_init) { struct proc *np; struct proc *initp = proc_init; boolean_t setzonetop = B_FALSE; if (!INGLOBALZONE(curproc)) setzonetop = B_TRUE; pgdetach(p); do { np = q->p_sibling; /* * Delete it from its current parent new state * list and add it to init new state list */ delete_ns(q->p_parent, q); q->p_ppid = 1; q->p_pidflag &= ~(CLDNOSIGCHLD | CLDWAITPID); if (setzonetop) { mutex_enter(&q->p_lock); q->p_flag |= SZONETOP; mutex_exit(&q->p_lock); } q->p_parent = initp; /* * Since q will be the first child, * it will not have a previous sibling. */ q->p_psibling = NULL; if (initp->p_child) { initp->p_child->p_psibling = q; } q->p_sibling = initp->p_child; initp->p_child = q; if (q->p_proc_flag & P_PR_PTRACE) { mutex_enter(&q->p_lock); sigtoproc(q, NULL, SIGKILL); mutex_exit(&q->p_lock); } /* * sigcld() will add the child to parents * newstate list. */ if (q->p_stat == SZOMB) sigcld(q, NULL); } while ((q = np) != NULL); p->p_child = NULL; ASSERT(p->p_child_ns == NULL); } TRACE_1(TR_FAC_PROC, TR_PROC_EXIT, "proc_exit: %p", p); mutex_enter(&p->p_lock); CL_EXIT(curthread); /* tell the scheduler that curthread is exiting */ /* * Have our task accummulate our resource usage data before they * become contaminated by p_cacct etc., and before we renounce * membership of the task. * * We do this regardless of whether or not task accounting is active. * This is to avoid having nonsense data reported for this task if * task accounting is subsequently enabled. The overhead is minimal; * by this point, this process has accounted for the usage of all its * LWPs. We nonetheless do the work here, and under the protection of * pidlock, so that the movement of the process's usage to the task * happens at the same time as the removal of the process from the * task, from the point of view of exacct_snapshot_task_usage(). */ exacct_update_task_mstate(p); hrutime = mstate_aggr_state(p, LMS_USER); hrstime = mstate_aggr_state(p, LMS_SYSTEM); p->p_utime = (clock_t)NSEC_TO_TICK(hrutime) + p->p_cutime; p->p_stime = (clock_t)NSEC_TO_TICK(hrstime) + p->p_cstime; p->p_acct[LMS_USER] += p->p_cacct[LMS_USER]; p->p_acct[LMS_SYSTEM] += p->p_cacct[LMS_SYSTEM]; p->p_acct[LMS_TRAP] += p->p_cacct[LMS_TRAP]; p->p_acct[LMS_TFAULT] += p->p_cacct[LMS_TFAULT]; p->p_acct[LMS_DFAULT] += p->p_cacct[LMS_DFAULT]; p->p_acct[LMS_KFAULT] += p->p_cacct[LMS_KFAULT]; p->p_acct[LMS_USER_LOCK] += p->p_cacct[LMS_USER_LOCK]; p->p_acct[LMS_SLEEP] += p->p_cacct[LMS_SLEEP]; p->p_acct[LMS_WAIT_CPU] += p->p_cacct[LMS_WAIT_CPU]; p->p_acct[LMS_STOPPED] += p->p_cacct[LMS_STOPPED]; p->p_ru.minflt += p->p_cru.minflt; p->p_ru.majflt += p->p_cru.majflt; p->p_ru.nswap += p->p_cru.nswap; p->p_ru.inblock += p->p_cru.inblock; p->p_ru.oublock += p->p_cru.oublock; p->p_ru.msgsnd += p->p_cru.msgsnd; p->p_ru.msgrcv += p->p_cru.msgrcv; p->p_ru.nsignals += p->p_cru.nsignals; p->p_ru.nvcsw += p->p_cru.nvcsw; p->p_ru.nivcsw += p->p_cru.nivcsw; p->p_ru.sysc += p->p_cru.sysc; p->p_ru.ioch += p->p_cru.ioch; p->p_stat = SZOMB; p->p_proc_flag &= ~P_PR_PTRACE; p->p_wdata = what; p->p_wcode = (char)why; cdir = PTOU(p)->u_cdir; rdir = PTOU(p)->u_rdir; cwd = PTOU(p)->u_cwd; ASSERT(cdir != NULL || p->p_parent == &p0); /* * Release resource controls, as they are no longer enforceable. */ rctl_set_free(p->p_rctls); /* * Decrement tk_nlwps counter for our task.max-lwps resource control. * An extended accounting record, if that facility is active, is * scheduled to be written. We cannot give up task and project * membership at this point because that would allow zombies to escape * from the max-processes resource controls. Zombies stay in their * current task and project until the process table slot is released * in freeproc(). */ tk = p->p_task; mutex_enter(&p->p_zone->zone_nlwps_lock); tk->tk_nlwps--; tk->tk_proj->kpj_nlwps--; p->p_zone->zone_nlwps--; mutex_exit(&p->p_zone->zone_nlwps_lock); /* * Clear the lwp directory and the lwpid hash table * now that /proc can't bother us any more. * We free the memory below, after dropping p->p_lock. */ lwpdir = p->p_lwpdir; lwpdir_sz = p->p_lwpdir_sz; tidhash = p->p_tidhash; tidhash_sz = p->p_tidhash_sz; ret_tidhash = p->p_ret_tidhash; p->p_lwpdir = NULL; p->p_lwpfree = NULL; p->p_lwpdir_sz = 0; p->p_tidhash = NULL; p->p_tidhash_sz = 0; p->p_ret_tidhash = NULL; /* * If the process has context ops installed, call the exit routine * on behalf of this last remaining thread. Normally exitpctx() is * called during thread_exit() or lwp_exit(), but because this is the * last thread in the process, we must call it here. By the time * thread_exit() is called (below), the association with the relevant * process has been lost. * * We also free the context here. */ if (p->p_pctx) { kpreempt_disable(); exitpctx(p); kpreempt_enable(); freepctx(p, 0); } /* * curthread's proc pointer is changed to point to the 'sched' * process for the corresponding zone, except in the case when * the exiting process is in fact a zsched instance, in which * case the proc pointer is set to p0. We do so, so that the * process still points at the right zone when we call the VN_RELE() * below. * * This is because curthread's original proc pointer can be freed as * soon as the child sends a SIGCLD to its parent. We use zsched so * that for user processes, even in the final moments of death, the * process is still associated with its zone. */ if (p != t->t_procp->p_zone->zone_zsched) t->t_procp = t->t_procp->p_zone->zone_zsched; else t->t_procp = &p0; mutex_exit(&p->p_lock); if (!evaporate) { p->p_pidflag &= ~CLDPEND; sigcld(p, sqp); } else { /* * Do what sigcld() would do if the disposition * of the SIGCHLD signal were set to be ignored. */ cv_broadcast(&p->p_srwchan_cv); freeproc(p); } mutex_exit(&pidlock); /* * We don't release u_cdir and u_rdir until SZOMB is set. * This protects us against dofusers(). */ if (cdir) VN_RELE(cdir); if (rdir) VN_RELE(rdir); if (cwd) refstr_rele(cwd); /* * task_rele() may ultimately cause the zone to go away (or * may cause the last user process in a zone to go away, which * signals zsched to go away). So prior to this call, we must * no longer point at zsched. */ t->t_procp = &p0; kmem_free(lwpdir, lwpdir_sz * sizeof (lwpdir_t)); kmem_free(tidhash, tidhash_sz * sizeof (tidhash_t)); while (ret_tidhash != NULL) { ret_tidhash_t *next = ret_tidhash->rth_next; kmem_free(ret_tidhash->rth_tidhash, ret_tidhash->rth_tidhash_sz * sizeof (tidhash_t)); kmem_free(ret_tidhash, sizeof (*ret_tidhash)); ret_tidhash = next; } thread_exit(); /* NOTREACHED */ }
int main ( int argc, char **argv ) { int n, m, ndx1a, ndx1b, ndx2a, ndx2b, fdin1 = 0, fdin2 = 0, fdout = 0; char buf1[ BUFSZ ], buf2[ BUFSZ ]; char ch = '\n'; if ( argc < 3 ){ write( STDERR_FILENO, "Usage: ",7 ); write( STDERR_FILENO, argv[0],strlen(argv[0]) ); write( STDERR_FILENO, " <file1> <file2> [file.out]\n",28 ); exit(-1); } if ( ( strcmp(argv[1], "-") == 0 ) && ( strcmp(argv[2], "-") == 0) ){ write( STDERR_FILENO, "Error: file1 and file2 cannot both be -\n", 40); exit(-1); } if ( strcmp(argv[1], "-") == 0 ){ fdin1 = STDIN_FILENO; }else if( ( fdin1 = open( argv[1], O_RDONLY ) ) < 0 ){ perror( argv[1] ); closeall( fdin1,fdin2,fdout ); exit( -1 ); } if ( strcmp(argv[2],"-") == 0){ fdin2 = STDIN_FILENO; }else if( ( fdin2 = open(argv[2], O_RDONLY ) ) < 0 ){ perror( argv[2] ); closeall( fdin1, fdin2, fdout ); exit( -1 ); } if ( argc == 4 ){ if ( ( fdout = open( argv[3],O_WRONLY | O_APPEND | O_TRUNC | O_CREAT, 0666 ) ) < 0){ perror( argv[3] ); closeall( fdin1, fdin2, fdout ); exit( -1 ); } }else{ fdout = STDOUT_FILENO; } while ( ( n = read( fdin1, buf1, BUFSZ ) ) > 0 && ( m = read( fdin2, buf2, BUFSZ ) ) > 0 ){ ndx1a = 0, ndx1b = 0, ndx2a = 0, ndx2b = 0; /* If the buf1's or buf2's forward ndx (ndx1a and ndx2a respectively) are less than * the location of the data read in for each buffer (n and m respectively), then * the loop is entered. Inside the loop, must still test to see which buffer has * data in it, hence the if statements. */ while ( ndx1a < n || ndx2a < m ){ if ( ndx1a < n ){ /* Previous index ( last char to be read in ) is stored by ndx1b and * ndx2b. Before write anything, the forward index gets passed to the * back index. */ ndx1b = ndx1a; for( ; ndx1a < n ; ndx1a++ ){ if( buf1[ ndx1a ] == ch ){ ndx1a++; break; } } if ( write( fdout, &buf1[ ndx1b ], ( &buf1[ ndx1a ] - &buf1[ ndx1b ] ) ) != ( &buf1[ ndx1a ] - &buf1[ ndx1b ] ) ){ perror( argv[3] ); closeall( fdin1, fdin2, fdout ); exit( -1 ); } } if ( ndx2a < m ){ ndx2b = ndx2a; for ( ; ndx2a < m ; ndx2a++ ){ if ( buf2[ ndx2a ] == ch ){; ndx2a++; break; } } if ( write( fdout, &buf2[ ndx2b ], ( &buf2[ ndx2a ] - &buf2[ ndx2b ] ) ) != ( &buf2[ ndx2a ] - &buf2[ ndx2b ] ) ){ perror( argv[3] ); closeall( fdin1, fdin2, fdout ); exit( -1 ); } } } } if ( n < 0 || m < 0 ){ perror ( "read error" ); closeall( fdin1, fdin2, fdout ); exit( -1 ); } if ( n > 0 ){ if ( write( fdout, buf1, n ) != n ){ perror( argv[ 3 ] ); closeall( fdin1, fdin2, fdout ); exit( -1 ); } while ( (n = read( fdin1, buf1, BUFSZ ) ) > 0 ){ if ( write( fdout, buf1, n ) != n ){ perror ( argv[ 3 ] ); closeall( fdin1, fdin2, fdout ); exit( -1 ); } } if ( n < 0 ){ perror ( "read error" ); closeall( fdin1, fdin2, fdout ); exit( -1 ); } } if ( m > 0 ){ if ( write( fdout, buf2, m ) != m ){ perror ( argv[ 3 ] ); closeall( fdin1, fdin2, fdout ); exit( -1 ); } while ( ( m = read( fdin2, buf2, BUFSZ ) ) > 0 ){ if ( write( fdout, buf2, m ) != m ){ perror( argv[ 3 ] ); closeall( fdin1, fdin2, fdout ); exit( -1 ); } } if ( m < 0 ){ perror ( "read error" ); closeall( fdin1, fdin2, fdout ); exit( -1 ); } } closeall( fdin1, fdin2, fdout ); exit( 0 ); }