C Minishell Command Expansion Printing Gibberish

Posted by Optimus_Pwn on Programmers See other posts from Programmers or by Optimus_Pwn
Published on 2012-11-19T04:30:14Z Indexed on 2012/11/19 5:25 UTC
Read the original article Hit count: 231

Filed under:
|
|
|
|

I'm writing a unix minishell in C, and am at the point where I'm adding command expansion. What I mean by this is that I can nest commands in other commands, for example:

$> echo hello $(echo world! ... $(echo and stuff))
hello world! ... and stuff

I think I have it working mostly, however it isn't marking the end of the expanded string correctly, for example if I do:

$> echo a $(echo b $(echo c))
a b c
$> echo d $(echo e)
d e c

See it prints the c, even though I didn't ask it to. Here is my code:

msh.c - http://pastebin.com/sd6DZYwB expand.c - http://pastebin.com/uLqvFGPw

I have a more code, but there's a lot of it, and these are the parts that I'm having trouble with at the moment. I'll try to tell you the basic way I'm doing this.

Main is in msh.c, here it gets a line of input from either the commandline or a shellfile, and then calls processline (char *line, int outFD, int waitFlag), where line is the line we just got, outFD is the file descriptor of the output file, and waitFlag tells us whether or not we should wait if we fork. When we call this from main we do it like this:

processline (buffer, 1, 1);

In processline, we allocate a new line:

char expanded_line[EXPANDEDLEN];

We then call expand, in expand.c:

expand(line, expanded_line, EXPANDEDLEN);

In expand, we copy the characters literally from line to expanded_line until we find a $(, which then calls:

static int expCmdOutput(char *orig, char *new, int *oldl_ind, int *newl_ind)

orig is line, and new is expanded line. oldl_ind and newl_ind are the current positions in the line and expanded line, respectively. Then we pipe, and recursively call processline, passing it the nested command(for example, if we had "echo a $(echo b)", we would pass processline "echo b").

This is where I get confused, each time expand is called, is it allocating a new chunk of memory EXPANDEDLEN long? If so, this is bad because I'll run out of stack room really quickly(in the case of a hugely nested commandline input). In expand I insert a null character at the end of the expanded string, so why is it printing past it?

If you guys need any more code, or explanations, just ask. Secondly, I put the code in pastebin because there's a ton of it, and in my experience people don't like it when I fill up several pages with code.

Thanks.

© Programmers or respective owner

Related posts about c

    Related posts about unix