/* * Getdents put routine for 64-bit ABI, uio form. */ static int xfs_dir2_put_dirent64_uio( xfs_dir2_put_args_t *pa) { xfs_dirent_t *idbp; /* dirent pointer */ int namelen; /* entry name length */ int reclen; /* entry total length */ int rval; /* return value */ uio_t *uio; /* I/O control */ namelen = pa->namelen; reclen = DIRENTSIZE(namelen); uio = pa->uio; /* * Won't fit in the remaining space. */ if (reclen > uio->uio_resid) { pa->done = 0; return 0; } idbp = pa->dbp; idbp->d_reclen = reclen; idbp->d_ino = pa->ino; idbp->d_off = pa->cook; idbp->d_name[namelen] = '\0'; memcpy(idbp->d_name, pa->name, namelen); rval = uio_read((caddr_t)idbp, reclen, uio); pa->done = (rval == 0); return rval; }
static int debugCmdCat(DebugContext *debugContext, int argc, char *argv[]) { uio_Handle *handle; #define READBUFSIZE 0x10000 char readBuf[READBUFSIZE]; char *bufPtr; ssize_t numInBuf, numWritten; size_t totalWritten; if (argc != 2) { fprintf(debugContext->err, "Invalid number of arguments.\n"); return 1; } handle = uio_open(debugContext->cwd, argv[1], O_RDONLY #ifdef WIN32 | O_BINARY #endif , 0); if (handle == NULL) { fprintf(debugContext->err, "Could not open file: %s\n", strerror(errno)); return 1; } totalWritten = 0; while (1) { numInBuf = uio_read(handle, readBuf, READBUFSIZE); if (numInBuf == -1) { if (errno == EINTR) continue; fprintf(debugContext->err, "Could not read from file: %s\n", strerror(errno)); uio_close(handle); return 1; } if (numInBuf == 0) break; bufPtr = readBuf; do { numWritten = write(fileno(debugContext->out), bufPtr, numInBuf); if (numWritten == -1) { if (errno == EINTR) continue; fprintf(debugContext->err, "Could not read from file: %s\n", strerror(errno)); uio_close(handle); } numInBuf -= numWritten; bufPtr += numWritten; totalWritten += numWritten; } while (numInBuf > 0); } fprintf(debugContext->out, "[%u bytes]\n", (unsigned int) totalWritten); uio_close(handle); return 0; }
int uio_copyFileBlock(uio_FileBlock *block, off_t offset, char *buffer, size_t length) { if (block->flags & uio_FB_USE_MMAP) { // TODO errno = ENOSYS; return -1; } else { ssize_t numCopied = 0; ssize_t readResult; // Don't go beyond the end of the block. if (offset > (off_t) block->blockSize) return 0; if (length > block->blockSize - offset) length = block->blockSize - offset; // Check whether (part of) the requested data is already in our // own buffer. if (block->buffer != NULL && offset >= block->bufOffset && offset < block->bufOffset + (off_t) block->bufFill) { size_t toCopy = block->bufFill - offset; if (toCopy > length) toCopy = length; memcpy(buffer, block->buffer + (offset - block->bufOffset), toCopy); numCopied += toCopy; length -= toCopy; if (length == 0) return numCopied; buffer += toCopy; offset += toCopy; } // TODO: lock handle if (uio_lseek(block->handle, block->offset + offset, SEEK_SET) == (off_t) -1) { // errno is set return -1; } readResult = uio_read(block->handle, buffer, length); // TODO: unlock handle if (readResult == -1) { // errno is set return -1; } numCopied += readResult; return numCopied; } }
int main (int argc, char **argv) { struct uio_info_t *info_list, *p; program_name = argv[0]; decode_switches (argc, argv); if (uio_offset < 0) { fprintf(stderr, "Negative offsets are not supported.\n"); usage (-EINVAL); } if (opt_help) usage(0); if (opt_version) version(0); info_list = uio_find_devices(uio_filter); if (!info_list) printf("No UIO devices found.\n"); p = info_list; while (p) { char dev_name[16]; int fd; uio_get_all_info(p); uio_get_device_attributes(p); snprintf(dev_name,sizeof(dev_name),"/dev/uio%d",p->uio_num); fd = open(dev_name,O_RDWR); if (fd<0) { close(fd); p = p->next; continue; } uio_single_mmap(p,uio_map,fd); if (opt_read) uio_read(p); if (opt_write) uio_write(p); close(fd); p = p->next; } uio_free_info(info_list); exit (0); }
/* * Copy a file with path srcName to a file with name newName. * If the destination already exists, the operation fails. * Links are followed. * Special files (fifos, char devices, block devices, etc) will be * read as long as there is data available and the destination will be * a regular file with that data. * The new file will have the same permissions as the old. * If an error occurs during copying, an attempt will be made to * remove the copy. */ int copyFile (uio_DirHandle *srcDir, const char *srcName, uio_DirHandle *dstDir, const char *newName) { uio_Handle *src, *dst; struct stat sb; #define BUFSIZE 65536 uint8 *buf, *bufPtr; ssize_t numInBuf, numWritten; src = uio_open (srcDir, srcName, O_RDONLY #ifdef WIN32 | O_BINARY #endif , 0); if (src == NULL) return -1; if (uio_fstat (src, &sb) == -1) return copyError (src, NULL, NULL, NULL, NULL); dst = uio_open (dstDir, newName, O_WRONLY | O_CREAT | O_EXCL #ifdef WIN32 | O_BINARY #endif , sb.st_mode & (S_IRWXU | S_IRWXG | S_IRWXO)); if (dst == NULL) return copyError (src, NULL, NULL, NULL, NULL); buf = HMalloc(BUFSIZE); // This was originally a statically allocated buffer, // but as this function might be run from a thread with // a small Stack, this is better. while (1) { numInBuf = uio_read (src, buf, BUFSIZE); if (numInBuf == -1) { if (errno == EINTR) continue; return copyError (src, dst, dstDir, newName, buf); } if (numInBuf == 0) break; bufPtr = buf; do { numWritten = uio_write (dst, bufPtr, numInBuf); if (numWritten == -1) { if (errno == EINTR) continue; return copyError (src, dst, dstDir, newName, buf); } numInBuf -= numWritten; bufPtr += numWritten; } while (numInBuf > 0); } HFree (buf); uio_close (src); uio_close (dst); errno = 0; return 0; }
static inline ssize_t uio_accessFileBlockNoMmap(uio_FileBlock *block, off_t offset, size_t length, char **buffer) { ssize_t numRead; off_t start; off_t end; size_t bufSize; char *oldBuffer; //size_t oldBufSize; // Don't go beyond the end of the block. if (offset > (off_t) block->blockSize) { *buffer = block->buffer; return 0; } if (length > block->blockSize - offset) length = block->blockSize - offset; if (block->buffer != NULL) { // Check whether the requested data is already in the buffer. if (offset >= block->bufOffset && (offset - block->bufOffset) + length < block->bufFill) { *buffer = block->buffer + (offset - block->bufOffset); return length; } } if (length < block->readAheadBufSize && (block->flags & uio_FB_USAGE_MASK) != 0) { // We can buffer more data. switch (block->flags & uio_FB_USAGE_MASK) { case uio_FB_USAGE_FORWARD: // Read extra data after the requested data. start = offset; end = (block->readAheadBufSize > block->blockSize - offset) ? block->blockSize : offset + block->readAheadBufSize; break; case uio_FB_USAGE_BACKWARD: // Read extra data before the requested data. end = offset + length; start = (end <= (off_t) block->blockSize) ? 0 : end - block->bufSize; break; case uio_FB_USAGE_FORWARD | uio_FB_USAGE_BACKWARD: { // Read extra data both before and after the requested data. off_t extraBefore = (block->readAheadBufSize - length) / 2; start = (offset < extraBefore) ? 0 : offset - extraBefore; end = (block->readAheadBufSize > block->blockSize - start) ? block->blockSize : start + block->readAheadBufSize; break; } } } else { start = offset; end = offset + length; } bufSize = (length > block->readAheadBufSize) ? length : block->readAheadBufSize; // Start contains the start index in the block of the data we're going // to read. // End contains the end index. // bufSize contains the size of the buffer. bufSize >= end - start. oldBuffer = block->buffer; //oldBufSize = block->bufSize; if (block->buffer != NULL || block->bufSize != bufSize) { // We don't have a buffer, or we have one, but of the wrong size. block->buffer = uio_malloc(bufSize); block->bufSize = bufSize; } if (oldBuffer != NULL) { // TODO: If we have part of the data still in the old buffer, we // can keep that. // memmove(...) if (oldBuffer != block->buffer) uio_free(oldBuffer); } block->bufFill = 0; block->bufOffset = start; // TODO: lock handle if (uio_lseek(block->handle, block->offset + start, SEEK_SET) == (off_t) -1) { // errno is set return -1; } numRead = uio_read(block->handle, block->buffer, end - start); if (numRead == -1) { // errno is set // TODO: unlock handle return -1; } // TODO: unlock handle block->bufFill = numRead; *buffer = block->buffer + (offset - block->bufOffset); if (numRead <= (offset - block->bufOffset)) return 0; if ((size_t) numRead >= length) return length; return numRead - offset; }