/* ARGSUSED */ void unmap_phys_mem(void * base, unsigned long size) { DIOParPkt par; ULONG plen,vmaddr; /* We need here the VIRTADDR for unmapping, not the physical address */ /* This should be taken care of either here by keeping track of allocated */ /* pointers, but this is also already done in the driver... Thus it would */ /* be a waste to do this tracking twice. Can this be changed when the fn. */ /* is called? This would require tracking this function in all servers, */ /* and changing it appropriately to call this with the virtual adress */ /* If the above mapping function is only called once, then we can store */ /* the virtual adress and use it here.... */ par.addr = (ULONG)base; par.size = 0xffffffff; /* This is the virtual address parameter. Set this to ignore */ plen = sizeof(par); if (mapdev != -1) { DosDevIOCtl(mapdev, (ULONG)0x76, (ULONG)0x46, (PVOID)&par, (ULONG)plen, (PULONG)&plen, &vmaddr, sizeof(ULONG), &plen); callcount--; } /* Now if more than one region has been allocated and we close the driver, * the other pointers will immediately become invalid. We avoid closing * driver for now, but this should be fixed for server exit */ if(!callcount) close_mmap(); }
int main(int argc, char **argv) { int ret = 0; #ifdef TEST_CONTROLS if (argc != 8) { printf ("%s width height num_of_frames bright contrast saturation sharpness\n", argv[0]); printf("EX) $ %s 640 480 3 0 0 0 24612 \n", argv[0]); goto err; } #else if (argc != 4) { printf ("%s width height num_of_frames bright contrast saturation sharpness\n", argv[0]); printf("EX) $ %s 640 480 3\n", argv[0]); goto err; } #endif g_pix_width = atoi(argv[1]); g_pix_height = atoi(argv[2]); g_file_count = atoi(argv[3]) + 1; #ifdef TEST_CONTROLS g_brightness = atoi(argv[4]); g_contrast = atoi(argv[5]); g_saturation = atoi(argv[6]); g_sharpness = atoi(argv[7]); #endif g_img_buf = malloc(g_pix_width * g_pix_height * 3 * sizeof(char)); open_device(); set_input_chann(0); init_v4l2_device(); ret = init_mmap(&n_buffers); if (ret) errno_exit("init_mmap error !!!"); #ifdef TEST_CONTROLS start_control_testing(); #endif start_capturing(buffers); mainloop(); stop_capturing(); close_mmap(); close_device(); free(g_img_buf); exit(EXIT_SUCCESS); err: return ret; }
int main(int argc, char *argv[]) { int i, r = 1; struct ffile file_old = { .fd = -1, .addr = MAP_FAILED, }; struct ffile file_new = { .fd = -1, .addr = MAP_FAILED, }; if (argc < 3) { printf("Use: differ old_file new_file change_list.\n"); goto bad; } file_old.name = argv[1]; if (!open_mmap(&file_old)) goto bad; file_new.name = argv[2]; if (!open_mmap(&file_new)) goto bad; for (i = 3; i < argc; i++) if (check(argv[i], file_old.addr, file_new.addr) == FAIL) { printf ("FAILED for %s\n", argv[i]); r = 1; goto bad; } r = 0; bad: close_mmap(&file_new); close_mmap(&file_old); return r; }
void load(size_t begin_i, size_t end_i) { close_mmap(); begin_i = begin_i * sizeof(T) / PAGESIZE * PAGESIZE / sizeof(T); this->begin_i = begin_i; this->end_i = end_i; in_memory = true; // data_in_memory = (T *)memalign(PAGESIZE, (end_i - begin_i) * sizeof(T) + PAGESIZE); // assert(data_in_memory!=NULL); data_in_memory = (T *)mmap(0, (end_i - begin_i) * sizeof(T) + PAGESIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); assert(data_in_memory!=MAP_FAILED); long end_offset = end_i * sizeof(T); long offset = begin_i * sizeof(T); long bytes; while (offset < end_offset) { bytes = pread(fd, data_in_memory + (offset / sizeof(T) - begin_i), (end_offset - offset + PAGESIZE - 1) / PAGESIZE * PAGESIZE, offset); if (bytes==-1) { printf("%ld %ld\n", offset, end_offset); printf("%s\n", strerror(errno)); getchar(); exit(-1); } offset += bytes; } }
int main(int argc, char** argv) { int c; while ((c = getopt(argc, argv, "v:")) != -1) { switch (c) { case 'v': verbose = atoi(optarg); break; default: usage(argv[0]); } } if (optind != argc-1) usage(argv[0]); char* display = argv[optind]; trueorabort(display[0] == ':', "Invalid display: '%s'", display); char* endptr; int displaynum = (int)strtol(display+1, &endptr, 10); trueorabort(display+1 != endptr && (*endptr == '\0' || *endptr == '.'), "Invalid display number: '%s'", display); init_display(display); socket_server_init(PORT_BASE + displaynum); unsigned char buffer[BUFFERSIZE]; int length; while (1) { set_connected(dpy, False); socket_server_accept(VERSION); write_init(); set_connected(dpy, True); while (1) { length = socket_client_read_frame((char*)buffer, sizeof(buffer)); if (length < 0) { socket_client_close(1); break; } if (length < 1) { error("Invalid packet from client (size <1)."); socket_client_close(0); break; } switch (buffer[0]) { case 'S': /* Screen */ if (!check_size(length, sizeof(struct screen), "screen")) break; write_image((struct screen*)buffer); break; case 'P': /* Cursor */ if (!check_size(length, sizeof(struct cursor), "cursor")) break; write_cursor(); break; case 'R': /* Resolution */ if (!check_size(length, sizeof(struct resolution), "resolution")) break; change_resolution((struct resolution*)buffer); break; case 'K': { /* Key */ if (!check_size(length, sizeof(struct key), "key")) break; struct key* k = (struct key*)buffer; log(2, "Key: kc=%04x\n", k->keycode); XTestFakeKeyEvent(dpy, k->keycode, k->down, CurrentTime); if (k->down) { kb_add(KEYBOARD, k->keycode); } else { kb_remove(KEYBOARD, k->keycode); } break; } case 'C': { /* Click */ if (!check_size(length, sizeof(struct mouseclick), "mouseclick")) break; struct mouseclick* mc = (struct mouseclick*)buffer; XTestFakeButtonEvent(dpy, mc->button, mc->down, CurrentTime); if (mc->down) { kb_add(MOUSE, mc->button); } else { kb_remove(MOUSE, mc->button); } break; } case 'M': { /* Mouse move */ if (!check_size(length, sizeof(struct mousemove), "mousemove")) break; struct mousemove* mm = (struct mousemove*)buffer; XTestFakeMotionEvent(dpy, 0, mm->x, mm->y, CurrentTime); break; } case 'Q': /* "Quit": release all keys */ kb_release_all(); break; default: error("Invalid packet from client (%d).", buffer[0]); socket_client_close(0); } } socket_client_close(0); kb_release_all(); close_mmap(&cache[0]); close_mmap(&cache[1]); } return 0; }
/* Finds NaCl/Chromium shm memory using external handler. * Reply must be in the form PID:file */ struct cache_entry* find_shm(uint64_t paddr, uint64_t sig, size_t length) { struct cache_entry* entry = NULL; /* Find entry in cache */ if (cache[0].paddr == paddr) { entry = &cache[0]; } else if (cache[1].paddr == paddr) { entry = &cache[1]; } else { /* Not found: erase an existing entry. */ entry = &cache[next_entry]; next_entry = (next_entry + 1) % 2; close_mmap(entry); } int try; for (try = 0; try < 2; try++) { /* Check signature */ if (entry->map) { if (*((uint64_t*)entry->map) == sig) return entry; log(1, "Invalid signature, fetching new shm!"); close_mmap(entry); } /* Setup parameters and run command */ char arg1[32], arg2[32]; int c; c = snprintf(arg1, sizeof(arg1), "%08lx", (long)paddr & 0xffffffff); trueorabort(c > 0, "snprintf"); int i, p = 0; for (i = 0; i < 8; i++) { c = snprintf(arg2 + p, sizeof(arg2) - p, "%02x", ((uint8_t*)&sig)[i]); trueorabort(c > 0, "snprintf"); p += c; } char* cmd = "croutonfindnacl"; char* args[] = {cmd, arg1, arg2, NULL}; char buffer[256]; log(2, "Running %s %s %s", cmd, arg1, arg2); c = popen2(cmd, args, NULL, 0, buffer, sizeof(buffer)); if (c <= 0) { error("Error running helper."); return NULL; } buffer[c < sizeof(buffer) ? c : (sizeof(buffer)-1)] = 0; log(2, "Result: %s", buffer); /* Parse PID:file output */ char* cut = strchr(buffer, ':'); if (!cut) { error("No ':' in helper reply: %s.", cut); return NULL; } *cut = 0; char* endptr; long pid = strtol(buffer, &endptr, 10); if(buffer == endptr || *endptr != '\0') { error("Invalid pid: %s", buffer); return NULL; } char* file = cut+1; log(2, "PID:%ld, FILE:%s", pid, file); entry->paddr = paddr; entry->fd = open(file, O_RDWR); if (entry->fd < 0) { error("Cannot open file %s\n", file); return NULL; } entry->length = length; entry->map = mmap(NULL, length, PROT_READ|PROT_WRITE, MAP_SHARED, entry->fd, 0); if (!entry->map) { error("Cannot mmap %s\n", file); close(entry->fd); return NULL; } log(2, "mmap ok %p %zu %d", entry->map, entry->length, entry->fd); } error("Cannot find shm."); return NULL; } /* WebSocket functions */ XImage* img = NULL; XShmSegmentInfo shminfo; /* Writes framebuffer image to websocket/shm */ int write_image(const struct screen* screen) { char reply_raw[FRAMEMAXHEADERSIZE + sizeof(struct screen_reply)]; struct screen_reply* reply = (struct screen_reply*)(reply_raw + FRAMEMAXHEADERSIZE); int refresh = 0; memset(reply_raw, 0, sizeof(reply_raw)); reply->type = 'S'; reply->width = screen->width; reply->height = screen->height; /* Allocate XShmImage */ if (!img || img->width != screen->width || img->height != screen->height) { if (img) { XDestroyImage(img); shmdt(shminfo.shmaddr); shmctl(shminfo.shmid, IPC_RMID, 0); } /* FIXME: Some error checking should happen here... */ img = XShmCreateImage(dpy, DefaultVisual(dpy, 0), 24, ZPixmap, NULL, &shminfo, screen->width, screen->height); trueorabort(img, "XShmCreateImage"); shminfo.shmid = shmget(IPC_PRIVATE, img->bytes_per_line*img->height, IPC_CREAT|0777); trueorabort(shminfo.shmid != -1, "shmget"); shminfo.shmaddr = img->data = shmat(shminfo.shmid, 0, 0); trueorabort(shminfo.shmaddr != (void*)-1, "shmat"); shminfo.readOnly = False; int ret = XShmAttach(dpy, &shminfo); trueorabort(ret, "XShmAttach"); /* Force refresh */ refresh = 1; } if (screen->refresh) { log(1, "Force refresh from client."); /* refresh forced by the client */ refresh = 1; } XEvent ev; /* Register damage on new windows */ while (XCheckTypedEvent(dpy, MapNotify, &ev)) { register_damage(dpy, ev.xcreatewindow.window); refresh = 1; } /* Check for damage */ while (XCheckTypedEvent(dpy, damageEvent + XDamageNotify, &ev)) { refresh = 1; } /* Check for cursor events */ reply->cursor_updated = 0; while (XCheckTypedEvent(dpy, fixesEvent + XFixesCursorNotify, &ev)) { XFixesCursorNotifyEvent* curev = (XFixesCursorNotifyEvent*)&ev; if (verbose >= 2) { char* name = XGetAtomName(dpy, curev->cursor_name); log(2, "cursor! %ld %s", curev->cursor_serial, name); XFree(name); } reply->cursor_updated = 1; reply->cursor_serial = curev->cursor_serial; } /* No update */ if (!refresh) { reply->shm = 0; reply->updated = 0; socket_client_write_frame(reply_raw, sizeof(*reply), WS_OPCODE_BINARY, 1); return 0; } /* Get new image from framebuffer */ XShmGetImage(dpy, DefaultRootWindow(dpy), img, 0, 0, AllPlanes); int size = img->bytes_per_line * img->height; trueorabort(size == screen->width*screen->height*4, "Invalid screen byte count"); trueorabort(screen->shm, "Non-SHM rendering is not supported"); struct cache_entry* entry = find_shm(screen->paddr, screen->sig, size); reply->shm = 1; reply->updated = 1; reply->shmfailed = 0; if (entry && entry->map) { if (size == entry->length) { memcpy(entry->map, img->data, size); msync(entry->map, size, MS_SYNC); } else { /* This should never happen (it means the client passed an * outdated buffer to us). */ error("Invalid shm entry length (client bug!)."); reply->shmfailed = 1; } } else { /* Keep the flow going, even if we cannot find the shm. Next time * the NaCl client reallocates the buffer, we are likely to be able * to find it. */ error("Cannot find shm, moving on..."); reply->shmfailed = 1; } /* Confirm write is done */ socket_client_write_frame(reply_raw, sizeof(*reply), WS_OPCODE_BINARY, 1); return 0; } /* Writes cursor image to websocket */ int write_cursor() { XFixesCursorImage *img = XFixesGetCursorImage(dpy); if (!img) { error("XFixesGetCursorImage returned NULL"); return -1; } int size = img->width*img->height; const int replylength = sizeof(struct cursor_reply) + size*sizeof(uint32_t); char reply_raw[FRAMEMAXHEADERSIZE + replylength]; struct cursor_reply* reply = (struct cursor_reply*)(reply_raw + FRAMEMAXHEADERSIZE); memset(reply_raw, 0, sizeof(*reply_raw)); reply->type = 'P'; reply->width = img->width; reply->height = img->height; reply->xhot = img->xhot; reply->yhot = img->yhot; reply->cursor_serial = img->cursor_serial; /* This casts long[] to uint32_t[] */ int i; for (i = 0; i < size; i++) reply->pixels[i] = img->pixels[i]; socket_client_write_frame(reply_raw, replylength, WS_OPCODE_BINARY, 1); XFree(img); return 0; }
~BigVector() { if (is_open && file_exists(path)) { close_mmap(); } }