void serve_open(u_int envid, struct Fsreq_open *rq) { writef("serve_open %08x %x 0x%x\n", envid, (int)rq->req_path, rq->req_omode); u_char path[MAXPATHLEN]; struct File *f; struct Filefd *ff; int fileid; int r; struct Open *o; // Copy in the path, making sure it's null-terminated user_bcopy(rq->req_path, path, MAXPATHLEN); path[MAXPATHLEN - 1] = 0; //writef("serve_open:enter open %s\n",rq->req_path); // Find a file id. if ((r = open_alloc(&o)) < 0) { writef("open_alloc failed: %d", r); goto out; } fileid = r; //writef("serve_open:ending find a file id o = %x\n",o); // Open the file. if ((r = file_open((char *)path, &f)) < 0) { writef("file_open failed: %e", r); goto out; } //writef("serve_open:ending open the file\n"); // Save the file pointer. o->o_file = f; // Fill out the Filefd structure ff = (struct Filefd *)o->o_ff; ff->f_file = *f; ff->f_fileid = o->o_fileid; o->o_mode = rq->req_omode; ff->f_fd.fd_omode = o->o_mode; ff->f_fd.fd_dev_id = devfile.dev_id; //writef("serve_open:will to ipc send\n"); if (debug) { writef("sending success, page %08x\n", (u_int)o->o_ff); } ipc_send(envid, 0, (u_int)o->o_ff, PTE_V | PTE_R | PTE_LIBRARY); //writef("serve_open:end of open %s\n",rq->req_path); return; out: user_panic("*********************path:%s", path); ipc_send(envid, r, 0, 0); }
void umain(int argc, char **argv) { int fd, r, n, n2; if ((fd = open("motd", O_RDONLY)) < 0) user_panic("open motd: %e", fd); seek(fd, 0); if ((n = readn(fd, buf, sizeof buf)) <= 0) user_panic("readn: %e", n); if ((r = fork()) < 0) user_panic("fork: %e", r); if (r == 0) { seek(fd, 0); writef("going to read in child (might page fault if your sharing is buggy)\n"); if ((n2 = readn(fd, buf2, sizeof buf2)) != n2) user_panic("read in parent got %d, read in child got %d", n, n2); if(memcmp(buf, buf2, n) != 0) user_panic("read in parent got different bytes from read in child"); writef("read in child succeeded\n"); seek(fd, 0); close(fd); exit(); } wait(r); //seek(fd, 0); if ((n2 = readn(fd, buf2, sizeof buf2)) != n) user_panic("read in parent got %d, then got %d", n, n2); writef("buf : %s\n",buf); writef("read in parent succeeded\n"); }
void umain(void) { char buf[100]; int i, pid, p[2]; if ((i=pipe(p)) < 0) user_panic("pipe: %e", i); if ((pid=fork()) < 0) user_panic("fork: %e", i); if (pid == 0) { writef("[%08x] pipereadeof close %d\n", env->env_id, p[1]); close(p[1]); writef("[%08x] pipereadeof readn %d\n", env->env_id, p[0]); i = readn(p[0], buf, sizeof buf-1); if (i < 0) user_panic("read: %e", i); buf[i] = 0; if (strcmp(buf, msg) == 0) writef("\npipe read closed properly\n"); else writef("\ngot %d bytes: %s\n", i, buf); exit(); } else { writef("[%08x] pipereadeof close %d\n", env->env_id, p[0]); close(p[0]); writef("[%08x] pipereadeof write %d\n", env->env_id, p[1]); if ((i=write(p[1], msg, strlen(msg))) != strlen(msg)) user_panic("write: %e", i); close(p[1]); } wait(pid); if ((i=pipe(p)) < 0) user_panic("pipe: %e", i); if ((pid=fork()) < 0) user_panic("fork: %e", i); if (pid == 0) { close(p[0]); for(;;){ writef("."); if(write(p[1], "x", 1) != 1) break; } writef("\npipe write closed properly\n"); } close(p[0]); close(p[1]); wait(pid); writef("pipe tests passed\n"); }
// Send val to whom. This function keeps trying until // it succeeds. It should panic() on any error other than // -E_IPC_NOT_RECV. // // Hint: use syscall_yield() to be CPU-friendly. void ipc_send(u_int whom, u_int val, u_int srcva, u_int perm) { int r; while ((r = syscall_ipc_can_send(whom, val, srcva, perm)) == -E_IPC_NOT_RECV) { syscall_yield(); //writef("QQ"); } if (r == 0) { return; } user_panic("error in ipc_send: %d", r); }
static int xioctl(int fd, int IOCTL_X, void *arg) { int ret = 0; int tries = IOCTL_RETRY; do { ret = IOCTL_VIDEO(fd, IOCTL_X, arg); } while(ret && tries-- && ((errno == EINTR) || (errno == EAGAIN) || (errno == ETIMEDOUT))); if (ret && tries <= 0) { log_itf(LOG_ERROR, "ioctl (%x) retried %i times - giving up: %s.", IOCTL_X, IOCTL_RETRY, strerror(errno)); user_panic("ioctl error."); } return (ret); }
struct video_device *create_video_device(char *device, int width, int height, int fps, int format, int jpeg_quality) { struct video_device *vd; struct v4l2_fmtdesc fmtdesc; int current_width, current_height = 0; struct v4l2_format current_format; struct v4l2_frmsizeenum fsenum; int j; vd = malloc(sizeof(struct video_device)); if (device == NULL) return NULL; if (width == 0 || height == 0) return NULL; vd->device_filename = (char *) calloc(MAX_DEVICE_FILENAME, sizeof(char)); snprintf(vd->device_filename, MAX_DEVICE_FILENAME, "%s", device); vd->width = width; vd->height = height; vd->fps = fps; vd->format_in = format; vd->use_streaming = 1; // Use mmap vd->jpeg_quality = jpeg_quality; vd->format_count = 0; vd->formats = NULL; vd->resolution_count = 0; vd->resolutions = NULL; if (init_v4l2(vd) < 0) { user_panic("Init V4L2 failed on device %s.", vd->device_filename); } // enumerating formats memset(¤t_format, 0, sizeof(struct v4l2_format)); current_format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (xioctl(vd->fd, VIDIOC_G_FMT, ¤t_format) == 0) { current_width = current_format.fmt.pix.width; current_height = current_format.fmt.pix.height; DBG("Current resolution is %dx%d on device %s.", current_width, current_height, vd->device_filename); } while (1) { memset(&fmtdesc, 0, sizeof(struct v4l2_fmtdesc)); fmtdesc.index = vd->format_count; fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE; if (xioctl(vd->fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) { break; } if (vd->formats == NULL) { vd->formats = (struct v4l2_fmtdesc*) malloc(sizeof(struct v4l2_fmtdesc)); } else { vd->formats = (struct v4l2_fmtdesc*) realloc(vd->formats, (vd->format_count + 1) *sizeof(struct v4l2_fmtdesc)); } memcpy(&vd->formats[vd->format_count], &fmtdesc, sizeof(struct v4l2_fmtdesc)); if (fmtdesc.pixelformat == format) { vd->current_format_index = vd->format_count; } DBG("%s: Supported format: %s", vd->device_filename, fmtdesc.description); memset(&fsenum, 0, sizeof(struct v4l2_frmsizeenum)); for (j = 0; ; j++) { fsenum.pixel_format = fmtdesc.pixelformat; fsenum.index = j; if (xioctl(vd->fd, VIDIOC_ENUM_FRAMESIZES, &fsenum) != 0) { break; // Stop enumeration } if (vd->resolutions == NULL) { vd->resolutions = malloc(sizeof(struct resolution)); } else { vd->resolutions = realloc(vd->resolutions, (vd->resolution_count + 1) *sizeof(struct resolution)); } vd->resolutions[vd->resolution_count].width = fsenum.discrete.width; vd->resolutions[vd->resolution_count].height = fsenum.discrete.height; vd->resolutions[vd->resolution_count].pixelformat = fmtdesc.pixelformat; if (format == fmtdesc.pixelformat) { if (fsenum.discrete.width == width && fsenum.discrete.height == height) { vd->current_resolution_index = vd->resolution_count; } } DBG("%s: supported size: %dx%d", vd->device_filename, fsenum.discrete.width, fsenum.discrete.height); vd->resolution_count += 1; } vd->format_count++; } switch(vd->format_in) { case V4L2_PIX_FMT_MJPEG: vd->framebuffer_size = vd->width * (vd->height + 8) * 2; vd->framebuffer = (unsigned char *) malloc(vd->framebuffer_size); break; case V4L2_PIX_FMT_YUYV: vd->framebuffer_size = vd->width * vd->height * 2; vd->framebuffer = (unsigned char *) malloc(vd->framebuffer_size); break; default: user_panic("init_video_in: Unsupported format."); break; } return vd; }