Also fix the pipe open semantics for named pipes (I hope).
* calls as they want a parent and to create the new node.
*/
-char lastname[31];
-uint8_t n_open_fault;
-static char *name, *nameend;
+uint8_t lastname[31];
+
+static uint8_t n_open_fault;
+static uint8_t n_fault_type;
+static uint8_t *name, *nameend;
static uint8_t getcf(void)
{
- int16_t c;
- c = ugetc(name);
- if (c == -1 || name == nameend) {
- if (name == nameend)
- udata.u_error = ENAMETOOLONG;
+ if (name == nameend) {
+ udata.u_error = n_fault_type;
n_open_fault = 1;
return 0;
}
- return (uint8_t)c;
+ return (uint8_t)_ugetc(name);
}
-inoptr n_open(char *namep, inoptr *parent)
+inoptr n_open(uint8_t *namep, inoptr *parent)
{
staticfast inoptr wd; /* the directory we are currently searching. */
staticfast inoptr ninode;
inoptr temp;
uint8_t c;
- char *fp;
+ uint8_t *fp;
+ usize_t len;
+
+ /* Check the user address and length. If it's shorter than 512 bytes this
+ is fine, but set nameeend accordingly. This allows us to use _ugetc
+ in the hot path which saves us a ton of cycles */
+ len = valaddr(namep, 512);
+ if (len == 0)
+ return NULLINODE;
name = namep;
+ nameend = namep + len;
n_open_fault = 0;
- nameend = namep + 512; /* For now our pathmax is 512 */
-#ifdef DEBUG
- kprintf("kn_open(\"%s\")\n", name);
-#endif
+ /* What error do we return if we hit nameend - are we overlong, or out
+ of memory space */
+ if (len == 512)
+ n_fault_type = ENAMETOOLONG;
+ else
+ n_fault_type = EACCES;
if(getcf() == '/')
wd = udata.u_root;
* zeroes.
*/
-inoptr srch_dir(inoptr wd, char *compname)
+inoptr srch_dir(inoptr wd, uint8_t *compname)
{
int curentry;
blkno_t curblock;
do
{
udata.u_count = DIR_LEN;
- udata.u_base =(unsigned char *)&curentry;
+ udata.u_base = (uint8_t *)&curentry;
udata.u_sysio = true;
readi(wd, 0);
* or the user did not have write permission.
*/
-bool ch_link(inoptr wd, char *oldname, char *newname, inoptr nindex)
+bool ch_link(inoptr wd, uint8_t *oldname, uint8_t *newname, inoptr nindex)
{
struct direct curentry;
int i;
for(;;)
{
udata.u_count = DIR_LEN;
- udata.u_base =(unsigned char *)&curentry;
+ udata.u_base =(uint8_t *)&curentry;
udata.u_sysio = true;
readi(wd, 0);
/* Namecomp compares two strings to see if they are the same file name.
* It stops at FILENAME_LEN chars or a null or a slash. It returns 0 for difference.
+ *
+ * TODO: This generates crap code on most compilers so we probably ought to
+ * turn it into platform asm code.
*/
-bool namecomp(char *n1, char *n2) // return true if n1 == n2
+bool namecomp(uint8_t *n1, uint8_t *n2) // return true if n1 == n2
{
uint8_t n; // do we have enough variables called n?
* it's cleaner ???
*/
-inoptr newfile(inoptr pino, char *name)
+inoptr newfile(inoptr pino, uint8_t *name)
{
regptr inoptr nindex;
uint8_t j;
nindex->c_node.i_addr[j] = 0;
}
wr_inode(nindex);
- if (!ch_link(pino, "", name, nindex)) {
+ if (!ch_link(pino, (uint8_t *)"", name, nindex)) {
i_deref(nindex);
/* ch_link sets udata.u_error */
goto nogood;
panic(PANIC_INODE_FREED);
if (mode == MODE_R(F_PIPE))
- wakeup((char *)ino);
+ wakeup((uint8_t *)ino);
/* If the inode has no links and no refs, it must have
its blocks freed. */
for(j=17; j >= 0; --j)
freeblk(dev, ino->c_node.i_addr[j], 0);
- memset((char *)ino->c_node.i_addr, 0, sizeof(ino->c_node.i_addr));
+ memset((uint8_t *)ino->c_node.i_addr, 0, sizeof(ino->c_node.i_addr));
ino->c_flags |= CDIRTY;
ino->c_node.i_size = 0;
* FIXME: this could be more efficient if we remembered which directory offset
* we found the node at lookup time
*/
-arg_t unlinki(inoptr ino, inoptr pino, char *fname)
+arg_t unlinki(inoptr ino, inoptr pino, uint8_t *fname)
{
if (getmode(ino) == MODE_R(F_DIR)) {
udata.u_error = EISDIR;
}
/* Remove the directory entry (ch_link checks perms) */
- if (!ch_link(pino, fname, "", NULLINODE))
+ if (!ch_link(pino, fname, (uint8_t *)"", NULLINODE))
return -1;
/* Decrease the link count of the inode */
#define CPUTYPE_R2K 9
#define CPUTYPE_Z280 10
#define CPUTYPE_8080 11
+#define CPUTYPE_8085 12
/* Maximum UFTSIZE can be is 16, then you need to alter the O_CLOEXEC code */
#define DIR_LEN 32
typedef struct direct {
uint16_t d_ino;
- char d_name[FILENAME_LEN];
+ uint8_t d_name[FILENAME_LEN];
} direct;
#define uputw(v, p) ((*(uint16_t*)(p) = (v)) && 0)
#define uzero(a,b) (memset(a,0,b) && 0)
#else
-extern usize_t valaddr(const char *base, usize_t size);
+extern usize_t valaddr(const uint8_t *base, usize_t size);
extern int uget(const void *userspace_source, void *dest, usize_t count);
extern int16_t ugetc(const void *userspace_source);
extern uint16_t ugetw(const void *userspace_source);
/* filesys.c */
/* open file, "name" in user address space */
-extern char lastname[31];
-extern inoptr n_open(char *uname, inoptr *parent);
+extern uint8_t lastname[31];
+extern inoptr n_open(uint8_t *uname, inoptr *parent);
extern inoptr i_open(uint16_t dev, uint16_t ino);
-extern inoptr srch_dir(inoptr wd, char *compname);
+extern inoptr srch_dir(inoptr wd, uint8_t *compname);
extern inoptr srch_mt(inoptr ino);
extern bool emptydir(inoptr ino);
-extern bool ch_link(inoptr wd, char *oldname, char *newname, inoptr nindex);
+extern bool ch_link(inoptr wd, uint8_t *oldname, uint8_t *newname, inoptr nindex);
/* return true if n1 == n2 */
-extern bool namecomp(char *n1, char *n2);
-extern inoptr newfile(inoptr pino, char *name);
+extern bool namecomp(uint8_t *n1, uint8_t *n2);
+extern inoptr newfile(inoptr pino, uint8_t *name);
extern fsptr getdev(uint16_t dev);
extern bool baddev(fsptr dev);
extern uint16_t i_alloc(uint16_t devno);
/* returns true on failure, false on success */
extern bool fmount(uint16_t dev, inoptr ino, uint16_t flags);
extern void magic(inoptr ino);
-extern arg_t unlinki(inoptr ino, inoptr pino, char *fname);
+extern arg_t unlinki(inoptr ino, inoptr pino, uint8_t *fname);
/* inode.c */
extern void readi(inoptr ino, uint8_t flag);
/* syscalls_fs.c, syscalls_proc.c, syscall_other.c etc */
extern void updoff(void);
-extern int stcpy(inoptr ino, char *buf);
+extern int stcpy(inoptr ino, uint8_t *buf);
extern bool rargs (char **userspace_argv, struct s_argblk *argbuf);
extern char **wargs(char *userspace_ptr, struct s_argblk *argbuf, int *cnt);
-extern arg_t unlinki(inoptr ino, inoptr pino, char *fname);
/* timer.c */
extern void rdtime(time_t *tloc);
#define di __hard_di
#define irqrestore __hard_irqrestore
#define ei __hard_ei
+#else
+extern irqflags_t di(void);
+extern void irqrestore(irqflags_t f);
+extern void ei(void);
#endif
/* Will need a uptr_t eventually */
char *path;
char *buf;
********************************************/
-#define path (char *)udata.u_argn
-#define buf (char *)udata.u_argn1
+#define path (uint8_t *)udata.u_argn
+#define buf (uint8_t *)udata.u_argn1
arg_t _stat(void)
{
char *buf;
********************************************/
#define fd (int16_t)udata.u_argn
-#define buf (char *)udata.u_argn1
+#define buf (uint8_t *)udata.u_argn1
arg_t _fstat(void)
{
/* Utility for stat and fstat */
-int stcpy(inoptr ino, char *buf)
+int stcpy(inoptr ino, uint8_t *buf)
{
static uint8_t zero[4];
/* Copying the structure a member at a time is too expensive. Instead we
unlink (path) Function 6
char *path;
********************************************/
-#define path (char *)udata.u_argn
+#define path (uint8_t *)udata.u_argn
arg_t _unlink(void)
{
uint16_t nbytes;
********************************************/
#define d (int16_t)udata.u_argn
-#define buf (char *)udata.u_argn1
+#define buf (uint8_t *)udata.u_argn1
#define nbytes (susize_t)udata.u_argn2
arg_t readwrite(uint8_t reading)
uint16_t nbytes;
********************************************/
#define d (int16_t)udata.u_argn
-#define buf (char *)udata.u_argn1
+#define buf (uint8_t *)udata.u_argn1
#define nbytes udata.u_argn2
/*
uint16_t nbytes;
********************************************/
#define d (int16_t)udata.u_argn
-#define buf (char *)udata.u_argn1
+#define buf (uint8_t *)udata.u_argn1
#define nbytes (susize_t)udata.u_argn2
arg_t _write(void)
chdir (dir) Function 10
char *dir;
********************************************/
-#define dir (char *)udata.u_argn
+#define dir (uint8_t *)udata.u_argn
arg_t _chdir(void)
{
chroot (dir) Function 46
char *dir;
********************************************/
-#define dir (char *)udata.u_argn
+#define dir (uint8_t *)udata.u_argn
arg_t _chroot(void)
{
int16_t mode;
int16_t dev;
********************************************/
-#define name (char *)udata.u_argn
-#define mode (int16_t)udata.u_argn1
-#define dev (int16_t)udata.u_argn2
+#define name (uint8_t *)udata.u_argn
+#define mode (uint16_t)udata.u_argn1
+#define dev (uint16_t)udata.u_argn2
arg_t _mknod(void)
{
char *path;
int16_t mode;
********************************************/
-#define path (char *)udata.u_argn
-#define mode (int16_t)udata.u_argn1
+#define path (uint8_t *)udata.u_argn
+#define mode (uint16_t)udata.u_argn1
arg_t _access(void)
{
char *path;
int16_t mode;
********************************************/
-#define path (char *)udata.u_argn
+#define path (uint8_t *)udata.u_argn
arg_t _chmod(void)
{
int owner;
int group;
********************************************/
-#define path (char *)udata.u_argn
+#define path (uint8_t *)udata.u_argn
arg_t _chown(void)
{
char *file;
char *buf;
********************************************/
-#define file (char *)udata.u_argn
-#define buf (char *)udata.u_argn1
+#define file (uint8_t *)udata.u_argn
+#define buf (uint8_t *)udata.u_argn1
arg_t _utime(void)
{
udata.u_error = ENXIO;
return (-1);
}
- return uput((char *) &m->m_fs, (char *) buf, sizeof(struct filesys));
+ return uput((uint8_t *) &m->m_fs, (uint8_t *) buf, sizeof(struct filesys));
}
#undef dev
int16_t flag;
int16_t mode;
********************************************/
-#define name (char *)udata.u_argn
+#define name (uint8_t *)udata.u_argn
#define flag (uint16_t)udata.u_argn1
#define mode (uint16_t)udata.u_argn2
i_unlock(ino);
/* FIXME: ATIME ? */
-/*
- * Sleep process if no writer or reader.
- * FIXME: check for other of pair now we have proper counts
- */
- if (getmode(ino) == MODE_R(F_PIPE) && of_tab[oftindex].o_refs == 1
- && !(flag & O_NDELAY))
- psleep(ino);
+
+ if (getmode(ino) == MODE_R(F_PIPE)) {
+ if (of_tab[oftindex].o_refs == 1
+ && !(flag & O_NDELAY)) {
+ psleep(ino);
+ if (chksigs()) {
+ udata.u_error = EINTR;
+ goto idrop;
+ }
+ }
+ if ((ino->c_writers == 0) && (flag & O_NDELAY)) {
+ udata.u_error = ENXIO;
+ goto idrop;
+ }
+ }
/* From the moment of the psleep ino is invalid */
return (uindex);
- idrop:
+idrop:
i_unlock(ino);
/* Falls through and drops the reference count */
- cantopen:
+cantopen:
oft_deref(oftindex); /* This will call i_deref() */
- nooft:
+nooft:
udata.u_files[uindex] = NO_FILE;
return (-1);
}
char *name1;
char *name2;
********************************************/
-#define name1 (char *)udata.u_argn
-#define name2 (char *)udata.u_argn1
+#define name1 (uint8_t *)udata.u_argn
+#define name2 (uint8_t *)udata.u_argn1
arg_t _link(void)
{
with node name. Rest is up to the libc.
********************************************/
-#define buf (char *)udata.u_argn
+#define buf (uint8_t *)udata.u_argn
#define len (uint16_t)udata.u_argn1
arg_t _uname(void)
put inside itself!
********************************************/
-#define src (char *)udata.u_argn
-#define dst (char *)udata.u_argn1
+#define src (uint8_t *)udata.u_argn
+#define dst (uint8_t *)udata.u_argn1
arg_t _rename(void)
{
int16_t mode;
********************************************/
-#define name (char *)udata.u_argn
+#define name (uint8_t *)udata.u_argn
#define mode (int16_t)udata.u_argn1
arg_t _mkdir(void)
rmdir (path) Function 52
char *path;
********************************************/
-#define path (char *)udata.u_argn
+#define path (uint8_t *)udata.u_argn
arg_t _rmdir(void)
{
char *dir;
int flags;
********************************************/
-#define spec (char *)udata.u_argn
-#define dir (char *)udata.u_argn1
+#define spec (uint8_t *)udata.u_argn
+#define dir (uint8_t *)udata.u_argn1
#define flags (int)udata.u_argn2
arg_t _mount(void)
char *spec;
********************************************/
-#define spec (char *)udata.u_argn
+#define spec (uint8_t *)udata.u_argn
#define flags (uint16_t)udata.u_argn1
static int do_umount(uint16_t dev)
uint16_t scale;
********************************************/
-#define samples (char *)udata.u_argn
+#define samples (uint8_t *)udata.u_argn
#define offset (usize_t)udata.u_argn1
#define size (usize_t)udata.u_argn2
#define scale (uint16_t)udata.u_argn3
********************************************/
#define cmd (int16_t)udata.u_argn
#define func (int16_t)udata.u_argn1
-#define ptr (char *)udata.u_argn2
+#define ptr (uint8_t *)udata.u_argn2
arg_t _uadmin(void)
{
times (buf) Function 42 ?
char *buf;
********************************************/
-#define buf (char *)udata.u_argn
+#define buf (uint8_t *)udata.u_argn
arg_t _times(void)
{
int retval;
uint8_t found;
- if (statloc && !valaddr((char *) statloc, sizeof(int))) {
+ if (statloc && !valaddr((uint8_t *) statloc, sizeof(int))) {
udata.u_error = EFAULT;
return (-1);
}
if (sig != SIGKILL && sig != SIGSTOP)
sb->s_ignored |= sigmask(sig);
} else {
- if (func != SIG_DFL && !valaddr((char *) func, 1)) {
+ if (func != SIG_DFL && !valaddr((uint8_t *) func, 1)) {
udata.u_error = EFAULT;
goto nogood;
}
int16_t sig;
int16_t disp;
*******************************************/
-#define sig (int16_t)udata.u_argn
-#define disp (int16_t)udata.u_argn1
+#define sig (uint16_t)udata.u_argn
+#define disp (uint16_t)udata.u_argn1
/* Implement sighold/sigrelse */
arg_t _sigdisp(void)
#if !defined(CONFIG_FLAT) && !defined(CONFIG_VMMU)
/* This checks to see if a user-supplied address is legitimate */
-usize_t valaddr(const char *base, usize_t size)
+usize_t valaddr(const uint8_t *base, usize_t size)
{
- if (!base || base < (const char *)PROGBASE || base + size < base ||
- base > (const char *)(size_t)udata.u_top)
+ if (!base || base < (const uint8_t *)PROGBASE || base + size < base ||
+ base > (const uint8_t *)(size_t)udata.u_top)
size = 0;
- else if (base + size > (const char *)(size_t)udata.u_top)
- size = (char *)(size_t)udata.u_top - base;
+ else if (base + size > (const uint8_t *)(size_t)udata.u_top)
+ size = (uint8_t *)(size_t)udata.u_top - base;
if (size == 0)
udata.u_error = EFAULT;
return size;