Skip to content

Commit 2bc9e55

Browse files
committed
Trim colon from device names
1 parent 57f199e commit 2bc9e55

File tree

1 file changed

+64
-6
lines changed

1 file changed

+64
-6
lines changed

src/command.c

Lines changed: 64 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,9 @@
5353
#ifndef _A_DEVICE
5454
#define _A_DEVICE 0x40u
5555
#endif
56+
#ifndef FA_DEVICE
57+
#define FA_DEVICE 0x40u
58+
#endif
5659
#include <libc/dosio.h>
5760
#include <pc.h>
5861
#include <io.h>
@@ -361,6 +364,42 @@ static void conv_unix_path_to_ms_dos(char *path)
361364
}
362365
}
363366

367+
/* check for form "NUL:"
368+
* returns:
369+
* -1 for invalid name (maybe has colon suffix, but doesn't resolve to a device)
370+
* 0 for a name without colon
371+
* 1 for is a device name with colon at position (*colon) */
372+
static int is_device_with_colon(const char *name, int *colon)
373+
{
374+
int ret = -1;
375+
int len;
376+
char *s, *pcolon;
377+
finddata_t ff;
378+
379+
pcolon = strchr(name, ':');
380+
if (!pcolon) // Plain device name or file
381+
return 0;
382+
383+
len = strlen(name);
384+
if (&name[len - 1] != pcolon) // More than one colon, or it's not the last character
385+
return -1;
386+
387+
if (len < 3) // Single ':' or probable drive '?:'
388+
return -1;
389+
390+
s = strndup(name, len - 1);
391+
if (!s)
392+
return -1;
393+
394+
if (findfirst_f(s, &ff, FA_DEVICE, NULL) == 0 && ff.ff_attrib == _A_DEVICE) {
395+
*colon = len - 1;
396+
ret = 1;
397+
}
398+
399+
free(s);
400+
return ret;
401+
}
402+
364403
static int is_drive_spec(char *s) // check for form "A:"
365404
{
366405
if (!isalpha(s[0]))
@@ -4568,13 +4607,31 @@ static void exec_cmd(int call)
45684607
}
45694608
else // open the pipe file
45704609
{
4571-
if (pipe_file_redir_count[STDIN_INDEX] > 0)
4610+
int colon, rc;
4611+
4612+
if (pipe_file_redir_count[STDIN_INDEX] > 0) {
4613+
rc = is_device_with_colon(pipe_file[STDIN_INDEX], &colon);
4614+
if (rc == -1) {
4615+
cprintf("Invalid standard input device name '%s'\r\n", pipe_file[STDIN_INDEX]);
4616+
goto Exit;
4617+
} else if (rc == 1) {
4618+
pipe_file[STDIN_INDEX][colon] = '\0';
4619+
}
45724620
pipe_fno[STDIN_INDEX] = open(pipe_file[STDIN_INDEX], O_TEXT|O_RDONLY, S_IRUSR);
4621+
}
45734622

4574-
if (pipe_file_redir_count[STDOUT_INDEX] > 1)
4575-
pipe_fno[STDOUT_INDEX] = open(pipe_file[STDOUT_INDEX], O_BINARY|O_WRONLY|O_APPEND|O_CREAT, S_IRUSR | S_IWUSR); // open for append
4576-
else if (pipe_file_redir_count[STDOUT_INDEX] == 1)
4577-
pipe_fno[STDOUT_INDEX] = open(pipe_file[STDOUT_INDEX], O_BINARY|O_WRONLY|O_TRUNC|O_CREAT, S_IRUSR | S_IWUSR); // open as new file
4623+
if (pipe_file_redir_count[STDOUT_INDEX] > 0) {
4624+
rc = is_device_with_colon(pipe_file[STDOUT_INDEX], &colon);
4625+
if (rc == -1) {
4626+
cprintf("Invalid standard output device name '%s'\r\n", pipe_file[STDOUT_INDEX]);
4627+
goto Exit;
4628+
} else if (rc == 1) {
4629+
pipe_file[STDOUT_INDEX][colon] = '\0';
4630+
}
4631+
if (pipe_file_redir_count[STDOUT_INDEX] == 1)
4632+
pipe_fno[STDOUT_INDEX] = open(pipe_file[STDOUT_INDEX], O_BINARY|O_WRONLY|O_TRUNC|O_CREAT, S_IRUSR | S_IWUSR); // open as new file
4633+
else
4634+
pipe_fno[STDOUT_INDEX] = open(pipe_file[STDOUT_INDEX], O_BINARY|O_WRONLY|O_APPEND|O_CREAT, S_IRUSR | S_IWUSR); // open for append
45784635

45794636
/* check for error
45804637
if (pipe_fno[pipe_index] < 0 ||
@@ -4589,6 +4646,7 @@ static void exec_cmd(int call)
45894646
goto Exit;
45904647
} */
45914648
}
4649+
}
45924650

45934651
for (pipe_index = 0; pipe_index < 2; pipe_index++)
45944652
{
@@ -4666,7 +4724,7 @@ static void exec_cmd(int call)
46664724
exec_cmd(true);
46674725
}
46684726

4669-
/* Exit: */
4727+
Exit:
46704728
cmd_line[0] = '\0';
46714729
if (redir_result[STDIN_INDEX] != -1) {
46724730
dup2(old_std_fno[STDIN_INDEX], STDIN_INDEX);

0 commit comments

Comments
 (0)