diff options
author | Daniel Dragan <bulk88@hotmail.com> | 2015-08-16 04:30:23 -0400 |
---|---|---|
committer | Zefram <zefram@fysh.org> | 2017-11-12 02:05:10 +0000 |
commit | d1ac83c4011b4bf51ca3fb070737a97a6c6ac545 (patch) | |
tree | dea46ad1fb806ccb24cf176b56ff606f372cc70a /pp_ctl.c | |
parent | 69374fe705978962b85217f3eb828a93f836fd8d (diff) | |
download | perl-d1ac83c4011b4bf51ca3fb070737a97a6c6ac545.tar.gz |
fix do dir returning no $!
do()ing a directory was returning false/empty string in $!, which isn't
an error, yet documentation says $! should have the error code in it.
Fix this by returning EISDIR for dirs, and EINVAL for block devices.
[perl #125774]
Remove "errno = 0" and comment added in b2da7ead68, since now there is no
scenario where errno is uninitialized, since the dir and block device
failure branches now set errno, where previously they didn't.
Diffstat (limited to 'pp_ctl.c')
-rw-r--r-- | pp_ctl.c | 25 |
1 files changed, 17 insertions, 8 deletions
@@ -3562,15 +3562,22 @@ S_check_type_and_open(pTHX_ SV *name) errno EACCES, so only do a stat to separate a dir from a real EACCES caused by user perms */ #ifndef WIN32 - /* we use the value of errno later to see how stat() or open() failed. - * We don't want it set if the stat succeeded but we still failed, - * such as if the name exists, but is a directory */ - errno = 0; - st_rc = PerlLIO_stat(p, &st); - if (st_rc < 0 || S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode)) { + if (st_rc < 0) return NULL; + else { + int eno; + if(S_ISBLK(st.st_mode)) { + eno = EINVAL; + goto not_file; + } + else if(S_ISDIR(st.st_mode)) { + eno = EISDIR; + not_file: + errno = eno; + return NULL; + } } #endif @@ -3582,8 +3589,10 @@ S_check_type_and_open(pTHX_ SV *name) int eno; st_rc = PerlLIO_stat(p, &st); if (st_rc >= 0) { - if(S_ISDIR(st.st_mode) || S_ISBLK(st.st_mode)) - eno = 0; + if(S_ISDIR(st.st_mode)) + eno = EISDIR; + else if(S_ISBLK(st.st_mode)) + eno = EINVAL; else eno = EACCES; errno = eno; |