rem: fprintf(stderr, "Could only read %ld bytes from attribute!\n", bytesRead);
add: if (bytesRead >= 0) fprintf(stderr, "Could only read %ld bytes from attribute!\n", bytesRead); else fprintf(stderr, "Failed to read from attribute: %s\n", strerror(bytesRead));
context: catAttr(const char *attribute, const char *fileName, bool keepRaw = false){	int fd = open(fileName, O_RDONLY);	if (fd < 0)		return errno;	attr_info info;	if (fs_stat_attr(fd, attribute, &info) < 0)		return errno;	// limit size of the attribute, only the first 64k will make it on screen	off_t size = info.size;	if (size > 64 * 1024)		size = 64 * 1024;	char* buffer = new char[size];	ssize_t bytesRead = fs_read_attr(fd, attribute, info.type, 0, buffer, size);	if (bytesRead < 0) {		delete[] buffer;		return errno;	}	if (bytesRead != size) {		fprintf(stderr, "Could only read %ld bytes from attribute!\n", bytesRead);		delete[] buffer;		return B_ERROR;	}	if (keepRaw) {		off_t pos = 0;		ssize_t written = 0;		while (pos < info.size) {			// write what we have read so far			written = write(STDOUT_FILENO, buffer, bytesRead);			// check for write error			if (written < bytesRead) {				fprintf(stderr, "Could only write %ld bytes to stream!\n", written);				if (written > 0)					written = B_ERROR;				break;			}			// read next chunk of data at pos			pos += bytesRead;			bytesRead = fs_read_attr(fd, attribute, info.type, pos, buffer, size);			// check for read error			if (bytesRead < size && pos + bytesRead < info.size) {				fprintf(stderr, "Could only read %ld bytes from attribute!\n", bytesRead);				written = B_ERROR;				break;			}		}		delete[] buffer;		if (written > 0)			written = B_OK;		return written;	}	switch (info.type) {		case B_INT8_TYPE:			printf("%s : int8 : %d\n", fileName, *((int8 *)buffer));			break;		case B_UINT8_TYPE:			printf("%s : uint8 : %u\n", fileName, *((uint8 *)buffer));			break;		case B_INT16_TYPE:			printf("%s : int16 : %d\n", fileName, *((int16 *)buffer));			break;		case B_UINT16_TYPE:			printf("%s : uint16 : %u\n", fileName, *((uint16 *)buffer));			break;		case B_INT32_TYPE:			printf("%s : int32 : %ld\n", fileName, *((int32 *)buffer));			break;		case B_UINT32_TYPE:			printf("%s : uint32 : %lu\n", fileName, *((uint32 *)buffer));			break;		case B_INT64_TYPE:			printf("%s : int64 : %Ld\n", fileName, *((int64 *)buffer));			break;		case B_UINT64_TYPE:			printf("%s : uint64 : %Lu\n", fileName, *((uint64 *)buffer));			break;		case B_FLOAT_TYPE:			printf("%s : float : %f\n", fileName, *((float *)buffer));			break;		case B_DOUBLE_TYPE:			printf("%s : double : %f\n", fileName, *((double *)buffer));			break;		case B_BOOL_TYPE:			printf("%s : bool : %d\n", fileName, *((unsigned char *)buffer));			break;		case B_STRING_TYPE:		case B_MIME_STRING_TYPE:			printf("%s : string : %s\n", fileName, buffer);			break;		default:			// The rest of the attributes types are displayed as raw data			printf("%s : raw_data : \n", fileName);			dumpRawData(buffer, size);			break;	}	delete[] buffer;	return B_OK;}