|
![]() |
Overclock.net - Overclocking.net > Software, Programming and Coding > Coding and Programming | |
CS 352 - Unix Software Development
|
||
![]() |
|
|
LinkBack | Thread Tools |
|
|
#11 (permalink) | ||||||||||||
|
New to Overclock.net
![]() |
^
__________________I was way off, I'm was going off what I had heard. After a brief talk with someone that has already taken the course it seems like it wont be an entire kernal from scratch (thank God). I guess it's going to be a 6 part mini-shell. I guess I'll just have to start reading up and see what happens once some of the stuff is posted. After talking about it, it is sounding a lot easier that I thought but it'll definitely keep me busy. *sigh of relief*
|
||||||||||||
|
|
|
|
|
#12 (permalink) | ||||||||||||||
|
Security Sleuth
![]() |
Sounds good dude, keep us posted. If you ever need help, we dont do your homework, but were here.
Ill be interested to see what classes I have interest in when I get where you are. Getting an early start has really helped me so far.
__________________
Quote:
Proud Member of the Linux Gaming CommunityI am your friend.
|
||||||||||||||
|
|
|
|
|
#13 (permalink) | ||||||||||||
|
New to Overclock.net
![]() |
Well we got assigned out first program last week (first day of class nonetheless), and I just turned it in. YAY. lol. It turned out being easier than I thought. I'm definitely still getting used to the unix thing. I definitely need to work on my debugging skills within the terminal. I spent a solid couple hours today looking everything over wondering why it wasnt working. lol. I had a 1 instead of a 0. DOH.
__________________Is it alright if I post my code up here to get your guy's feedback? lol. All in all I thought I did pretty well for the week. Learned how to use netBSD, the terminal, and wrote a very small portion of the shell. Part 1 down...only 5/6 more. ha. Code:
/* CS 352 -- Mini Shell!
*
* Cole Markusen
* Programming Assignment 1
* Created: September 24th, 2009
* Modified: September 29th, 2009
*
*/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
/* Constants */
#define LINELEN 1024
/* Prototypes */
void processline (char *line);
char** arg_parse (char *line);
/* Shell main */
int
main (void)
{
char buffer [LINELEN];
int len;
while (1) {
/* prompt and get line */
fprintf (stderr, "%% ");
if (fgets (buffer, LINELEN, stdin) != buffer)
break;
/* Get rid of \n at end of buffer. */
len = strlen(buffer);
if (buffer[len-1] == '\n')
buffer[len-1] = 0;
/* Run it ... */
processline (buffer);
}
if (!feof(stdin))
perror ("read");
return 0;/* Also known as exit (0); */
}
void processline (char *line)
{
pid_t cpid;
int status;
char **args;
args = arg_parse(line);
/* Start a new process to do the job. */
cpid = fork();
if (cpid < 0) {
perror ("fork");
return;
}
/* Check for who we are! */
if (cpid == 0) {
/* We are the child! */
execvp(args[0], args); //replace process
perror ("exec");
exit (127);
}
/* Have the parent wait for child to complete */
if (wait (&status) < 0)
perror ("wait");
free(args); //freeing up memory
}
char** arg_parse (char *line)
{
char** argv; //array for arguments
int count = 0; //counter for number of arguments
int i; //incrementation for 'for loops'
int index = 0; //incrementation for array
int length = strlen(line); //length of line
for(i=0; i < length; i++)
{
if(line[i] != ' ' && (line[i+1] == ' ' || line[i+1] == '\0' || line[i+1] == '\n'))
{
count++; //counting number of arguments
}
}
argv = (char**)calloc(sizeof(char**), count + 1); //allocating size
for(i=0; i < length; i++)
{
if(i == 0 && line[i] != ' ')
{
argv[index] = &line[i]; //adding character to array
index++;
}
if(line[i] == ' ')
{
line[i] = '\0'; //replacing whitespaces with 0.
if(line[i+1] != ' ' && line[i+1] != '\0')
{
argv[index] = &line[i+1]; //adding character to array
index++;
}
}
}
return argv; // returning array
}
Last edited by deafboy : 10-11-09 at 06:13 AM |
||||||||||||
|
|
|
|
|
#14 (permalink) | ||||||||||||
|
New to Overclock.net
![]() |
So I turned in my second program Friday morning... unfortunately I turned it in incomplete (has bugs).
__________________![]() I was hoping I could get some fresh set of eyes on this to see if anyone can help me fix things up. I hate having incomplete/buggy code I know some of the logic is a little sketch, didn't get much sleep last week. The Assignment: HERE msh (minishell main) Code:
/* CS 352 -- Mini Shell!
*
* Author: Cole Markusen
* Assignment Number: 2
* Class: CSCI 352 -- Unix Developement
* Created: September 24th, 2009
* Modified: October 9th, 2009
*
* The heart of this minishell was taken from minishell.c
* created by Phil Nelson. Function calls for arguments
* implemented as well as some error handling
*/
#include "proto.h"
/* Constants */
#define LINELEN 1024
/* Prototypes */
void processline (char *line);
/* Shell main */
int
main (void)
{
char buffer [LINELEN];
int len;
while (1) {
/* prompt and get line */
fprintf (stderr, "%% ");
if (fgets (buffer, LINELEN, stdin) != buffer)
break;
/* Get rid of \n at end of buffer. */
len = strlen(buffer);
if (buffer[len-1] == '\n')
buffer[len-1] = 0;
/* Run it ... */
processline (buffer);
}
if (!feof(stdin))
perror ("read");
return 0;/* Also known as exit (0); */
}
void processline (char *line)
{
pid_t cpid; //Process Identification
int status; //Status of process
int number_of_parameters; //Number of arguments in the line
int command_builtin; //Whether the command is a built in or not,
// 0 if it is, -1 if it is not.
char **args; //Argument array
number_of_parameters = arg_parse(line, &args);
command_builtin = check_builtin(number_of_parameters, args);
if(command_builtin == -1)
{
if (number_of_parameters == 0)
{
return; //blank line inputed
}
if (number_of_parameters > 0)
{
/* Start a new process to do the job. */
cpid = fork();
if (cpid < 0) {
perror ("fork");
return;
}
/* Check for who we are! */
if (cpid == 0) {
/* We are the child! */
execvp(args[0], args); //replace process
perror ("exec");
exit (127);
}
/* Have the parent wait for child to complete */
if (wait (&status) < 0)
perror ("wait");
free(args); //freeing up memory
}
}
if (number_of_parameters == -1)
{
//printin error for unbalanced quotation marks
fprintf(stderr, "error: unmatched quotation marks. \n");
main();
}
}
arg_parse (argument parser) -- disregard the print_array if you want. I used it to help me debug Code:
/* CS 352 -- Arg_Parse
*
* Author: Cole Markusen
* Assignment Number: 2
* Class: CSCI 352 -- Unix Developement
* Created: October 5th, 2009
* Modified: October 9th, 2009
*
*/
#include "proto.h"
void print_array(int count, char** argv, char* line, int pos)
{
int i = 0;
printf ("\"%s\"\n ", line);
for (i = 0; i < pos; i++) {
printf (" ");
}
printf ("^\n");
printf ("===============================\n");
for (i = 0; i < count +1; i++)
{
printf("[%i] => \"%s\"\n", i, argv[i]);
}
printf ("===============================\n");
return;
}
//function to shift the entire line to the left
//currently used to get rid of quotes
char* shift(char *line, int length, int i)
{
int j=0;
for(j = i; j < length; j++)
{
line[j] = line[j+1];
}
return line;
}
int arg_parse (char *line, char ***argvp)
{
char original[1024];
char** argv; //array for arguments
int count = 0; //counter for number of arguments
int i; //incrementation for 'for loops'
int index = 0; //incrementation for array
int length = strlen(line); //length of line
int number_of_quotes = 0; //tally for number of quotes
bool quotations = false; //bool to flag whether you're
//inside a quote or not
strcpy (original, line);
//count the number of quotes
for(i=0; i < length; i++)
{
if(line[i] == '"')
{
number_of_quotes++;
}
}
//uneven number of quotes -- error
if((number_of_quotes % 2) != 0)
{
return -1;
}
//count the number of arguments
for(i=0; i<length; i++)
{
if(line[i] == '"')
{
if(quotations == false)
{
quotations = true; //inside quote
}
else
{
quotations = false; //leaving quote
}
}
if(line[i] == ' ' || line[i+1] == '\0')
{
if((line[i+1] != ' ' && line[i+1] != '\t') && !quotations)
{
count++; //increment number of arguments
}
}
}
argv = (char**)calloc(sizeof(char**), count + 1); //allocating size
for(i=0; i<length; i++)
{
print_array(count, argv, original, i);
if(i == 0 && line[i] != ' ' && line[i] != '"' && line[i] != '\t')
{
argv[index] = &line[i]; //adding character to array
index++;
}
if(line[i] == '"')
{
if(quotations == false)
{
quotations = true; //inside quote
}
else if (quotations == true && line[i+1] == ' ')
{
quotations = false; //leaving quote
}
line = shift(line, length, i); //get rid of quotes
i--;
}
if((line[i] == ' ' || line[i] == '\t') && !quotations)
{
if(line[i+1] != ' ' && line[i+1] != '\t' && line[i+1] != '\0')
{
argv[index] = &line[i+1]; //adding character to array
index++;
}
line[i] = '\0'; //replacing whitespaces with 0.
}
}
*argvp = argv; //setting array values
return count; // returning number of parameters
}
builtin (Built In Commands) Code:
/* CS 352 -- Builtin Functions
*
* Author: Cole Markusen
* Assignment Number: 2
* Class: CSCI 352 -- Unix Developement
* Created: October 5th, 2009
* Modified: October 9th, 2009
*
*/
#include "proto.h"
//declare typedef function and struct
typedef void(*builtin_ptr)(int, char**);
typedef struct {char *name; builtin_ptr func;} bi_entry;
//declare built in commands
void do_exit(int count, char** args);
void do_aecho(int count, char** args);
//Putting commands into an array and setting the number of commands.
bi_entry commands[] = {{"exit", do_exit}, {"aecho", do_aecho}};
int number_of_commands = 2;
int check_builtin(int count, char** args)
{
int i; //incrementor
int is_command = 0; //checking to see if command is a built in or not
printf("%i", count);
if(count > 0)
{
for(i=0; i < (number_of_commands); i++)
{
is_command = strcmp(commands[i].name, args[0]); //compare strings
if(is_command == 0)
{
commands[i].func(count, args); //call built in function
return 0; //it is a command
}
}
}
return -1; //it is not a command, empty.
}
void do_exit(int count, char** args)
{
if(count > 2)
{
exit(atoi(args[1])); //using user defined exit command
}
else
{
exit(0); //default exit command is 0
}
}
void do_aecho(int count, char** args)
{
int i; //incrementor
int do_newline; //whether to add a newline or not
// 0 = no new line, -1 = new line
if(count > 2)
{
//check to see if the second argument is a "-n"
do_newline = strcmp(args[1], "-n");
}
if(do_newline == 0) // args[1] is equal to "-n", don't add new ling
{
for(i=2; i < (count+1); i++) //i=2 so the commands do not get printed
{
if(args[i] != NULL) //makes sure the argument isnt null
{
printf("%s", args[i]);
}
if(i < (count))
printf("%s", " ");
}
}
if(do_newline != 0) // args[1] isn't equal to "-n" add new line
{
for(i=1; i < (count+1); i++) //i=1 so the commands do not get printed
{
if(args[i] != NULL) //makes sure the argument isnt null
{
printf("%s", args[i]);
}
if(i < (count))
printf("%s", " ");
}
printf("%s", "\n");
}
return; // nothing after aecho inputed
}
proto (h file) Code:
/* CS 352 -- Proto Header File * * Author: Cole Markusen * Assignment Number: 2 * Class: CSCI 352 -- Unix Developement * Created: October 5th, 2009 * Modified: October 9th, 2009 * */ #pragma once #include <stdio.h> #include <stdbool.h> #include <string.h> #include <unistd.h> #include <errno.h> #include <stdlib.h> #include <sys/types.h> #include <sys/wait.h> void print_array(int count, char** argv, char* line, int pos); // Function used to parse a line and return the number // of arguments. int arg_parse (char *line, char ***argvp); // Function used to shift the line to the left to remove // any quote within the line char* shift(char *line, int length, int i); // Function used to determine whether the input command // is a built in or not. int check_builtin(int count, char** args);
|
||||||||||||
|
|
|
|
|
#15 (permalink) | |||||||||||||||||
|
4.0 GHz
![]() |
One problem I noticed:
You have: Quote:
Quote:
But there's some recursion going on that can make things messy. Consider: i.) User does something to go into processline(), and then gets main() called from within processline() ii.) User repeats above iii.) User enters in the "break" condition in the main() loop. The program will not exit here, but will trickle back up through the function calls - i.e., the second nested main() will return back into processline(), which then returns into the first nested main(). The user will need to trigger two more break conditions for the program to exit. This dovetails nicely into my next concern: Quote:
For example, in the above code, using return leads to the messy recursive scheme I described above, while using exit would avoid that altogether by stopping the program the first time it's reached. This, however, has it's own problems, because any program cleanup will not be executed; things like allocated memory not being freed up. Again, I may just not understand the "big picture" of your code, and this setup may have a purpose I'm not divining. Just giving my first impressions.
__________________
3DMark06: 19091 - 3DMark Vantage: P15264 - SuperPi: 10.968s Programming Quote of the Day: Bjarne Stroustrup: Quote:
|
|||||||||||||||||
|
|
|
|
|
#16 (permalink) | ||||||||||||
|
New to Overclock.net
![]() |
Thank you...lol. Oddly enough you pointed out areas that I'm not having a problem with. My issue is coming from my argument parser.
__________________I decided to try and rewrite my parser but I am having a hell of a time clearing my head and coming at it with a new perspective. It's really getting to me. Coding nightmares everynight... blah. The call to main I admit isn't correct, the other parts you mentioned though are. Thanks again +rep. Anyone have some insight on redoing my parser in a new light? lol. I've tried rewriting it half a dozen times but in the end it comes out almost exactly like I have it now. Which doesn't work quite right ![]() help.
|
||||||||||||
|
|
|
|
|
#17 (permalink) | |||||||||||||
|
New to Overclock.net
|
we just had an assignment to write a "shell" in my OS class.
__________________All it has to do it is read the line and execute the process. Used readline, strtok, and (obviously) fork/exec. you have built something considerably more complex though.
|
|||||||||||||
|
|
|
|
|
#18 (permalink) | ||||||||||||||
|
PC Gamer
![]() |
Sounds pretty complex to me - C is scary!!
__________________
Quote:
|
||||||||||||||
|
|
|
|
|
#19 (permalink) | |||||||||||||
|
New to Overclock.net
|
asm is scarier.
__________________and scheme will mkae you develop a hatred for brackets. and prolog will just make your head spin.
|
|||||||||||||
|
|
|
|
|
#20 (permalink) | ||||||||||||
|
New to Overclock.net
![]() |
lmao... i've never done asm but scheme is fun. I like it. It's nice once you get the hang of it. Used it last quater in my Automata Theory class.
__________________Prolog is just retarded. lmao. My third assignment was due friday. Didn't finish and wont be able to turn it in until wednesday for ~75% credit. Each one of these assignments is getting trickier. It's funny though because coming up with the code and writing it doesnt take very long but debugging it and testing it takes forever. It's fun but at the same time it's a pain rushing to get everything done in a timely manor.
|
||||||||||||
|
|
|
![]() |
| Currently Active Users Viewing This Thread: 1 (0 members and 1 guests) | |
| Thread Tools | |
|
|