示例#1
0
文件: file.c 项目: nickhen/muforth
/*
 * mu_read_file mmaps the file and returns its contents as a string
 */
void mu_read_file()     /* fd - addr len */
{
    char *p = NULL;
    struct stat s;
    int fd;

    fd = TOP;

    if (fstat(fd, &s) == -1)
    {
        close(fd);
        return abort_strerror();
    }

    /* If size of file is zero, don't try to mmap; it will fail and error
     * out. Instead, simply return a buffer starting at address 0, of
     * length 0.
     */
    if (s.st_size != 0)
    {
        p = (char *) mmap(0, s.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
        if (p == MAP_FAILED)
        {
            close(fd);
            return abort_strerror();
        }
    }

    DROP(-1);
    ST1 = (addr) p;
    TOP = s.st_size;
}
示例#2
0
/*
 * usb-find-device (vendor-id product-id -- handle -1 | 0)
 */
void mu_usb_find_device()
{
    int matched;

    /* Enumerate USB device tree, looking for a match */
    matched = enumerate_devices(ST1, TOP);

    /*
     * enumerate_devices only returns failure (-1) if it found a match but
     * couldn't open the device for read & write. Tell the user about the
     * error.
     */
    if (matched < 0) return abort_strerror();

    if (matched == 0)
    {
        /* No match found */
        DROP(1);
        TOP = 0;
    }
    else
    {
        /* Matched; return the device's _open_ file descriptor */
        ST1 = matched;
        TOP = -1;
    }
}
示例#3
0
/*
 * This is bogus, ridiculously dangerous and unportable, and for testing
 * only. But here it is: A generic ioctl interface!
 */
void mu_ioctl()     /* fd ioctl arg */
{
    if (ioctl(ST2, ST1, TOP) == -1)
        return abort_strerror();

    DROP(3);
}
示例#4
0
/*
 * usb-control (bmRequestType bRequest wValue wIndex wLength 'buffer device - count)
 */
void mu_usb_control()
{
    struct usb_ctl_request ucr;
    int fd;

#define req ucr.ucr_request
    req.bmRequestType = SP[6];
    req.bRequest = SP[5];
    USETW(req.wValue, SP[4]);
    USETW(req.wIndex, ST3);
    USETW(req.wLength, ST2);
    ucr.ucr_data = (void *)ST1;
    ucr.ucr_addr = 0;
    ucr.ucr_flags = (req.bmRequestType == UT_READ_DEVICE)
                    ? USBD_SHORT_XFER_OK : 0;
    fd = TOP;
    DROP(6);

    if (ioctl(fd, USB_DO_REQUEST, &ucr) == -1)
    {
        TOP = 0;    /* count of bytes transferred */
        return abort_strerror();
    }
    TOP = ucr.ucr_actlen;   /* actual length transferred */
}
示例#5
0
/* stack: ( fd termios - ) */
void mu_set_termios()
{
    /* drain out, flush in, set */
    if (tcsetattr(ST1, TCSAFLUSH, (struct termios *)TOP) == -1)
        return abort_strerror();

    DROP(2);
}
示例#6
0
文件: file.c 项目: nickhen/muforth
void mu_close_file()
{
    while (close(TOP) == -1)
    {
        if (errno == EINTR) continue;
        return abort_strerror();
    }
    DROP(1);
}
示例#7
0
文件: time.c 项目: eerpini/muforth
/*
 * We need a way to do short sleeps for talking to sensitive hardware
 * targets (like the Freescale HC908 series). I'm not getting good data
 * from the bootloader, and wondering if some short pauses would help.
 */
void mu_nanosleep()
{
    struct timespec ts;

    ts.tv_sec = ST1;
    ts.tv_nsec = TOP;

    while (nanosleep(&ts, &ts) == -1)
    {
        if (errno == EINTR) continue;
        return abort_strerror();
    }
    DROP(2);
}
示例#8
0
文件: file.c 项目: nickhen/muforth
void mu_create_file()       /* C-string-name - fd */
{
    int fd;
    char pathbuf[1024];
    char *path = abs_path((char *)TOP, pathbuf, 1024);

    if (path == NULL)
        return abort_zmsg("path too long");

    fd = open(path, O_CREAT | O_TRUNC | O_WRONLY, 0666);
    if (fd == -1)
        return abort_strerror();

    TOP = fd;
}
示例#9
0
文件: file.c 项目: nickhen/muforth
static void mu_open_file()     /* C-string-name flags - fd */
{
    int fd;
    char pathbuf[1024];
    char *path = abs_path((char *)ST1, pathbuf, 1024);

    if (path == NULL)
        return abort_zmsg("path too long");

    fd = open(path, TOP);
    if (fd == -1)
        return abort_strerror();

    DROP(1);
    TOP = fd;
}
示例#10
0
/*
 * Support for querying the column width of terminals, and staying updated
 * (via SIGWINCH) when they change.
 *
 * In case the user has redirected stdout to a file, use stderr as the file
 * descriptor to test.
 */
void mu_tty_width()     /* ( fd - width) */
{
    int fd = TOP;
    struct winsize tty_size;

    if (!isatty(fd))
    {
        TOP = 80;   /* default width for file output */
        return;
    }

    if (ioctl(fd, TIOCGWINSZ, &tty_size) == -1)
        return abort_strerror();

    TOP = tty_size.ws_col;
}
示例#11
0
文件: file.c 项目: nickhen/muforth
void mu_read_carefully()    /* fd buffer len -- #read */
{
    int fd;
    char *buffer;
    size_t len;
    ssize_t count;

    fd = ST2;
    buffer = (char *) ST1;
    len = TOP;
    DROP(2);

    while((count = read(fd, buffer, len)) == -1)
    {
        if (errno == EINTR) continue;
        return abort_strerror();
    }
    TOP = count;
}
示例#12
0
/*
 * usb-request (bmRequestType bRequest wValue wIndex wLength 'buffer device)
 * XXX should return actual length of transfer?
 */
void mu_usb_request()
{
    struct usb_ctl_request ucr;
    int fd;

#define req ucr.ucr_request
    req.bmRequestType = SP[6];
    req.bRequest = SP[5];
    USETW(req.wValue, SP[4]);
    USETW(req.wIndex, ST3);
    USETW(req.wLength, ST2);
    ucr.ucr_data = (void *)ST1;
    ucr.ucr_addr = 0;
    ucr.ucr_flags = (req.bmRequestType == UT_READ_DEVICE)
                    ? USB_SHORT_XFER_OK : 0;
    fd = TOP;
    DROP(7);

    if (ioctl(fd, USB_DO_REQUEST, &ucr) == -1) return abort_strerror();
}
示例#13
0
/*
 * usb-find-device (vendor-id product-id -- handle -1 | 0)
 */
void mu_usb_find_device()
{
    int matched;

    /* Enumerate USB device tree, looking for a match */
    matched = enumerate_devices(ST1, TOP);

    if (matched < 0) return abort_strerror();

    if (matched == 0)
    {
        /* No match found */
        DROP(1);
        TOP = 0;
    }
    else
    {
        /* Matched; return the device's _open_ file descriptor */
        ST1 = matched;
        TOP = -1;
    }
}
示例#14
0
文件: file.c 项目: nickhen/muforth
void mu_write_carefully()   /* fd buffer len */
{
    int fd;
    char *buffer;
    size_t len;
    ssize_t written;

    fd = ST2;
    buffer = (char *) ST1;
    len = TOP;
    DROP(3);

    while (len > 0)
    {
        written = write(fd, buffer, len);
        if (written == -1)
        {
            if (errno == EINTR) continue;
            return abort_strerror();
        }
        buffer += written;
        len -= written;
    }
}
示例#15
0
/*
 * Sometimes it's nice to know how many characters are waiting in the input
 * buffer.
 */
void mu_tty_icount()
{
    if (ioctl(TOP, FIONREAD, &TOP) == -1)
        return abort_strerror();
}