I am getting this compiler error:

gcc -g -Wall -O2 -c -o mybash.o mybash.c
mybash.c: In function ‘main’:
mybash.c:39: warning: implicit declaration of function ‘getline’
mybash.c:41: error: expected expression before ‘)’ token
make: *** [mybash.o] Error 1

It probably has to do with something I don't remember about initializing and using structs in c (its been awhile). Any help would be much appreciated.

Here is my main:

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>
#include <unistd.h>
#include "parser.h"

int main(int argc, char *argv[])
{
    int bytes_read;
    int nbytes = 1000;
    char *buf;
    char *command = NULL;
    char *args[11] = { 0 };
    int numargs = 0;
    int numcommands = 0; 
    char *infile = NULL;
    char *outfile = NULL;
    int  background = 0;
    struct Command com = {command, {args[11]}, numargs};
    struct CommandData data = {{com}, numcommands, infile, outfile, background};

    while (1) {
        /* Display the current working directory */
        printf("\n%s>", getcwd(NULL, 0));
	
	/* Prepare buffer and get the data from the user */
	buf = (char *) malloc (nbytes + 1);
  	bytes_read = getline(&buf, &nbytes, stdin);

	int succeed = ParseCommandLine(buf, data*);

	if (succeed == 0) {
	    printf("Bad data, unsuccessful parse\n");
	    break;
	} 

        printf("%s\n", buf);
	break;
    }
    exit(0);
}

And the is the Header Info:

struct Command {
  char *command;
  char *args[11];
  int numargs;
};

struct CommandData {
  struct Command TheCommands[20];  /* the commands to be
          executed.  TheCommands[0] is the first command
          to be executed.  Its output is piped to
          TheCommands[1], etc. */
  int numcommands; /* the number of commands in the above array */
  char *infile;   /* the file for input redirection, NULL if none */
  char *outfile;  /* the file for output redirection, NULL if none */
  int  background;  /* 0 if process is to run in foreground, 1 if in background */
};

extern int ParseCommandLine(char *, struct CommandData *);
int succeed = ParseCommandLine(buf, data*);

The above line does not make sense.

You want to pass the address of data to the function ParseCommandLine.

So the code should be

int succeed = ParseCommandLine(buf, &data);

Edited 6 Years Ago by thomas_naveen: changed ICODE to CODE

Why is this Seg Faulting!

Here is the exact relavent Data:
data.numcommands = 2; // TheCommands[0] and TheCommands[1]
data.TheCommands[0].numargs = 1
data.TheCommands[1].numargs = 1

/* Check and print out commands and arguments */ 
	        	printf("Number of commands        : %d\n", data.numcommands);
	        	printf("Number of args        : %d\n", data.TheCommands[0].numargs);
			int i = 0, j = 0;			
			for (i = 0; i < data.numcommands; i++) {
				printf("Entering outer loop (i)\n");
				printf("command%d			 : %s\n", i+1, data.TheCommands[i].command);
				printf("i = %d, j = %d\n", i, j);

				for (j = 0; j < data.TheCommands[i].numargs; j++) {
					printf("Entering inner loop (j)\n");
					printf("args[%d  : %s\n", j, data.TheCommands[i].args[j]);				
					printf("i = %d, j = %d\n", i, j);
					printf("i = %d, numcommands = %d\n", i+1, data.numcommands);
				}
			}

I get this output when running on a Solaris machine:
Number of commands : 2
Number of args : 1
Entering outer loop (i)
command1 : the_command
i = 0, j = 0
Entering inner loop (j)
args[0] : the_argument
i = 0, j = 0
i = 1, numcommands = 2
Entering outer loop (i)
command2 : 2nd_command
i = 1, j = 1
Entering inner loop (j)
args[0] : 2nd_commands_argument
i = 1, j = 0
i = 2, numcommands = 2
Segmentation fault (core dumped)

Edited 6 Years Ago by kylcrow: n/a

char *args[11];

Have you assigned anything to this variable before trying to print it out?

printf("args[%d  : %s\n", j, data.TheCommands[i].args[j])

You could consider removing the * in the args.

Removing the * in args didn't change the outcome, and I am assigning at most 2 values to args.
In the case above I only assigned 1 argument: data.TheCommands[0].args[0] = "-l" and data.TheCommands[1].args[0] = "-l"

args[1-11] would be undefined in the test above I believe.

So, you are saying that I am getting a seg fault becuase I didn't initialize my array of ptrs correctly? How should I initialize all 11 ptrs?

char* args[11] = { 0 };

You have 11 character pointers there with no memory allocated.

args[0] = (char*) malloc(sizeof(char));

*args[0] = 'l';

The above will allocate the memory that you want for a single character and during printing you should use %c instead of %s.

But from your way of initialising, I am guessing that you want 11 strings there instead of 11 characters.

You could go in for a two dimensional character array.

[EDIT]

Just multiplying the 'size of' above with the size of your required string should allocate the memory.

Edited 6 Years Ago by thomas_naveen: typo

I am using another function that takes in a struct. One of the variables in the struct is another struct. In the inner struct there is a variable char* args[11]. The thing is, The function is writing to args fine, its just segfaulting on Solaris. The program never crashed on Ubuntu. I figured Ubuntu was handling something automatically that the Solaris machine wasn't. (Sorry I am just trying to understand all this) The reason it is dumping is becuase I have to explicitly allocate memory of char* args[11] using malloc?

Writing to a null pointer results in unexpected behaviour. My guess is that you were just lucky that it did not crash before. (I have no experience with Ubuntu)

The expected behaviour from the user side is to allocate memory to pointers before use and free that memory after use.

First of all, Thanks for all the help. It has been tons.

This is still seg faulting:

int main(int argc, char *argv[])
{
	/* Really ugly declarations and initilizations */
	char* exitcommand = "exit";
    char buf[100];
    char *command = NULL;
	command = (char*)malloc(sizeof(char) * 60);
	char *args[11];
	int k = 0;
	for (k = 0; k < 11; k++) {
		args[k] = (char*)malloc(sizeof(char) * 128);
	}
    int numargs = 0;
    int numcommands = 0; 
    char *infile = NULL;
    char *outfile = NULL;
    int  background = 0;
    struct Command com = {command, {args[11]}, numargs};
    struct CommandData data = {{com}, numcommands, infile, outfile, background};

	/* Loop forever! (almost) */
    while (1) { ...........

You could try running the code on gdb and see where it is segfaulting?

Could you post your entire code together so that it can be better viewed? Looking at it in bits and pieces is a difficult thing.

Comments
You deserve a rep bump

Thanks for all your help, the problem was way down when I was trying to printf some data that wasn't defined. I didn't see it earlier because it looked as if the loops were causing it. To be honest I forgot about GDB, and as soon as I used it I found the problem. Thanks goes out to thomas_naveen.

This question has already been answered. Start a new discussion instead.