Jonathan Nieder <jrnie...@gmail.com> 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 <d...@vger.kernel.org>?
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

Reply via email to