void set_callback (STREAM *h, STREAM_FN call) { int i; for (i = 0; i < nfds; i++) { if (readfd(callback_handles [i]) == readfd(h)) { if (call == NULL) { if (nfds > 1) { callback_handles [i] = callback_handles [nfds-1]; callback_array [i] = callback_array [nfds-1]; } else { callback_handles [i] = NULL; callback_array [i] = NULL; } nfds --; } else { callback_array [i] = call; } return; } } callback_array [nfds] = call; callback_handles [nfds] = h; nfds ++; }
struct fileComp* comparefds(int fd1, int fd2) { struct fileComp* fc = malloc(sizeof(struct fileComp)); if(!fc) { printf("Could not allocate space for file contents\n"); exit(EXIT_FAILURE); } strcpy(fc->fileContents1, readfd(fd1)); strcpy(fc->fileContents2, readfd(fd2)); fc->cmp = strcmp(fc->fileContents1, fc->fileContents2); return fc; }
int main(int argc, char *argv[]) { int opt; while((opt = getopt_long(argc, argv, short_options, long_options, NULL)) >= 0) { switch(opt) { case 'r': sort_reverse = 1; break; case 'h': default: usage(basename(argv[0])); exit(EXIT_FAILURE); } } readfd(0); //stdin makeindex(); qsort(ver_index, index_nmemb, sizeof(char *), vercmpp); printindex(); free(ver_index); free(buffer); exit(EXIT_SUCCESS); }
rt_public void app_tpipe(STREAM *stream) { /* Initialize the file descriptor to be used in data exchanges with the * remote process. This enables us to omit this parameter whenever an I/O * with the remote process has to be made. */ if (app_sp != NULL) { unregister_packet_functions (app_sp); close_stream (app_sp); } if (stream != NULL) { app_sp = stream; register_packet_functions (app_sp, &app_send_packet, &app_recv_packet); } else { app_sp = (STREAM *) 0; }; #ifdef DEBUG #ifdef USE_ADD_LOG add_log(20, "stream set up as (rd = #%d, wr = #%d)", readfd(app_sp), writefd(app_sp)); #endif #endif }
Pipe::Pipe(const CloseOnExec& close_on_exec) { #ifdef HAVE_PIPE2 if(0 != pipe2(fd_, O_CLOEXEC)) { this->close(); // not sure if call to close matters here throw std::runtime_error("could not create pipe"); } #else if(0 != pipe(fd_)) { this->close(); // not sure if call to close matters here throw std::runtime_error("could not create pipe"); } if(CLOSE_ON_EXEC == close_on_exec) { if(-1 == fcntl(readfd(), F_SETFD, FD_CLOEXEC) || -1 == fcntl(writefd(), F_SETFD, FD_CLOEXEC)) { this->close(); throw std::runtime_error("could not set FD_CLOEXEC on pipe"); } } #endif }
int main (int argc, char **argv) { setprogname (argv[0]); if (!isunixsocket (0)) fatal << "stdin must be a unix domain socket\n"; if (argc < 2) fatal << "usage: " << progname << " command [arg1 arg2 ... ]\n"; char **cmdargv = argv + 1; str path = find_program_plus_libsfs (cmdargv[0]); if (!path) fatal << "Could not locate program: " << cmdargv[0] << "\n"; make_sync (0); char buf[1024]; int fd; while (readfd (0, buf, 1024, &fd) > 0) if (fd >= 0) { aspawn (path, cmdargv, fd, fd, errfd); close (fd); } return 0; }
static int recvfd (int fd) { int nfd = -1; char c; readfd (fd, &c, 1, &nfd); return nfd; }
int mcpRead(int fd, void *ptr, unsigned int nbytes) { char *buf = (char *) ptr; int nread = readfd(fd, buf, nbytes); return nread; }
int my_receivefd(int fd) { int passed_fd = -42; if (readfd(fd, &passed_fd) < 0) { return -1; } else { return passed_fd; } }
u16 getblk(u16 blk, char buf[ ]) { int cyl, head, sector; // convert blk to CHS; cyl = blk / 18; head = blk / 9; head = head % 2; sector = blk % 9; sector = sector * 2; readfd(cyl, head, sector, buf); }
int main(int argc, char **argv) { int bufsz = 1024 * 1024; void *buf; HC_ALLOC(buf, bufsz); fprintf(stderr, "total bytes read: %i\n", readfd(0 /* STDIN */, buf, bufsz, doit)); HC_FREE(buf); return 0; }
void unixfd::rcb () { if (reof) { fdcb (localfd_in, selread, NULL); return; } char buf[16*1024]; int fdrecved = -1; ssize_t n; if (unixsock) n = readfd (localfd_in, buf, sizeof (buf), &fdrecved); else n = read (localfd_in, buf, sizeof (buf)); if (n < 0) { if (errno != EAGAIN) abort (); return; } if (!n) { readeof (); return; } else { rex_payload arg; arg.channel = channo; arg.fd = fd; arg.data.set (buf, n); if (fdrecved >= 0) { close_on_exec (fdrecved); rex_newfd_arg arg; arg.channel = channo; arg.fd = fd; ref<rex_newfd_res> resp (New refcounted<rex_newfd_res> (false)); proxy->call (REX_NEWFD, &arg, resp, wrap (mkref (this), &unixfd::newfdcb, fdrecved, resp)); } ref<bool> pres (New refcounted<bool> (false)); rsize += n; proxy->call (REX_DATA, &arg, pres, wrap (mkref (this), &unixfd::datacb, n, pres)); } if (rsize >= hiwat) fdcb (localfd_in, selread, NULL); }
bool EnableRDS(uint32_t aMask) { if (!sRadioEnabled || !sRDSSupported) return false; if (sMsmFMMode) setControl(V4L2_CID_PRIVATE_TAVARUA_RDSGROUP_MASK, aMask); if (sRDSEnabled) return true; int pipefd[2]; int rc = pipe2(pipefd, O_NONBLOCK); if (rc < 0) { HAL_LOG("Could not create RDS thread signaling pipes (%d)", rc); return false; } ScopedClose writefd(pipefd[1]); ScopedClose readfd(pipefd[0]); rc = setControl(V4L2_CID_RDS_RECEPTION, true); if (rc < 0) { HAL_LOG("Could not enable RDS reception (%d)", rc); return false; } sRDSPipeFD = writefd; sRDSEnabled = true; rc = pthread_create(&sRDSThread, nullptr, readRDSDataThread, (void*)pipefd[0]); if (rc) { HAL_LOG("Could not start RDS reception thread (%d)", rc); setControl(V4L2_CID_RDS_RECEPTION, false); sRDSEnabled = false; return false; } readfd.forget(); writefd.forget(); return true; }
void chanfd::rcb (int fdn) { rex_payload data; data.channel = channo; data.fd = fdn; char buf[16*1024]; bool fdrecved = false; size_t numbytes = 0; ssize_t n = fdi[fdn].isunixsocket ? readfd (fdn, buf, sizeof (buf), fdrecved): readmore (fdi[fdn].fd, buf, sizeof (buf), numbytes); if (fdi[fdn].isunixsocket && n >= 0) numbytes = n; // warn << "isunixsocket = " << (fdi[fdn].isunixsocket ? "YES" : "NO") // << "; numbytes = " << numbytes << "\n"; if (numbytes > 0) { data.data.set (buf, numbytes); fdi[fdn].rsize += numbytes; if (fdi[fdn].rsize >= hiwat) disablercb (fdn); ref<bool> okp (New refcounted<bool> (false)); c->call (REXCB_DATA, &data, okp, wrap (this, &chanfd::ccb, fdn, numbytes, destroyed, okp)); } if (n < 0 && errno == EAGAIN) return; if (n <= 0) { if (fdrecved) return; if (n < 0) warn ("chanfd::rcb:read(%d), rexfd:%d: %m\n", fdi[fdn].fd, fdn); data.data.clear (); fdi[fdn].reof = true; disablercb (fdn); c->call (REXCB_DATA, &data, &garbage_bool, aclnt_cb_null); } }
rt_public int has_input(EIF_PSTREAM sp) { /* Returns 1 if the associated 'fd' has an input callback recorded, 0 if * the file is not selected, and -1 in case of error. */ #ifdef EIF_WINDOWS if (callback(sp) != NULL) return 1; #else int fd = readfd(sp); if (fd < 0 || fd >= NOFILE) { /* File descriptor out of range */ s_errno = S_FDESC; /* Invalid file descriptor */ return -1; } if (callback[fd] != NULL) { return 1; } #endif return 0; /* This file is not selected any more */ }
///@brief This function is responsible for receiving the block information from the disk ///@param blk This should be an integer (u16) that denotes the block number that is being received ///@param buf This is a string that the block information will be stored into ///@returns This will return a 0 for success and readfd will print if error u16 getBlock(u16 blk, char *buf) { readfd( blk / 18, ( blk % 18 ) / 9, ( ( blk % 18 ) % 9 ) << 1, buf); //this function is defined in bs.s, it will get the block info and put it into buf return 0; //signify succesful completion }
//return 0: continue, //return -1(<0): error //return 1(>0): exit success static inline int init_command(App & app, const char * pidfile){ int ret = 0; if (app.cmdopt().hasopt("stop")){ if (!pidfile){ fprintf(stderr, "lacking command line option pid-file ...\n"); return -1; } int killpid = lockpidfile(pidfile, SIGTERM, true); fprintf(stderr, "stoped process with normal stop mode [%d]\n", killpid); return 1; } if (app.cmdopt().hasopt("restart")){ if (!pidfile){ fprintf(stderr, "lacking command line option pid-file ...\n"); return -1; } int killpid = lockpidfile(pidfile, SIGUSR1, true); fprintf(stderr, "stoped process with restart mode [%d]\n", killpid); return 1; } if (app.cmdopt().hasopt("reload")){ if (!pidfile){ fprintf(stderr, "lacking command line option pid-file ...\n"); return -1; } int killpid = lockpidfile(pidfile, SIGUSR2, true, nullptr, true); fprintf(stderr, "reloaded process [%d]\n", killpid); return 1; } if (app.cmdopt().hasopt("console-shell")){ const char * console = app.cmdopt().getoptstr("console-listen"); if (!console){ fprintf(stderr, "has no console-listen option open console shell error !\n"); return -1; } string console_server = "tcp://"; console_server += console; printf("connecting to %s ...\n", console_server.c_str()); int confd = openfd(console_server.c_str(), "w", 3000); if (!confd){ fprintf(stderr, "connect error %s!\n", strerror(errno)); return -1; } enum { CONSOLE_BUFFER_SIZE = 1024*1024}; char * console_buffer = new char[CONSOLE_BUFFER_SIZE]; printf("console server connected ! command <quit> will exit shell\n"); while (true){ int n = readfd(confd, console_buffer, CONSOLE_BUFFER_SIZE, "token:\r\n\r\n", 1000 * 3600); if (n < 0){ fprintf(stderr, "console server closed [ret=%d]!\n", n); break; } printf("%s\n%s$", console_buffer, console); const char * command = fgets(console_buffer, CONSOLE_BUFFER_SIZE, stdin); if (strcasecmp(command, "quit") == 0){ break; } dcs::writefd(confd, command, 0, "token:\r\n\r\n"); } closefd(confd); delete console_buffer; return 1; } /////////////////////////////////////////////////////////////////// ret = _shm_command(app); if (ret < 0){ GLOG_ERR("shm command check error:%d !", ret); return -1; } if (ret > 0){ return 1; } return app.on_cmd_opt(); }
rt_public int add_input(EIF_PSTREAM sp, STREAM_FN call) /* `sp': Stream on which select must be done */ /* `call': Function to be called when input is available */ { /* Add an input condition on file descriptor 'fd', with associated call * back procedure and update internal informations. * The function returns 0 if ok, -1 otherwise (call back pointer void or * file descriptor invalid) and sets 's_errno' */ #ifdef EIF_WINDOWS if (nfds >= NOFILE) { /* File descriptor out of range */ #else int fd = readfd(sp); if (fd < 0 || fd >= NOFILE) { /* File descriptor out of range */ #endif s_errno = S_FDESC; /* Invalid file descriptor */ return -1; } if (call == NULL) { /* Null pointer for callback */ s_errno = S_CALBAK; /* Invalid callback pointer */ return -1; } #ifdef EIF_WINDOWS if (callback(sp) != NULL) { /* Callback already set */ #else if (callback[fd] != NULL) { /* Callback already set */ #endif s_errno = S_CALSET; /* Cannot override old callback */ return -1; } #ifdef EIF_WINDOWS set_callback(sp, call); /* Record callback */ set_multiple_mask(sp, rd_mask); /* Select will monitor this fd */ set_multiple_mask(sp, rd_tmask); /* Also set temporary mask */ #else if ((fd + 1) > nfds) { /* Keep number of fd up-to-date */ nfds = fd + 1; /* Fd start at 0 */ } callback[fd] = call; /* Record callback */ FD_SET(fd, &rd_mask); /* Select will monitor this fd */ FD_SET(fd, &rd_tmask); /* Also set temporary mask */ #endif return 0; /* Ok status */ } rt_public STREAM_FN new_callback(EIF_PSTREAM sp, STREAM_FN call) /* `sp': STREAM on which select must be done */ /* `call': New function to be called when input is available */ { /* Change the call back associated with the file descriptor and return the * old call back. If no input was associated with that file descriptor, * it is an error and a null pointer is returned. */ STREAM_FN old_call; /* The old call back set for that fd */ #ifdef EIF_WINDOWS if (call == NULL) { /* Null pointer for callback */ s_errno = S_CALBAK; /* Invalid callback pointer */ return NULL; } old_call = callback(sp); /* Previously stored callback address */ set_callback(sp, NULL); /* Otherwise add_input() will fail */ if (-1 == add_input(sp, call)) { /* Failed, restore old status */ set_callback(sp,old_call); /* Reset old callback value */ return NULL; /* No change occurred */ } #else int fd = readfd(sp); if (fd < 0 || fd >= NOFILE) { /* File descriptor out of range */ s_errno = S_FDESC; /* Invalid file descriptor */ return NULL; } if (call == NULL) { /* Null pointer for callback */ s_errno = S_CALBAK; /* Invalid callback pointer */ return NULL; } old_call = callback[fd]; /* Previously stored callback address */ callback[fd] = NULL; /* Otherwise add_input() will fail */ if (-1 == add_input(sp, call)) { /* Failed, restore old status */ callback[fd] = old_call; /* Reset old callback value */ return NULL; /* No change occurred */ } #endif return old_call; /* Success: return old value (cannot be null) */ }
// Gets block from disk and writes it to ES + buf u16 getblk(u16 blk, char *buf) { readfd( blk/18, ((blk*2)%36)/18, ((blk*2)%36)%18, buf); }
static char *authenticate(struct conninfo *ci) { char buf[1024]; int n; int noauth=0; int uidpw=0; D(DEBUG_CONNECT) { fprintf(stderr, "DEBUG: Connection from "); printaddr(stderr, &ci->clientaddr); fprintf(stderr, "\n"); fflush(stderr); } readfd(ci, buf, 2); if (buf[0] != 5) { fprintf(stderr, "ERR: "); printaddr(stderr, &ci->clientaddr); fprintf(stderr, " - received unknown protocol version: %d\n", (int)(unsigned char)buf[0]); fflush(stderr); exit(0); } readfd(ci, buf+2, (int)(unsigned char)buf[1]); for (n=0; n<(int)(unsigned char)buf[1]; n++) switch (buf[2+n]) { case 0: noauth=1; break; case 2: uidpw=1; break; } if (uidpw) { int uidl; int pwdl; char *pw; buf[0]=5; buf[1]=2; writefd(ci, buf, 2); readfd(ci, buf, 2); if (buf[0] != 1) { fprintf(stderr, "ERR: "); printaddr(stderr, &ci->clientaddr); fprintf(stderr, " - received unknown userid/password authentication version: %d\n", (int)(unsigned char)buf[0]); fflush(stderr); exit(0); } uidl=(int)(unsigned char)buf[1]; readfd(ci, buf, uidl+1); pw=buf+uidl; pwdl=(int)(unsigned char)*pw; *pw++=0; readfd(ci, pw, pwdl); pw[pwdl]=0; if (buf[0] == 0) { /* Empty userid - no authentication */ buf[0]=5; buf[1]=0; writefd(ci, buf, 2); D(DEBUG_CONNECT) { fprintf(stderr,"DEBUG: Empty userid - unauthenticated connection from "); printaddr(stderr, &ci->clientaddr); fprintf(stderr, "\n"); fflush(stderr); } return NULL; } if (validateuseridpw(buf, pw)) { buf[0]=5; buf[1]=1; writefd(ci, buf, 2); fprintf(stderr, "ERR: "); printaddr(stderr, &ci->clientaddr); fprintf(stderr, " - userid/password invalid.\n"); fflush(stderr); fcntl(ci->clientfd, F_SETFL, 0); close(ci->clientfd); exit(0); } pw=strdup(buf); buf[0]=5; buf[1]=0; writefd(ci, buf, 2); D(DEBUG_CONNECT) { fprintf(stderr, "DEBUG: Connection from "); printaddr(stderr, &ci->clientaddr); fprintf(stderr, " authenticated as %s\n", buf); fflush(stderr); } if (!pw) { perror("ERR: malloc"); exit(0); } return pw; }
int main(int argc, char **argv, char **environ) { #else int main(int argc, char **argv) { #endif int i, ret = EXIT_SUCCESS; pid_t pid = getpid(), wpid = 0; char **ipccommands = NULL; int pthread_errno; FILE *commandpipe_in, *commandpipe_out; int commandpipe[2]; int debugsocket[2]; char need_recovery = 0; char debug = 0; int debugme_pipe = 0; char crash_threshold = 5; char *einit_crash_data = NULL; boottime = time(NULL); uname (&osinfo); config_configure(); // initialise subsystems ipc_configure(NULL); // is this the system's init-process? isinit = getpid() == 1; event_listen (einit_event_subsystem_core, core_einit_event_handler); event_listen (einit_event_subsystem_timer, core_timer_event_handler); if (argv) einit_argv = (char **)setdup ((const void **)argv, SET_TYPE_STRING); /* check command line arguments */ for (i = 1; i < argc; i++) { if (argv[i][0] == '-') switch (argv[i][1]) { case 'c': if ((++i) < argc) einit_default_startup_configuration_files[0] = argv[i]; else return print_usage_info (); break; case 'h': return print_usage_info (); break; case 'v': eputs("eINIT " EINIT_VERSION_LITERAL "\n", stdout); return 0; case 'L': eputs("eINIT " EINIT_VERSION_LITERAL "\nThis Program is Free Software, released under the terms of this (BSD) License:\n" "--------------------------------------------------------------------------------\n" "Copyright (c) 2006, 2007, Magnus Deininger\n" BSDLICENSE "\n", stdout); return 0; case '-': if (strmatch(argv[i], "--check-configuration") || strmatch(argv[i], "--checkup") || strmatch(argv[i], "--wtf")) { ipccommands = (char **)setadd ((void **)ipccommands, "examine configuration", SET_TYPE_STRING); } else if (strmatch(argv[i], "--help")) return print_usage_info (); else if (strmatch(argv[i], "--ipc-command") && argv[i+1]) ipccommands = (char **)setadd ((void **)ipccommands, (void *)argv[i+1], SET_TYPE_STRING); else if (strmatch(argv[i], "--override-init-check")) initoverride = 1; else if (strmatch(argv[i], "--sandbox")) { einit_default_startup_configuration_files[0] = "lib/einit/einit.xml"; coremode = einit_mode_sandbox; need_recovery = 1; } else if (strmatch(argv[i], "--metadaemon")) { coremode = einit_mode_metadaemon; } else if (strmatch(argv[i], "--bootstrap-modules")) { bootstrapmodulepath = argv[i+1]; } else if (strmatch(argv[i], "--debugme")) { debugme_pipe = parse_integer (argv[i+1]); i++; initoverride = 1; } else if (strmatch(argv[i], "--debug")) { debug = 1; } break; } } /* check environment */ if (environ) { uint32_t e = 0; for (e = 0; environ[e]; e++) { char *ed = estrdup (environ[e]); char *lp = strchr (ed, '='); *lp = 0; lp++; if (strmatch (ed, "softlevel")) { einit_startup_mode_switches = str2set (':', lp); } if (strmatch (ed, "mode")) { /* override default mode-switches with the ones in the environment variable mode= */ einit_startup_mode_switches = str2set (':', lp); } else if (strmatch (ed, "einit")) { /* override default configuration files and/or mode-switches with the ones in the variable einit= */ char **tmpstrset = str2set (',', lp); uint32_t rx = 0; for (rx = 0; tmpstrset[rx]; rx++) { char **atom = str2set (':', tmpstrset[rx]); if (strmatch (atom[0], "file")) { /* specify configuration files */ einit_startup_configuration_files = (char **)setdup ((const void **)atom, SET_TYPE_STRING); einit_startup_configuration_files = (char **)strsetdel (einit_startup_configuration_files, (void *)"file"); } else if (strmatch (atom[0], "mode")) { /* specify mode-switches */ einit_startup_mode_switches = (char **)setdup ((const void **)atom, SET_TYPE_STRING); einit_startup_mode_switches = (char **)strsetdel (einit_startup_mode_switches, (void *)"mode"); } else if (strmatch (atom[0], "stfu")) { einit_quietness = 3; } else if (strmatch (atom[0], "silent")) { einit_quietness = 2; } else if (strmatch (atom[0], "quiet")) { einit_quietness = 1; } free (atom); } free (tmpstrset); } free (ed); } einit_initial_environment = (char **)setdup ((const void **)environ, SET_TYPE_STRING); } if (!einit_startup_mode_switches) einit_startup_mode_switches = einit_default_startup_mode_switches; if (!einit_startup_configuration_files) einit_startup_configuration_files = einit_default_startup_configuration_files; respawn: pipe (commandpipe); fcntl (commandpipe[1], F_SETFD, FD_CLOEXEC); socketpair (AF_UNIX, SOCK_STREAM, 0, debugsocket); fcntl (debugsocket[0], F_SETFD, FD_CLOEXEC); fcntl (debugsocket[1], F_SETFD, FD_CLOEXEC); if (!debug) { fcntl (commandpipe[0], F_SETFD, FD_CLOEXEC); commandpipe_in = fdopen (commandpipe[0], "r"); } commandpipe_out = fdopen (commandpipe[1], "w"); if (!initoverride && ((pid == 1) || ((coremode & einit_mode_sandbox) && !ipccommands))) { // if (pid == 1) { initoverride = 1; #if 0 #ifdef LINUX if ((einit_sub = syscall(__NR_clone, CLONE_PTRACE | SIGCHLD, 0, NULL, NULL, NULL)) < 0) { bitch (bitch_stdio, errno, "Could not fork()"); eputs (" !! Haven't been able to fork a secondary worker process. This is VERY bad, you will get a lot of zombie processes! (provided that things work at all)\n", stderr); } #else #endif #endif if ((einit_sub = fork()) < 0) { bitch (bitch_stdio, errno, "Could not fork()"); eputs (" !! Haven't been able to fork a secondary worker process. This is VERY bad, you will get a lot of zombie processes! (provided that things work at all)\n", stderr); } } if (einit_sub) { /* PID==1 part */ int rstatus; struct sigaction action; /* signal handlers */ action.sa_sigaction = einit_sigint; sigemptyset(&(action.sa_mask)); action.sa_flags = SA_SIGINFO | SA_RESTART | SA_NODEFER; if ( sigaction (SIGINT, &action, NULL) ) bitch (bitch_stdio, 0, "calling sigaction() failed."); /* ignore sigpipe */ action.sa_sigaction = (void (*)(int, siginfo_t *, void *))SIG_IGN; if ( sigaction (SIGPIPE, &action, NULL) ) bitch (bitch_stdio, 0, "calling sigaction() failed."); close (debugsocket[1]); if (einit_crash_data) { free (einit_crash_data); einit_crash_data = NULL; } while (1) { wpid = waitpid(-1, &rstatus, 0); /* this ought to wait for ANY process */ if (wpid == einit_sub) { // goto respawn; /* try to recover by re-booting */ if (!debug) if (commandpipe_in) fclose (commandpipe_in); if (commandpipe_out) fclose (commandpipe_out); if (WIFEXITED(rstatus) && (WEXITSTATUS(rstatus) != einit_exit_status_die_respawn)) { fprintf (stderr, "eINIT has quit properly.\n"); if (!(coremode & einit_mode_sandbox)) { if (WEXITSTATUS(rstatus) == einit_exit_status_last_rites_halt) { execl (EINIT_LIB_BASE "/bin/last-rites", EINIT_LIB_BASE "/bin/last-rites", "h", NULL); } else if (WEXITSTATUS(rstatus) == einit_exit_status_last_rites_reboot) { execl (EINIT_LIB_BASE "/bin/last-rites", EINIT_LIB_BASE "/bin/last-rites", "r", NULL); } else if (WEXITSTATUS(rstatus) == einit_exit_status_last_rites_kexec) { execl (EINIT_LIB_BASE "/bin/last-rites", EINIT_LIB_BASE "/bin/last-rites", "k", NULL); } } exit (EXIT_SUCCESS); } int n = 5; fprintf (stderr, "The secondary eINIT process has died, waiting a while before respawning.\n"); if ((einit_crash_data = readfd (debugsocket[0]))) { fprintf (stderr, " > neat, received crash data\n"); } while ((n = sleep (n))); fprintf (stderr, "Respawning secondary eINIT process.\n"); if (crash_threshold) crash_threshold--; else debug = 1; need_recovery = 1; initoverride = 0; close (debugsocket[0]); goto respawn; } else { if (commandpipe_out) { if (WIFEXITED(rstatus)) { fprintf (commandpipe_out, "pid %i terminated\n\n", wpid); } else { fprintf (commandpipe_out, "pid %i died\n\n", wpid); } fflush (commandpipe_out); } } } } else { enable_core_dumps (); close (debugsocket[0]); sched_trace_target = debugsocket[1]; if (debug) { char **xargv = (char **)setdup ((const void **)argv, SET_TYPE_STRING); char tbuffer[BUFFERSIZE]; struct stat st; char have_valgrind = 0; char have_gdb = 0; fputs ("eINIT needs to be debugged, starting in debugger mode\n.", stderr); xargv = (char **)setadd ((void **)xargv, (void *)"--debugme", SET_TYPE_STRING); snprintf (tbuffer, BUFFERSIZE, "%i", commandpipe[0]); xargv = (char **)setadd ((void **)xargv, (void *)tbuffer, SET_TYPE_STRING); xargv = strsetdel (xargv, "--debug"); // don't keep the --debug flag if (!stat ("/usr/bin/valgrind", &st)) have_valgrind = 1; if (!stat ("/usr/bin/gdb", &st)) have_gdb = 1; if (have_valgrind) { char **nargv = NULL; uint32_t i = 1; #ifdef LINUX if (!(coremode & einit_mode_sandbox)) { mount ("proc", "/proc", "proc", 0, NULL); mount ("sys", "/sys", "sysfs", 0, NULL); system ("mount / -o remount,rw"); } #endif nargv = (char **)setadd ((void **)nargv, "/usr/bin/valgrind", SET_TYPE_STRING); nargv = (char **)setadd ((void **)nargv, "--log-file=/einit.valgrind", SET_TYPE_STRING); nargv = (char **)setadd ((void **)nargv, (coremode & einit_mode_sandbox) ? "sbin/einit" : "/sbin/einit", SET_TYPE_STRING); for (; xargv[i]; i++) { nargv = (char **)setadd ((void **)nargv, xargv[i], SET_TYPE_STRING); } execv ("/usr/bin/valgrind", nargv); } else { execv ((coremode & einit_mode_sandbox) ? "sbin/einit" : "/sbin/einit", xargv); } } if (debugme_pipe) { // commandpipe[0] fcntl (commandpipe[0], F_SETFD, FD_CLOEXEC); commandpipe_in = fdopen (debugme_pipe, "r"); } /* actual system initialisation */ struct einit_event cev = evstaticinit(einit_core_update_configuration); if (ipccommands && (coremode != einit_mode_sandbox)) { coremode = einit_mode_ipconly; } eprintf (stderr, "eINIT " EINIT_VERSION_LITERAL ": Initialising: %s\n", osinfo.sysname); if ((pthread_errno = pthread_attr_init (&thread_attribute_detached))) { bitch(bitch_epthreads, pthread_errno, "pthread_attr_init() failed."); if (einit_initial_environment) free (einit_initial_environment); return -1; } else { if ((pthread_errno = pthread_attr_setdetachstate (&thread_attribute_detached, PTHREAD_CREATE_DETACHED))) { bitch(bitch_epthreads, pthread_errno, "pthread_attr_setdetachstate() failed."); } } if ((pthread_errno = pthread_key_create(&einit_function_macro_key, NULL))) { bitch(bitch_epthreads, pthread_errno, "pthread_key_create(einit_function_macro_key) failed."); if (einit_initial_environment) free (einit_initial_environment); return -1; } /* this should be a good place to initialise internal modules */ if (coremodules) { uint32_t cp = 0; eputs (" >> initialising in-core modules:", stderr); for (; coremodules[cp]; cp++) { struct lmodule *lmm; eprintf (stderr, " [%s]", (*coremodules[cp])->rid); lmm = mod_add(NULL, (*coremodules[cp])); lmm->source = estrdup("core"); } eputs (" OK\n", stderr); } /* emit events to read configuration files */ if (einit_startup_configuration_files) { uint32_t rx = 0; for (; einit_startup_configuration_files[rx]; rx++) { cev.string = einit_startup_configuration_files[rx]; event_emit (&cev, einit_event_flag_broadcast); } if (einit_startup_configuration_files != einit_default_startup_configuration_files) { free (einit_startup_configuration_files); } } cev.string = NULL; cev.type = einit_core_configuration_update; // make sure we keep updating until everything is sorted out while (cev.type == einit_core_configuration_update) { // notice (2, "stuff changed, updating configuration."); cev.type = einit_core_update_configuration; event_emit (&cev, einit_event_flag_broadcast); } evstaticdestroy(cev); if (ipccommands) { uint32_t rx = 0; for (; ipccommands[rx]; rx++) { ret = ipc_process (ipccommands[rx], stdout); } // if (gmode == EINIT_GMODE_SANDBOX) // cleanup (); free (ipccommands); if (einit_initial_environment) free (einit_initial_environment); return ret; } else if ((coremode == einit_mode_init) && !isinit && !initoverride) { eputs ("WARNING: eINIT is configured to run as init, but is not the init-process (pid=1) and the --override-init-check flag was not specified.\nexiting...\n\n", stderr); exit (EXIT_FAILURE); } else { /* actual init code */ uint32_t e = 0; nice (einit_core_niceness_increment); if (need_recovery) { notice (1, "need to recover from something..."); struct einit_event eml = evstaticinit(einit_core_recover); event_emit (&eml, einit_event_flag_broadcast); evstaticdestroy(eml); } if (einit_crash_data) { notice (1, "submitting crash data..."); struct einit_event eml = evstaticinit(einit_core_crash_data); eml.string = einit_crash_data; event_emit (&eml, einit_event_flag_broadcast); evstaticdestroy(eml); free (einit_crash_data); einit_crash_data = NULL; } { notice (3, "running early bootup code..."); struct einit_event eml = evstaticinit(einit_boot_early); event_emit (&eml, einit_event_flag_broadcast | einit_event_flag_spawn_thread_multi_wait); evstaticdestroy(eml); } notice (2, "scheduling startup switches.\n"); for (e = 0; einit_startup_mode_switches[e]; e++) { struct einit_event ee = evstaticinit(einit_core_switch_mode); ee.string = einit_startup_mode_switches[e]; event_emit (&ee, einit_event_flag_broadcast | einit_event_flag_spawn_thread | einit_event_flag_duplicate); evstaticdestroy(ee); } struct einit_event eml = evstaticinit(einit_core_main_loop_reached); eml.file = commandpipe_in; event_emit (&eml, einit_event_flag_broadcast); evstaticdestroy(eml); } if (einit_initial_environment) free (einit_initial_environment); return ret; } /* this should never be reached... */ if (einit_initial_environment) free (einit_initial_environment); return 0; }
rt_public int net_recv(EIF_PSTREAM cs, char *buf, size_t size #ifdef EIF_WINDOWS ,BOOL reset #endif ) /* The connected socket descriptor */ /* Where data are to be stored */ /* Amount of data to be read */ /* Reset event associated with cs reader? */ /* The connected socket descriptor */ /* Where data are to be stored */ /* Amount of data to be read */ { /* Read from network */ volatile size_t len = 0; /* Total amount of bytes read */ #ifdef EIF_WINDOWS DWORD length; /* Amount read by last system call */ UINT_PTR timer = 0; BOOL fSuccess; #ifdef USE_ADD_LOG add_log(2, "in net_recv"); #endif #else Signal_t (*oldalrm)(int); int length; #endif REQUIRE("Valid size", size <= INT32_MAX); #ifdef EIF_WINDOWS if (0 != setjmp(env)) { KillTimer (NULL, timer); /* Stop alarm clock */ errno = EPIPE; /* Signal timeout on read */ return -1; } while (len < size) { timer = SetTimer(NULL, timer, TIMEOUT*1000, (TIMERPROC) timeout); /* Give read only TIMEOUT seconds to succeed */ fSuccess = ReadFile(readfd(cs), buf + len, (DWORD) (size - len), &length, NULL); KillTimer (NULL, timer); if (fSuccess) if (length == 0) /* connection closed */ goto closed; else ; else return -1; /* failed */ len += length; } if (reset) { /* There is a problem when there are 0 bytes t send * Literally 0 bytes are sent and the Semaphore is set * We need to release the semaphore in this case */ if (size == 0) { /* Wait to get back in sync. */ if (WaitForSingleObject (readev(cs), INFINITE) != WAIT_OBJECT_0) { #ifdef USE_ADD_LOG add_log (8, "network:97 Bad wait"); #endif } } else { if (WaitForSingleObject (readev(cs), 0) != WAIT_OBJECT_0) { #ifdef USE_ADD_LOG add_log (8, "network:101 Wait on %d failed", size); #endif } } } return 0; closed: /* Unlike recv(), we return an error condition with a suitable errno code * if possible when and end of file is detected... because we never expect * one. Before closing the connection, the remote application should be * polite enough to send a 'bye' request and wait for us to receive it. */ errno = EPIPE; /* connection is broken */ KillTimer (NULL, timer); /* stop alarm clock */ return -1; #else oldalrm = signal(SIGALRM, timeout); /* Trap SIGALRM within this function */ if (0 != setjmp(env)) { alarm(0); /* Stop alarm clock */ signal(SIGPIPE, oldalrm); errno = NET_TIMEOUT; /* Signal timeout on read */ return -1; } while (len < size) { alarm(TIMEOUT); /* Give read only TIMEOUT seconds to succeed */ length = read(readfd(cs), buf + len, size - len); alarm(0); if (length == 0) /* connection closed */ goto closed; if (length == -1) { if (errno != EINTR) { return -1; /* failed */ } else { length = 0; } } len += length; } signal(SIGALRM, oldalrm); /* restore default handler */ return 0; closed: /* Unlike recv(), we return an error condition with a suitable errno code * if possible when and end of file is detected... because we never expect * one. Before closing the connection, the remote application should be * polite enough to send a 'bye' request and wait for us to receive it. */ errno = NET_BROKEN; /* conntection is broken */ alarm(0); /* stop alarm clock */ signal(SIGALRM, oldalrm); /* restore default handler */ return -1; #endif }
int getsector(__u16 sector) { readfd(sector/36, ((sector)%36)/18, (((sector)%36)%18)); }
rt_public STREAM_FN rem_input(EIF_PSTREAM sp) /* `sp': Stream on which no select is to be done */ { /* This function removes the input and associated callback for 'sp' and * returns the old callback value. */ STREAM_FN old_call; /* The old call back set for that fd */ #ifdef EIF_WINDOWS old_call = callback(sp); /* Save previous callback value */ set_callback(sp, NULL); /* And clear entry anyway */ if (old_call == NULL) { /* No callback was set */ s_errno = S_NOCALBAK; /* This error does not really matter */ return NULL; /* As we cleared the entry already */ } /* Update the reading mask and the nfds value. This is important, because * it is the only way do_select() can tell whether there is at least one * input file descriptor. Otherwise, with a null timout, we could block * forever. */ unset_multiple_mask(sp, rd_mask); /* We no longer need to monitor it */ unset_multiple_mask(sp, rd_tmask); /* Remove it also from temporary mask */ #else int i; /* To eventually update nfds */ int fd = readfd(sp); if (fd < 0 || fd >= NOFILE) { /* File descriptor out of range */ s_errno = S_FDESC; return NULL; } old_call = callback[fd]; /* Save previous callback value */ callback[fd] = NULL; /* And clear entry anyway */ if (old_call == NULL) { /* No callback was set */ s_errno = S_NOCALBAK; /* This error does not really matter */ return NULL; /* As we cleared the entry already */ } /* Update the reading mask and the nfds value. This is important, because * it is the only way do_select() can tell whether there is at least one * input file descriptor. Otherwise, with a null timout, we could block * forever. */ FD_CLR(fd, &rd_mask); /* We no longer need to monitor it */ FD_CLR(fd, &rd_tmask); /* Remove it also from temporary mask */ if (nfds == (fd + 1)) { /* This file was the maximum fd */ nfds = 0; /* Assume no more file */ for (i = fd - 1; i >= 0; i--) if (callback[i] != NULL) { nfds = i + 1; /* Number of fd still monitored */ break; /* Found it, break loop */ } } #endif return old_call; /* Success: return old value (cannot be null) */ }
rt_public int do_select(struct timeval *timeout) #endif { /* Finally, this runs the select call with the computed read mask, with the * specified timeout. The return value is simply the propagated status we * got from select() itself. If some input is available, we handle it by * calling the specified callback routine. If more than one file descriptor * was ready, we handle them all before returning. * Note that when the select call is interrupted by a signal, it is * restarted automatically. */ STREAM* sp; /* To loop over STREAM* */ #ifdef EIF_WINDOWS DWORD first_timeout; /* Timeout used for first select */ DWORD nfd; /* Status reported by select */ int isfirst = 1; /* Mark first select */ #else struct timeval first_timeout; /* Timeout used for first select */ int nfd; /* Status reported by select */ int fd; /* To loop over file descriptors */ int isfirst = 1; /* Mark first select */ #endif /* If no more file are to be selected, return immediately with a proper * error status in 's_errno'. This should be a convenient way to detect * that all the input sources have been removed, if this is only a * meta-knowledge. */ if (nfds == 0) { s_errno = S_NOFILE; /* No more input file */ return -1; } #ifdef DEBUG #ifdef USE_ADD_LOG add_log(20, "selecting with mask 0x%lx", rd_mask); #endif #endif /* Loop until select() succeeds or fails for any reason but a signal */ for (;;) { #ifdef USE_ADD_LOG add_log(20, "selecting"); #endif /* The first select is done with TMP_TIMEOUT time unless a timeout is * given. The temporary mask is used for this first selection. That * way, we do not select for the temporary "out" files, which increases * the chance of having the remote end of a stream clear to send the * next time those files are selected. */ #ifdef EIF_WINDOWS #ifdef USE_ADD_LOG add_log(20, "Selecting on count %d", nfds); { int i; for (i = 0; i < nfds; i++) add_log (20, " semaphore %d", rd_tmask [i]); } #endif #endif #ifdef EIF_WINDOWS if (isfirst) { if (timeout == 0) { first_timeout = TMP_TIMEOUT; nfd = WaitForMultipleObjects (nfds, rd_tmask, FALSE, first_timeout / 1000); } else { first_timeout = timeout; nfd = WaitForMultipleObjects (nfds, rd_tmask, FALSE, first_timeout * 1000); } } else { nfd = WaitForMultipleObjects (nfds, rd_mask, FALSE, timeout * 1000); } if (nfd == WAIT_FAILED) { #ifdef USE_ADD_LOG add_log(20, "Select failure %d count %d", GetLastError(), nfds); #endif s_errno = S_SELECT; /* Signals: select failed */ return -1; /* Propagate error status */ } if (isfirst) { isfirst = 0; if (nfd == WAIT_TIMEOUT && timeout == 0) { continue; /* First select timed out */ } } break; /* Exit from loop */ #else if (isfirst) { if (timeout == (struct timeval *) 0) { first_timeout.tv_sec = 0; first_timeout.tv_usec = TMP_TIMEOUT; } else { memcpy (&first_timeout, timeout, sizeof(struct timeval)); } memcpy (&read_mask, &rd_tmask, sizeof(fd_set)); nfd = select(nfds, &read_mask, (Select_fd_set_t) 0, (Select_fd_set_t) 0, &first_timeout); } else { memcpy (&read_mask, &rd_mask, sizeof(fd_set)); nfd = select(nfds, &read_mask, (Select_fd_set_t) 0, (Select_fd_set_t) 0, timeout); } if (nfd == -1) { if (errno != EINTR) { /* Not interrupted by a signal */ s_errno = S_SELECT; /* Signals: select failed */ return -1; /* Propagate error status */ } else { continue; /* Re-issue the system call */ } } if (isfirst) { isfirst = 0; if (nfd == 0 && timeout == (struct timeval *) 0) { continue; /* First select timed out */ } } break; /* Exit from loop */ #endif } /* end of for(;;) */ /* If we come here, then the select call must have succeded. If the timeout * value was reached, nfd is set to 0. Otherwise, it is set to the number * of ready file descriptors. */ #ifdef EIF_WINDOWS if (nfd == WAIT_TIMEOUT) { /* Select timed out */ #else if (nfd == 0) { /* Select timed out */ #endif return 0; /* Propagate status */ } #ifdef EIF_WINDOWS sp = callback_handles [nfd - WAIT_OBJECT_0]; #endif #ifdef DEBUG #ifdef EIF_WINDOWS #ifdef USE_ADD_LOG add_log(20, "file descriptor #%d is ready", sp->sr); #endif #else /* if not EIF_WINDOWS */ #ifdef USE_ADD_LOG for (fd = 0; fd < nfds; fd++) if (FD_ISSET(fd, &read_mask)) /* Something is present */ add_log(20, "file descriptor #%d is ready", fd); #endif #endif #endif /* Loop over the file descriptors and process any of them which is marked * as ready for reading. */ #ifdef EIF_WINDOWS callback_array [nfd - WAIT_OBJECT_0](sp); /* Wake up associated callback */ #else for (fd = 0; fd < nfds; fd++) { if (FD_ISSET(fd, &read_mask)) { /* Something is present */ sp = stream_by_fd[fd]; (callback[fd])(sp); /* Wake up associated callback */ }; } #endif #ifdef DEBUG #ifdef USE_ADD_LOG add_log(20, "select call returning %d", nfd); #endif #endif #ifdef EIF_WINDOWS return 1; /* Number of files processed */ #else return nfd; /* Number of files processed */ #endif } #ifdef EIF_WINDOWS STREAM_FN callback(STREAM *h) { int i; for (i = 0; i < nfds; i++) if (readfd(callback_handles[i]) == readfd(h)) return callback_array [i]; return NULL; }