Jonathan Nieder <[email protected]> writes:
> Hi Krzysztof,
>
> Sorry for the long delay in responding.
>
> Krzysztof A. Sobiecki wrote:
>
> [...]
>> +++ dash-0.5.6.1/src/input.c 2010-06-25 00:45:19.000000000 +0200
>> @@ -400,15 +402,28 @@ popstring(void)
>> */
>>
>> int
>> +isdir(const char *name)
>> +{
>> + struct stat64 st;
>> + if (stat64(name, &st) < 0)
>> + return -1;
>> + if (S_ISDIR(st.st_mode)) {
>> + return -1;
>> + }
>> + return 0;
>> +}
>
> This function does not distinguish between failures where errno is set
> and where it is not...
>
>> +
>> +int
>> setinputfile(const char *fname, int flags)
>> {
>> int fd;
>>
>> INTOFF;
>> - if ((fd = open(fname, O_RDONLY)) < 0) {
>> + if ((isdir(fname) < 0) || ((fd = open(fname, O_RDONLY)) < 0)) {
>> if (flags & INPUT_NOFILE_OK)
>> goto out;
>> - sh_error("Can't open %s", fname);
>> + exitstatus = 127;
>> + exerror(EXIFILE, "Can't open %s", fname);
>
> ... so the caller unconditionally suppresses errno.
When I will have some time, I will think about it.
> The isdir() check happens before the open(), leading to unpleasant
> behavior if a file is replaced by a directory between them.
After 5 minutes, I hacked something to work around this problem(I hope).
I have absolutely no faith about it.
> The patch fixes two issues at once: changing the exit status to 127
> and catching attempts to redirect from a directory.
I have tried to split it in two parts, but I didn't have time to do it
properly. I'm sending what I have.
> That said, do you think this could be made into two patches against
> upstream to be sent to <[email protected]>?
I don't think that this patches are good enough to send them to upstream.
d.diff depends on c.diff
diff -rup ~dash-0.5.6.1/src/error.h tdash-0.5.6.1/src/error.h
--- ~dash-0.5.6.1/src/error.h 2010-08-02 03:05:09.000000000 +0200
+++ tdash-0.5.6.1/src/error.h 2010-08-02 03:22:21.000000000 +0200
@@ -69,7 +69,7 @@ extern int exception;
#define EXSHELLPROC 2 /* execute a shell procedure */
#define EXEXEC 3 /* command execution failed */
#define EXEXIT 4 /* exit the shell */
-
+#define EXIFILE 5 /* inputfile cannot be opened or is a directory */
/*
* These macros allow the user to suspend the handling of interrupt signals
diff -rup ~dash-0.5.6.1/src/options.c tdash-0.5.6.1/src/options.c
--- ~dash-0.5.6.1/src/options.c 2010-08-02 03:05:09.000000000 +0200
+++ tdash-0.5.6.1/src/options.c 2010-08-02 03:26:06.000000000 +0200
@@ -35,6 +35,9 @@
#include <signal.h>
#include <unistd.h>
#include <stdlib.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <errno.h>
#include "shell.h"
#define DEFINE_OPTIONS
@@ -117,6 +120,23 @@ STATIC int getopts(char *, char *, char
*/
int
+isdir(const char *name)
+{
+ int fd;
+ struct stat64 st;
+
+ if ((fd = open(name, O_RDONLY))<0)
+ return -1;
+ if (fstat64(fd, &st) < 0)
+ return -1;
+ if (S_ISDIR(st.st_mode)) {
+ return -1;
+ errno = EISDIR;
+ }
+ return 0;
+}
+
+int
procargs(int argc, char **argv)
{
int i;
@@ -156,10 +176,16 @@ procargs(int argc, char **argv)
if (*xargv)
goto setarg0;
} else if (!sflag) {
- setinputfile(*xargv, 0);
+ if(!isdir(*xargv)) {
+ setinputfile(*xargv, 0);
+ }
+ else {
+ exerror(EXIFILE, "Can't open %s", *xargv);
+ }
setarg0:
- arg0 = *xargv++;
- commandname = arg0;
+ arg0 = *xargv++;
+ commandname = arg0;
+
}
shellparam.p = xargv;
diff -rup tdash-0.5.6.1/src/options.c dash-0.5.6.1/src/options.c
--- tdash-0.5.6.1/src/options.c 2010-08-02 03:26:06.000000000 +0200
+++ dash-0.5.6.1/src/options.c 2010-08-02 03:26:31.000000000 +0200
@@ -180,6 +180,7 @@ procargs(int argc, char **argv)
setinputfile(*xargv, 0);
}
else {
+ exitstatus = 127;
exerror(EXIFILE, "Can't open %s", *xargv);
}
setarg0:
--
X was an interactive protocol:
alpha blending a full-screen image looked like slugs racing down the monitor.
http://www.keithp.com/~keithp/talks/usenix2000/render.html