Commit a7a24954 authored by Benoît Minisini's avatar Benoît Minisini
Browse files

Fix how 'Lof()' behaves on special files, and how read watches are...

Fix how 'Lof()' behaves on special files, and how read watches are automatically disabled or not. Add a new "Unknown stream size" error.

[INTERPRETER]
* NEW: New "Unknown stream size" error when 'Lof()' cannot know the size of a stream.
* BUG: If we can't know the size of a stream watched for reading, then we don't unwatch it automatically anymore.
* BUG: Streams based on non-regular file descriptors (devices for example) opened in direct mode now never use 'fstat()' for getting the file length.
parent 2b66c080
......@@ -49,7 +49,7 @@ int ERROR_depth = 0;
static int _lock = 0;
static char *_print_prefix = NULL;
static const char *const _message[77] =
static const char *const _message[78] =
{
/* 0 E_UNKNOWN */ "Unknown error",
/* 1 E_MEMORY */ "Out of memory",
......@@ -127,7 +127,8 @@ static const char *const _message[77] =
/* 73 E_ASSERT */ "Assertion failed",
/* 74 E_MARRAY */ "Multidimensional array",
/* 75 E_UCLASS */ ".1Unknown class '&1'",
/* 76 E_SPEC */ ".2Incorrect declaration of symbol '&1' in class '&2'"
/* 76 E_SPEC */ ".2Incorrect declaration of symbol '&1' in class '&2'",
/* 77 E_USIZE */ "Unknow stream size"
};
static void clear_info(ERROR_INFO *info)
......
......@@ -113,7 +113,8 @@ enum {
E_ASSERT,
E_MARRAY,
E_UCLASS,
E_SPEC
E_SPEC,
E_USIZE
};
#ifndef __GB_ERROR_C
......
......@@ -80,12 +80,11 @@ static GB_FUNCTION _term_resize_func;
static void callback_read(int fd, int type, CSTREAM *_object)
{
STREAM *stream = CSTREAM_TO_STREAM(_object);
int64_t lof;
int64_t len;
STREAM_read_ahead(stream);
STREAM_lof(stream, &lof);
if (lof > 0)
if (STREAM_lof_safe(stream, &len) || len > 0)
GB_Raise(_object, EVENT_Read, 0);
else
{
......
......@@ -107,7 +107,7 @@ bool STREAM_in_archive(const char *path)
return FALSE;
}
int STREAM_get_readable(STREAM *stream, int *len)
bool STREAM_get_readable(STREAM *stream, int *len)
{
int fd;
off_t off;
......@@ -124,7 +124,7 @@ int STREAM_get_readable(STREAM *stream, int *len)
if (!stream->common.no_fionread)
{
if (ioctl(fd, FIONREAD, len) >= 0)
return 0;
return FALSE;
stream->common.no_fionread = TRUE;
}
......@@ -145,7 +145,7 @@ int STREAM_get_readable(STREAM *stream, int *len)
off = lseek(fd, off, SEEK_SET);
if (off >= 0)
return 0;
return FALSE;
}
}
......@@ -153,7 +153,7 @@ int STREAM_get_readable(STREAM *stream, int *len)
}
//fprintf(stderr, "STREAM_get_readable: lseek: %d\n", *len);
return (-1);
return TRUE;
}
bool STREAM_default_eof(STREAM *stream)
......@@ -168,10 +168,13 @@ bool STREAM_default_eof(STREAM *stream)
if (STREAM_is_blocking(stream) && !stream->common.available_now)
wait_for_fd_ready_to_read(STREAM_handle(stream));
if (STREAM_get_readable(stream, &ilen))
return TRUE;
return (ilen == 0);
if (!STREAM_get_readable(stream, &ilen))
{
fprintf(stderr, "STREAM_get_readable -> %d\n", ilen);
return (ilen == 0);
}
return FALSE; // Unable to get the remaining size.
}
// STREAM_open *MUST* initialize completely the stream structure
......@@ -1918,15 +1921,11 @@ __ERROR:
}
void STREAM_lof(STREAM *stream, int64_t *len)
bool STREAM_lof_safe(STREAM *stream, int64_t *len)
{
int fd;
int ilen;
STREAM_EXTRA *extra;
if (STREAM_is_closed(stream))
THROW(E_CLOSED);
*len = 0;
if (stream->type->lof)
......@@ -1935,9 +1934,10 @@ void STREAM_lof(STREAM *stream, int64_t *len)
goto ADD_BUFFER;
}
fd = STREAM_handle(stream);
if ((fd >= 0) && (STREAM_get_readable(stream, &ilen) == 0))
*len = ilen;
if (STREAM_get_readable(stream, &ilen))
return TRUE;
*len = ilen;
ADD_BUFFER:
......@@ -1949,6 +1949,18 @@ ADD_BUFFER:
if (extra->buffer)
*len += extra->buffer_len - extra->buffer_pos;
}
return FALSE;
}
void STREAM_lof(STREAM *stream, int64_t *len)
{
if (STREAM_is_closed(stream))
THROW(E_CLOSED);
if (STREAM_lof_safe(stream, len))
THROW(E_USIZE);
}
......
......@@ -231,7 +231,6 @@ STREAM_CLASS stream = \
#define STREAM_BUFFER_SIZE 1024
bool STREAM_in_archive(const char *path);
//int STREAM_get_readable(int fd, long *len);
void STREAM_open(STREAM *stream, const char *path, int mode);
......@@ -254,6 +253,7 @@ void STREAM_write_type(STREAM *stream, TYPE type, VALUE *value);
void STREAM_write_eol(STREAM *stream);
void STREAM_flush(STREAM *stream);
int STREAM_handle(STREAM *stream);
bool STREAM_lof_safe(STREAM *stream, int64_t *len);
void STREAM_lof(STREAM *stream, int64_t *len);
bool STREAM_eof(STREAM *stream);
bool STREAM_default_eof(STREAM *stream);
......@@ -272,7 +272,7 @@ void STREAM_blocking(STREAM *stream, bool block);
#define STREAM_is_blocking(_stream) ((_stream)->common.blocking)
void STREAM_check_blocking(STREAM *stream);
int STREAM_get_readable(STREAM *stream, int *len);
bool STREAM_get_readable(STREAM *stream, int *len);
void STREAM_exit(void);
......
......@@ -67,6 +67,9 @@ static int stream_open(STREAM *stream, const char *path, int mode)
default: fmode |= O_RDONLY;
}
stream->direct.has_size = FALSE;
stream->direct.use_size = FALSE;
if (path[0] == '.' && isdigit(path[1]))
{
if ((mode & GB_ST_CREATE) || (mode & GB_ST_APPEND))
......@@ -116,14 +119,13 @@ static int stream_open(STREAM *stream, const char *path, int mode)
{
stream->common.available_now = FALSE;
stream->common.no_read_ahead = TRUE;
stream->direct.has_size = TRUE;
fcntl(fd, F_SETFL, O_NONBLOCK);
}
else
stream->common.available_now = TRUE;
}
stream->direct.has_size = FALSE;
FD = fd;
return FALSE;
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment