CS 3733 Operating Systems, Fall 2002 Assignment 1 Comments
The assignment was graded on a basis of 30 points.
- About half the class got this to work sufficiently well to
pass all of my tests.
- Only 2 students did not have a serious problem that I could find in under
5 minutes. This, of course, does not mean that they did not have a
problem that I did not find, but is good enough to receive full credit.
- If you assumed a maximum length to inlin, your maximum score was 25.
- If not all of my tests were passed, your maximum score was 25, typically
it was 20-25.
- If you did not make sufficient progress on Part 4, you maximum score was 20.
- If you did not make sufficient progress on Part 3, you maximum score was 15.
- If you did not make sufficient progress on Part 2, you maximum score was 5.
- If it says "see me" on the front of your assignment, it does not
(necessarily) mean that you are in trouble, just that means that either you
or I did not understand what you did.
- Circled entries in your index indicate you should look for comments.
- Remember that inlin is not a string, and string functions should only
be used with strings.
- parse_initial should not have to do any dynamic memory allocation.
- Do not exit from command_logger on error, use
return.
- EOF is not a character, and is never stored in an array of characters.
- You should limit the number of mallocs and reallocs.
command_logger should not have to do more than one malloc and no
reallocs. Idea: First find the length of inlin. This gives
an upper bound on the size of the buffer needed, slightly more than
twice the length of inlin. Remember than inlin is
not a string and its length is determined by the position of the
newline.
- The number 33 should not appear anywhere in your code. Use:
#define INVALID_MSG "Line does not contain 3 tokens.\n"
int invalid_msg_length;
invalid_msg_length = strlen(INVALID_MSG);
Avoid using other such "magic numbers"
- You should not have any lint warnings of the form: xxx implicitly declared to ...
- If you do more than one malloc, be sure to free the first one if the second
one produces and error.
- command_logger may not assume a maximum size for the input line.
- Instead of write(fd,"abc",3) use write(fd,"abc",strlen("abc"));
- command_logger in part 4 must use only one write.
Do not check for a return value of -1, check that the return value
is equal to the number of bytes you wanted to write.
- Each variable should be declared on a separate line.
- Test for errors on write and malloc
- For command_logger it is an error if not all bytes are written
with a single write.
- Use realloc instead of reinventing it yourself.
- You don't need any reallocs at all. Find the length of inlin and
do one malloc that is large enough.
- You may not access memory past the newline in inlin.
- It is invalid to do something like:
sprintf(buf,"%sxxxx",buf);
strcat(buf,buf);
Keep in mind that if copying takes place between objects that overlap,
the behavior is undedfned.
- Your code must be maintainable by others.
Avoid using a large number of variables whose meaing is not obvious.
- Avoid using strncat(x,y,strlen(y). Use strcat.
- Be careful not to do
ptr = realloc(ptr,xxx)
If this returns an error, you can no longer access or free the old memory.
Outline of parse_initial:
ptr = inlin;
ptr = skip_white_space(ptr);
if (ptr == NULL) return -1;
*commandp = ptr;
ptr = skip_to_white_space(ptr);
if (ptr == NULL) return -1;
*ptr = 0;
ptr++;
ptr = skip_white_space(ptr);
if (ptr == NULL) return -1;
*pathp = ptr;
ptr = skip_to_white_space(ptr);
if (ptr == NULL) return -1;
*ptr = 0;
ptr++;
ptr = skip_white_space(ptr);
if (ptr == NULL) return -1;
*protocolp = ptr;
ptr = skip_token(ptr);
if (white_space(*ptr)) {
make sure no more tokens, don't change ptr.
}
*ptr = 0;
if (strncmp(*pathp,"http://",7) == 0) {
handle server
}
return 0;
Outline of command_logger:
#define COMMAND "Command: "
#define SERVER "Server: "
#define PORT "Port: "
#define PATH "Path: "
#define PROTOCOL "Protocol: "
#define BADGET "Line is not a valid GET command."
#define ALL_OVERHEAD 100
len = get_line_length(inlin);
buf = (char *)malloc(2*len+ALL_OVERHEAD);
if (buf == NULL) return -1;
memcpy(buf,inlin,len);
if (parse__initial(inlin,&command,&server,&path,&protocol) == -1)
len = copy_line(buf,len,BADGET,NULL);
else {
len = copy_line(buf,len,COMMAND,command);
len = copy_line(buf,len,SERVER,server);
len = copy_line(buf,len,PORT,port);
len = copy_line(buf,len,PATH,path);
len = copy_line(buf,len,PROTOCOL,protocol);
}
ret = write(fd,buf,len);
free(buf);
if (ret == len) return 0;
return -1;
}
copy_line(char *buf, int buflen, char *name, char *value)
copies the string name into the array at buf+buflen and then appends
the string value if it is not NULL. Terminate with a newline.
Return the new length.