Example #1
0
/*
 * 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;
}
Example #2
0
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;
}
Example #3
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;
	}
}
Example #4
0
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);
}
Example #5
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;
}
Example #6
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;
}