mirror of
https://gitlab.gnome.org/GNOME/libxml2.git
synced 2026-01-26 21:41:34 +03:00
io: Fix read/write error handling
Handle short reads/writes from fd. Fix stdio error handling.
This commit is contained in:
87
xmlIO.c
87
xmlIO.c
@@ -140,7 +140,7 @@ __xmlIOErr(int domain, int code, const char *extra)
|
|||||||
int res;
|
int res;
|
||||||
|
|
||||||
if (code == 0) {
|
if (code == 0) {
|
||||||
if (errno == 0) code = 0;
|
if (errno == 0) code = XML_IO_UNKNOWN;
|
||||||
#ifdef EACCES
|
#ifdef EACCES
|
||||||
else if (errno == EACCES) code = XML_IO_EACCES;
|
else if (errno == EACCES) code = XML_IO_EACCES;
|
||||||
#endif
|
#endif
|
||||||
@@ -557,15 +557,32 @@ xmlFdOpen(const char *filename, int write, int *out) {
|
|||||||
*
|
*
|
||||||
* Read @len bytes to @buffer from the I/O channel.
|
* Read @len bytes to @buffer from the I/O channel.
|
||||||
*
|
*
|
||||||
* Returns the number of bytes written
|
* Returns the number of bytes read
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
xmlFdRead (void * context, char * buffer, int len) {
|
xmlFdRead(void *context, char *buffer, int len) {
|
||||||
int ret;
|
int fd = (int) (ptrdiff_t) context;
|
||||||
|
int ret = 0;
|
||||||
|
int bytes;
|
||||||
|
|
||||||
|
while (len > 0) {
|
||||||
|
bytes = read(fd, buffer, len);
|
||||||
|
if (bytes < 0) {
|
||||||
|
/*
|
||||||
|
* If we already got some bytes, return them without
|
||||||
|
* raising an error.
|
||||||
|
*/
|
||||||
|
if (ret > 0)
|
||||||
|
break;
|
||||||
|
return(-xmlIOErr(0, "read()"));
|
||||||
|
}
|
||||||
|
if (bytes == 0)
|
||||||
|
break;
|
||||||
|
ret += bytes;
|
||||||
|
buffer += bytes;
|
||||||
|
len -= bytes;
|
||||||
|
}
|
||||||
|
|
||||||
ret = read((int) (ptrdiff_t) context, &buffer[0], len);
|
|
||||||
if (ret < 0)
|
|
||||||
return(-xmlIOErr(0, "fread()"));
|
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -581,13 +598,20 @@ xmlFdRead (void * context, char * buffer, int len) {
|
|||||||
* Returns the number of bytes written
|
* Returns the number of bytes written
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
xmlFdWrite (void * context, const char * buffer, int len) {
|
xmlFdWrite(void *context, const char *buffer, int len) {
|
||||||
|
int fd = (int) (ptrdiff_t) context;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
int bytes;
|
||||||
|
|
||||||
if (len > 0) {
|
while (len > 0) {
|
||||||
ret = write((int) (ptrdiff_t) context, &buffer[0], len);
|
bytes = write(fd, buffer, len);
|
||||||
if (ret < 0) xmlIOErr(0, "write()");
|
if (bytes < 0)
|
||||||
|
return(-xmlIOErr(0, "write()"));
|
||||||
|
ret += bytes;
|
||||||
|
buffer += bytes;
|
||||||
|
len -= bytes;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(ret);
|
return(ret);
|
||||||
}
|
}
|
||||||
#endif /* LIBXML_OUTPUT_ENABLED */
|
#endif /* LIBXML_OUTPUT_ENABLED */
|
||||||
@@ -707,17 +731,28 @@ xmlFileOpen(const char *filename) {
|
|||||||
*
|
*
|
||||||
* DEPRECATED: Internal function, don't use.
|
* DEPRECATED: Internal function, don't use.
|
||||||
*
|
*
|
||||||
* Returns the number of bytes written or < 0 in case of failure
|
* Returns the number of bytes read or < 0 in case of failure
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
xmlFileRead (void * context, char * buffer, int len) {
|
xmlFileRead(void * context, char * buffer, int len) {
|
||||||
int ret;
|
FILE *file = context;
|
||||||
|
size_t bytes;
|
||||||
|
|
||||||
if ((context == NULL) || (buffer == NULL))
|
if ((context == NULL) || (buffer == NULL))
|
||||||
return(-1);
|
return(-1);
|
||||||
ret = fread(&buffer[0], 1, len, (FILE *) context);
|
|
||||||
if (ret < 0)
|
/*
|
||||||
|
* The C standard doesn't mandate that fread sets errno, only
|
||||||
|
* POSIX does. The Windows documentation isn't really clear.
|
||||||
|
* Set errno to zero which will be reported as unknown error
|
||||||
|
* if fread fails without setting errno.
|
||||||
|
*/
|
||||||
|
errno = 0;
|
||||||
|
bytes = fread(buffer, 1, len, file);
|
||||||
|
if ((bytes < (size_t) len) && (ferror(file)))
|
||||||
return(-xmlIOErr(0, "fread()"));
|
return(-xmlIOErr(0, "fread()"));
|
||||||
return(ret);
|
|
||||||
|
return(len);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LIBXML_OUTPUT_ENABLED
|
#ifdef LIBXML_OUTPUT_ENABLED
|
||||||
@@ -732,17 +767,19 @@ xmlFileRead (void * context, char * buffer, int len) {
|
|||||||
* Returns the number of bytes written
|
* Returns the number of bytes written
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
xmlFileWrite (void * context, const char * buffer, int len) {
|
xmlFileWrite(void *context, const char *buffer, int len) {
|
||||||
int items;
|
FILE *file = context;
|
||||||
|
size_t bytes;
|
||||||
|
|
||||||
if ((context == NULL) || (buffer == NULL))
|
if ((context == NULL) || (buffer == NULL))
|
||||||
return(-1);
|
return(-1);
|
||||||
items = fwrite(&buffer[0], len, 1, (FILE *) context);
|
|
||||||
if ((items == 0) && (ferror((FILE *) context))) {
|
errno = 0;
|
||||||
xmlIOErr(0, "fwrite()");
|
bytes = fwrite(buffer, 1, len, file);
|
||||||
return(-1);
|
if (bytes < (size_t) len)
|
||||||
}
|
return(-xmlIOErr(0, "fwrite()"));
|
||||||
return(items * len);
|
|
||||||
|
return(len);
|
||||||
}
|
}
|
||||||
#endif /* LIBXML_OUTPUT_ENABLED */
|
#endif /* LIBXML_OUTPUT_ENABLED */
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user