Beispiel #1
0
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));
}
Beispiel #2
0
bool ridual_mkdir(QString path, QString& error_string) {
  bool r = mkdir(path.toLocal8Bit(), 0755) == 0;
  if (!r) {
    errno_to_string(error_string);
  }
  return r;
}
Beispiel #3
0
/*
 *  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);
}
Beispiel #4
0
/* 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;
}
Beispiel #5
0
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);
}
Beispiel #7
0
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;
}
Beispiel #8
0
void cmd_ls(char *arg)
{
    struct file *file = vfs_open(arg);

    if (!file->isdir) {
        _printk("%s", errno_to_string(ENOTDIR));
        return;
    }

    return;
}
Beispiel #9
0
	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;
	}
Beispiel #10
0
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;

}
Beispiel #11
0
// 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);
	}
}
Beispiel #12
0
/*
 *  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);
}
Beispiel #13
0
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+");
}
Beispiel #14
0
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;
}
Beispiel #15
0
/*
 * 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);
}
Beispiel #16
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);
}