From: Andre Noll Date: Thu, 8 Dec 2011 20:01:01 +0000 (+0100) Subject: Improve error diagnostics of mmap_full_file(). X-Git-Tag: v0.4.10~10^2 X-Git-Url: http://git.tue.mpg.de/?a=commitdiff_plain;h=d9566a07057f68b0effd404e2da7817555f35383;p=paraslash.git Improve error diagnostics of mmap_full_file(). On mmap errors, this function used to return the error code it got from mmap(). Unfortunately, in at least two cases, this results in rather obscure error messages: $ para_afh -i . main: No such device $ touch foo; para_afh -i foo main: Invalid argument This simple patch specifically checks whether the given fd refers to a directory or an empty file so that the error messages become more readable: $ para_afh -i . main: failed to mmap "." main: Is a directory $ touch foo; para_afh -i foo main: failed to mmap "foo" main: file is empty --- diff --git a/afh.c b/afh.c index f2745b61..04c13ebd 100644 --- a/afh.c +++ b/afh.c @@ -187,8 +187,10 @@ int main(int argc, char **argv) int ret2; ret = mmap_full_file(conf.inputs[i], O_RDONLY, &audio_file_data, &audio_file_size, &fd); - if (ret < 0) + if (ret < 0) { + PARA_ERROR_LOG("failed to mmap \"%s\"\n", conf.inputs[i]); goto out; + } ret = compute_afhi(conf.inputs[i], audio_file_data, audio_file_size, fd, &afhi); if (ret < 0) diff --git a/error.h b/error.h index 63d4d5db..39c109f9 100644 --- a/error.h +++ b/error.h @@ -441,6 +441,7 @@ extern const char **para_errlist[]; PARA_ERROR(FGETS, "fgets error"), \ PARA_ERROR(EOF, "end of file"), \ PARA_ERROR(READ_PATTERN, "did not read expected pattern"), \ + PARA_ERROR(EMPTY, "file is empty"), \ #define ALSA_WRITE_ERRORS \ diff --git a/fd.c b/fd.c index 2e05313e..9b6c6917 100644 --- a/fd.c +++ b/fd.c @@ -541,6 +541,22 @@ int mmap_full_file(const char *path, int open_mode, void **map, goto out; } *size = file_status.st_size; + /* + * If the file is empty, *size is zero and mmap() would return EINVAL + * (Invalid argument). This error is common enough to spend an extra + * error code which explicitly states the problem. + */ + ret = -E_EMPTY; + if (*size == 0) + goto out; + /* + * If fd refers to a directory, mmap() returns ENODEV (No such device), + * at least on Linux. "Is a directory" seems to be more to the point. + */ + ret = -ERRNO_TO_PARA_ERROR(EISDIR); + if (S_ISDIR(file_status.st_mode)) + goto out; + ret = para_mmap(*size, mmap_prot, mmap_flags, fd, 0, map); out: if (ret < 0 || !fd_ptr)