![cinap_lenrek](/assets/img/avatar_default.png)
The mount() and bind() syscalls return -1 on error, and the mountid sequence number on success. The manpage states that the mountid sequence number is a positive integer, but the kernels implementation currently uses a unsigned 32-bit integer and does not guarantee that the mountid will not become negative. Most code just cares about the error, so test for the -1 error value only.
136 lines
2.1 KiB
C
136 lines
2.1 KiB
C
#include <u.h>
|
|
#include <libc.h>
|
|
#include <thread.h>
|
|
#include "dat.h"
|
|
#include "fns.h"
|
|
|
|
int vfp = 1;
|
|
int nflag, pflag, bflag;
|
|
Ref nproc;
|
|
|
|
void
|
|
dump(void)
|
|
{
|
|
int i;
|
|
|
|
for(i = 0; i < 16; i++) {
|
|
print("R%2d %.8ux", i, P->R[i]);
|
|
if((i % 4) == 3) print("\n");
|
|
else print("\t");
|
|
}
|
|
}
|
|
|
|
static void
|
|
adjustns(void)
|
|
{
|
|
if(bind("/arm/bin", "/bin", MREPL) == -1)
|
|
sysfatal("bind: %r");
|
|
if(bind("/rc/bin", "/bin", MAFTER) == -1)
|
|
sysfatal("bind: %r");
|
|
putenv("cputype", "arm");
|
|
putenv("objtype", "arm");
|
|
}
|
|
|
|
void
|
|
cleanup(void)
|
|
{
|
|
if(P == nil)
|
|
return;
|
|
|
|
clrex();
|
|
remproc(P);
|
|
decref(&nproc);
|
|
freesegs();
|
|
fddecref(P->fd);
|
|
if(P->path != nil && decref(P->path) == 0)
|
|
free(P->path);
|
|
free(P);
|
|
}
|
|
|
|
static void
|
|
usage(void)
|
|
{
|
|
fprint(2, "usage: 5e [-npbF] text [...]\n");
|
|
exits(nil);
|
|
}
|
|
|
|
void
|
|
suicide(char *fmt, ...)
|
|
{
|
|
va_list va;
|
|
char buf[1024];
|
|
|
|
va_start(va, fmt);
|
|
vsnprint(buf, sizeof(buf), fmt, va);
|
|
va_end(va);
|
|
fprint(2, "%s\n", buf);
|
|
if(!bflag)
|
|
exits(buf);
|
|
abort();
|
|
}
|
|
|
|
int
|
|
notehandler(void *, char *note)
|
|
{
|
|
if(strncmp(note, "sys:", 4) == 0)
|
|
return 0;
|
|
|
|
if(strncmp(note, "emu:", 4) == 0)
|
|
exits(note);
|
|
|
|
addnote(note);
|
|
return 1;
|
|
}
|
|
|
|
static void
|
|
dotext(int argc, char **argv)
|
|
{
|
|
char *file;
|
|
|
|
if(**argv == '/' || **argv == '.' || **argv == '#') {
|
|
if(loadtext(*argv, argc, argv) < 0)
|
|
sysfatal("loadtext: %r");
|
|
return;
|
|
}
|
|
file = smprint("/bin/%s", *argv);
|
|
if(loadtext(file, argc, argv) < 0)
|
|
sysfatal("loadtext: %r");
|
|
free(file);
|
|
}
|
|
|
|
void
|
|
main(int argc, char **argv)
|
|
{
|
|
ARGBEGIN {
|
|
case 'n': nflag++; break;
|
|
case 'p': pflag++; break;
|
|
case 'b': bflag++; break;
|
|
case 'f': vfp = 1; break;
|
|
case 'F': vfp = 0; break;
|
|
default: usage();
|
|
} ARGEND;
|
|
if(argc < 1)
|
|
usage();
|
|
if(_nprivates < 1)
|
|
sysfatal("we don't have privates");
|
|
if(rfork(RFREND | RFNAMEG | RFENVG) < 0)
|
|
sysfatal("rfork: %r");
|
|
atexit(cleanup);
|
|
if(!nflag)
|
|
adjustns();
|
|
if(pflag)
|
|
initfs("armproc", "/proc");
|
|
initproc();
|
|
dotext(argc, argv);
|
|
atnotify(notehandler, 1);
|
|
for(;;) {
|
|
if(ultraverbose)
|
|
dump();
|
|
step();
|
|
while((P->notein - P->noteout) % NNOTE) {
|
|
donote(P->notes[P->noteout % NNOTE], 0);
|
|
ainc(&P->noteout);
|
|
}
|
|
}
|
|
}
|