void cmd_elf(char *arg) { int fd, ret; struct file *fp; int isElf; elf_header_t header; fd = call_syscall(5, (uintptr_t) arg, 0, 0); if (fd <= 0) { _printk("open failed: %d\n", fd); return; } fp = current->owner->file_table[fd]; isElf = elf_probe(fp); _printk("file(%d) is %sELF\n", fd, isElf ? "" : "not "); if (!isElf) { call_syscall(6, fd, 0, 0); return; } fp->fops->read(fp, &header, sizeof(elf_header_t)); _printk("ELF Type: %s\n", elf_type_as_string(header.e_type)); _printk("Entry Point: 0x%x\n", header.e_entry); ret = elf_load(fp); _printk("ELF RET: %s\n", errno_to_string(ret)); }
bool ridual_mkdir(QString path, QString& error_string) { bool r = mkdir(path.toLocal8Bit(), 0755) == 0; if (!r) { errno_to_string(error_string); } return r; }
/* * Mark a queue as closed. No further IO is permitted. * All blocks are released. */ void qclose(struct queue *q) { struct block *bfirst; if (q == NULL) return; /* mark it */ spin_lock_irqsave(&q->lock); q->state |= Qclosed; q->state &= ~(Qflow | Qstarve | Qdropoverflow | Qnonblock); strlcpy(q->err, errno_to_string(ECONNABORTED), sizeof(q->err)); bfirst = q->bfirst; q->bfirst = 0; q->len = 0; q->dlen = 0; spin_unlock_irqsave(&q->lock); /* free queued blocks */ freeblist(bfirst); /* wake up readers/writers */ rendez_wakeup(&q->rr); rendez_wakeup(&q->wr); qwake_cb(q, FDTAP_FILT_HANGUP); }
/* Wait for the queue to be non-empty or closed. Returns TRUE for a successful * wait, FALSE on Qclose (without error) * * Called with q ilocked. May error out, back through the caller, with * the irqsave lock unlocked. */ static bool qwait(struct queue *q) { /* wait for data */ for (;;) { if (q->bfirst != NULL) break; if (q->state & Qclosed) { if (++q->eof > 3) { spin_unlock_irqsave(&q->lock); error(EFAIL, "multiple reads on a closed queue"); } if (*q->err && strcmp(q->err, errno_to_string(ECONNABORTED)) != 0) { spin_unlock_irqsave(&q->lock); error(EFAIL, q->err); } return FALSE; } /* We set Qstarve regardless of whether we are non-blocking or not. * Qstarve tracks the edge detection of the queue being empty. */ q->state |= Qstarve; if (q->state & Qnonblock) { spin_unlock_irqsave(&q->lock); error(EAGAIN, "queue empty"); } spin_unlock_irqsave(&q->lock); /* may throw an error() */ rendez_sleep(&q->rr, notempty, q); spin_lock_irqsave(&q->lock); } return TRUE; }
void c_tun_device_apple::set_mtu(uint32_t mtu) { _fact("Setting MTU="<<mtu); const auto name = m_ifr_name.c_str(); _fact("Setting MTU="<<mtu<<" on card: " << name); t_syserr error = NetPlatform_setMTU(name, mtu); if (error.my_code != 0) throw std::runtime_error("set MTU error: " + errno_to_string(error.errno_copy)); }
jobject errno_to_enum(JNIEnv *env, int errnum) { char *str = errno_to_string(errnum); assert(str != NULL); jstring jstr = (*env)->NewStringUTF(env, str); PASS_EXCEPTIONS_RET(env, NULL); return (*env)->CallStaticObjectMethod( env, enum_class, enum_valueOf, errno_class, jstr); }
bool ridual_rmdir(QString path, QString& error_string) { bool r = rmdir(path.toLocal8Bit()) == 0; if (!r) { if (errno == EEXIST || errno == ENOTEMPTY) { error_string = QObject::tr("Directory is not empty"); } else { errno_to_string(error_string); } } return r; }
void cmd_ls(char *arg) { struct file *file = vfs_open(arg); if (!file->isdir) { _printk("%s", errno_to_string(ENOTDIR)); return; } return; }
static lock_file create_or_throw(const int fd){ const auto lockres = lockf(fd, F_TLOCK, 0); if (lockres< 0) { const auto err = errno; throw std::runtime_error("lockf failed with following error:" + errno_to_string(err)); } lock_file lf; lf.fd = fd; lf.lockres = lockres; return lf; }
inline locked_file create_pid_file(const std::string& pid_file){ const int fd = open(pid_file.c_str(), O_RDWR|O_CREAT, 0640); if(fd == -1){ const auto err = errno; throw std::runtime_error("open failed with following error:" + errno_to_string(err)); } open_file_descriptor file(fd); lock_file lf = lock_file::create_or_throw(fd); locked_file toreturn(std::move(file), std::move(lf)); // save PID to file const auto pid = std::to_string(getpid()) + "\n"; const auto write_res = write(fd, pid.c_str(), pid.size()); if(write_res == static_cast<decltype(write_res)>(-1)){ const auto err = errno; throw std::runtime_error("writing pid to file failed with following error:" + errno_to_string(err)); } return toreturn; }
// terminates parent with EXIT_SUCCESS if ok, terminates with EXIT_FAILURE if not // FIXME: unclear if I should use exit or _exit // _exit does not remove tmpfiles, exit does... inline void fork_and_close_parent(){ // Fork off the parent process const auto pid = fork(); // Check if an error occurred if (pid < 0) { // fork failed, return error const auto err = errno; throw std::runtime_error("fork failed with following error:" + errno_to_string(err)); } // Success: Let the parent terminate if (pid > 0) { // We are parent: _exit() or exit() ? exit(EXIT_SUCCESS); } }
/* * Mark a queue as closed. Wakeup any readers. Don't remove queued * blocks. */ void qhangup(struct queue *q, char *msg) { /* mark it */ spin_lock_irqsave(&q->lock); q->state |= Qclosed; if (msg == 0 || *msg == 0) strlcpy(q->err, errno_to_string(ECONNABORTED), sizeof(q->err)); else strlcpy(q->err, msg, ERRMAX); spin_unlock_irqsave(&q->lock); /* wake up readers/writers */ rendez_wakeup(&q->rr); rendez_wakeup(&q->wr); qwake_cb(q, FDTAP_FILT_HANGUP); }
inline void daemonize(){ // Fork off the parent process fork_and_close_parent(); // The child process becomes session leader if (setsid() < 0) { exit(EXIT_FAILURE); } // Ignore signal sent from child to parent process signal(SIGCHLD, SIG_IGN); // Fork off for the second time fork_and_close_parent(); // Set new file permissions const auto old_mode = umask(0); (void)old_mode; // Change the working directory to the root directory // or another appropriated directory const auto chdir_res = chdir("/"); if(chdir_res != 0){ // what to do? we have already forked once -> is it ok to chdir before the first fork? const auto err = errno; throw std::runtime_error("open failed with following error:" + errno_to_string(err)); } // Close all open file descriptors // since close takes a positive int, (and sysconf returns a long) ignore those outside the [0, max_int] range constexpr long i_max{std::numeric_limits<int>::max()}; const auto first_fd = sysconf(_SC_OPEN_MAX); const auto first_fd_i = static_cast<int>(myclamp(first_fd, 0l, i_max)); for (auto fd = first_fd_i; fd > 0; fd--) { close(fd); } // Reopen stdin (fd = 0), stdout (fd = 1), stderr (fd = 2) stdin = fopen("/dev/null", "r"); stdout = fopen("/dev/null", "w+"); stderr = fopen("/dev/null", "w+"); }
static int csdial(DS * ds) { int n, fd, rv = -1; char *p, *buf, *clone, *err, *besterr; buf = kmalloc(Maxstring, KMALLOC_WAIT); clone = kmalloc(Maxpath, KMALLOC_WAIT); err = kmalloc(ERRMAX, KMALLOC_WAIT); besterr = kmalloc(ERRMAX, KMALLOC_WAIT); /* * open connection server */ snprintf(buf, Maxstring, "%s/cs", ds->netdir); fd = sysopen(buf, O_RDWR); if (fd < 0) { /* no connection server, don't translate */ snprintf(clone, Maxpath, "%s/%s/clone", ds->netdir, ds->proto); rv = call(clone, ds->rem, ds); goto out; } /* * ask connection server to translate */ snprintf(buf, Maxstring, "%s!%s", ds->proto, ds->rem); if (syswrite(fd, buf, strlen(buf)) < 0) { kerrstr(err, ERRMAX); sysclose(fd); set_errstr("%s (%s)", err, buf); goto out; } /* * loop through each address from the connection server till * we get one that works. */ *besterr = 0; strlcpy(err, errno_to_string(ECONNRESET), ERRMAX); sysseek(fd, 0, 0); while ((n = sysread(fd, buf, Maxstring - 1)) > 0) { buf[n] = 0; p = strchr(buf, ' '); if (p == 0) continue; *p++ = 0; rv = call(buf, p, ds); if (rv >= 0) break; err[0] = 0; kerrstr(err, ERRMAX); if (strstr(err, "does not exist") == 0) memmove(besterr, err, ERRMAX); } sysclose(fd); if (rv < 0 && *besterr) kerrstr(besterr, ERRMAX); else kerrstr(err, ERRMAX); out: kfree(buf); kfree(clone); kfree(err); kfree(besterr); return rv; }
/* * Enact a scenario by looping through the four test cases for the scenario, * spawning off pairs of processes with the desired credentials, and * reporting results to stdout. */ static int enact_scenario(int scenario) { pid_t pid1, pid2; char *name, *tracefile; int error, desirederror, loop; for (loop = 0; loop < LOOP_MAX+1; loop++) { /* * Spawn the first child, target of the operation. */ pid1 = fork(); switch (pid1) { case -1: return (-1); case 0: /* child */ error = cred_set(scenarios[scenario].sc_cred2); if (error) { perror("cred_set"); return (error); } /* 200 seconds should be plenty of time. */ sleep(200); exit(0); default: /* parent */ break; } /* * XXX * This really isn't ideal -- give proc 1 a chance to set * its credentials, or we may get spurious errors. Really, * some for of IPC should be used to allow the parent to * wait for the first child to be ready before spawning * the second child. */ sleep(1); /* * Spawn the second child, source of the operation. */ pid2 = fork(); switch (pid2) { case -1: return (-1); case 0: /* child */ error = cred_set(scenarios[scenario].sc_cred1); if (error) { perror("cred_set"); return (error); } /* * Initialize errno to zero so as to catch any * generated errors. In each case, perform the * operation. Preserve the error number for later * use so it doesn't get stomped on by any I/O. * Determine the desired error for the given case * by extracting it from the scenario table. * Initialize a function name string for output * prettiness. */ errno = 0; switch (loop) { case LOOP_PTRACE: error = ptrace(PT_ATTACH, pid1, NULL, 0); error = errno; name = "ptrace"; desirederror = scenarios[scenario].sc_canptrace_errno; break; case LOOP_KTRACE: tracefile = mktemp("/tmp/testuid_ktrace.XXXXXX"); if (tracefile == NULL) { error = errno; perror("mktemp"); break; } error = ktrace(tracefile, KTROP_SET, KTRFAC_SYSCALL, pid1); error = errno; name = "ktrace"; desirederror = scenarios[scenario].sc_canktrace_errno; unlink(tracefile); break; case LOOP_SIGHUP: error = kill(pid1, SIGHUP); error = errno; name = "sighup"; desirederror = scenarios[scenario].sc_cansighup_errno; break; case LOOP_SIGSEGV: error = kill(pid1, SIGSEGV); error = errno; name = "sigsegv"; desirederror = scenarios[scenario].sc_cansigsegv_errno; break; case LOOP_SEE: getpriority(PRIO_PROCESS, pid1); error = errno; name = "see"; desirederror = scenarios[scenario].sc_cansee_errno; break; case LOOP_SCHED: error = setpriority(PRIO_PROCESS, pid1, 0); error = errno; name = "sched"; desirederror = scenarios[scenario].sc_cansched_errno; break; default: name = "broken"; } if (error != desirederror) { fprintf(stdout, "[%s].%s: expected %s, got %s\n ", scenarios[scenario].sc_name, name, errno_to_string(desirederror), errno_to_string(error)); cred_print(stdout, scenarios[scenario].sc_cred1); cred_print(stdout, scenarios[scenario].sc_cred2); fprintf(stdout, "\n"); } exit(0); default: /* parent */ break; } error = waitpid(pid2, NULL, 0); /* * Once pid2 has died, it's safe to kill pid1, if it's still * alive. Mask signal failure in case the test actually * killed pid1 (not unlikely: can occur in both signal and * ptrace cases). */ kill(pid1, SIGKILL); error = waitpid(pid2, NULL, 0); } return (0); }
static void throw_errno(int error, const std::string& message) { const std::string error_str = errno_to_string(error); const std::string full_message = tinfra::tsprintf("%s: %s", message, error_str); throw E(full_message); }