Find the answer to your Linux question:
Results 1 to 6 of 6
I have problems with unstanding this code. This code is for Minix but i think this should also work on Linux. What is the function of these: int strstripl(char *inbuf, ...
Enjoy an ad free experience by logging in. Not a member yet? Register.
  1. #1
    Just Joined!
    Join Date
    May 2003
    Posts
    6

    Problem with understanding this code


    I have problems with unstanding this code. This code is for Minix but i think this should also work on Linux. What is the function of these:

    int strstripl(char *inbuf, int n)
    int strstripr(char *inbuf, int n)
    int read_line(char *line) /* read a command*/
    void parse(char *buf, char **args)
    int strsepp(char *input, char *token, int sep)

    ///////////////////////////////////////////////////////////////////////////////////
    Code:
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    /* Strips n chars off inbuf to the left side*/
    int strstripl&#40;char *inbuf, int n&#41; &#123;
    
    char *origbuf = inbuf;
    
    if &#40;n > strlen&#40;inbuf&#41;&#41; 
            return&#40;-1&#41;;
    origbuf = &#40;origbuf + n&#41;;
    while&#40; &#40;*inbuf++ = *origbuf++&#41; != '\0'&#41;;
    return&#40;0&#41;;                                                                                            
    &#125;
    
    /* Strips n chars off inbuf to the left side*/                                                        
    int strstripr&#40;char *inbuf, int n&#41; &#123;                                                                   
    
    if &#40;n > strlen&#40;inbuf&#41;&#41; 
            return&#40;-1&#41;;
    n = &#40;strlen&#40;inbuf&#41; -n&#41;;
    inbuf = inbuf +n;
    *inbuf = '\0';
    return&#40;0&#41;;
    &#125;
    
    int strsepp&#40;char *input, char *token, int sep&#41; &#123;
    
      char *cmd;
      int tokenpos;
     
     
      if &#40;&#40;cmd = strchr&#40;input, sep&#41;&#41; == NULL&#41; &#123;
        return&#40;-1&#41;;
      &#125;
     
      tokenpos = &#40;strlen&#40;input&#41;-strlen&#40;cmd&#41;&#41;;
      strncpy&#40;token, input, tokenpos&#41;;
      strstripl&#40;input, tokenpos+1&#41;;
    
      return&#40;0&#41;;
    &#125;
    
    
    int read_line&#40;char *line&#41; &#123;
      int c;
      while&#40; &#40;c = getchar&#40;&#41;&#41; != 10&#41;
        *line++ = c;
      *line++ = '\0';
    &#125;
    
    
    
    void parse&#40;char *buf, char **args&#41;
    &#123;
      while &#40;*buf != '\0'&#41; &#123;
        
        /* Argument is to replace the whitespace og the terminater with a NULL */
        while &#40;&#40;*buf == ' '&#41; || &#40;*buf == '\t'&#41;&#41;
          *buf++ = '\0';
        
        /* Save the argument. */
        *args++ = buf;
    
        /* Skip over the argument. */
        while &#40;&#40;*buf != '\0'&#41; && &#40;*buf != ' '&#41; && &#40;*buf != '\t'&#41;&#41;
          buf++;
      &#125;
      
      /* Zero terminate the last argument */
      *args = NULL;
    &#125;
    
    
    int main&#40;int argcc, char *argvv&#91;&#93;&#41; &#123;
    
      char inputline&#91;255&#93;;
      char *tokenstr;
      char *input;
      char *argv&#91;80&#93;;
      int pid, status;
      int BGRND = 0;
    
      for&#40;;;&#41; &#123;
        
        /* Write the prompt */
        printf&#40;"cesh>"&#41;;
        
        /* Read the input */
        read_line&#40;inputline&#41;;
        
        /* If the line is containing a ; at the end it is an syntak error */
        if &#40;inputline&#91;strlen&#40;inputline&#41;-1&#93; == ';'&#41; &#123;
          printf&#40;"Syntax error.\n"&#41;;
        &#125;
        else
          &#123;
    	/* ambigous place a ; at the end of the string to make strsep work right */
    	input = strcat&#40;inputline, ";"&#41;;
    	for&#40;;;&#41; &#123;
    	  /* allocate mem for the string token */
    	  tokenstr = calloc&#40;255,8&#41;;
    	  
    	  /* is we are at the end of the string do a break */
    	  if &#40; strsepp&#40;input, tokenstr, 59&#41; == -1&#41;
    	    break;
    	  
    	  /* if the user types exit quit the program */
    	  if &#40;strncmp&#40;"exit", tokenstr, 4&#41; == 0&#41;
    	    return&#40;0&#41;;
    
    	  if &#40;tokenstr&#91;strlen&#40;tokenstr&#41;-1&#93; == '&'&#41; &#123; 
    	    BGRND = 1;
    	    tokenstr&#91;strlen&#40;tokenstr&#41;-1&#93; = '\0';
    	  &#125;
     	  
    	  /* now parse the argument list into single string pointers to the execvp call */
    	  parse&#40;tokenstr, argv&#41;;
    	  
    	  /* fork the process and exit if somthing goes wrong */
    	  if &#40;&#40;pid = fork&#40;&#41;&#41; < 0&#41; 
    	    return&#40;0&#41;;
    	  
    	  /* here is the child, execute and exit the process */
    	  if &#40;pid == 0&#41; &#123;
    
    	    if &#40;&#40;execvp&#40;argv&#91;0&#93;, argv&#41;&#41; == -1&#41;
    	      printf&#40;"%s&#58; Command not found.\n", tokenstr&#41;;
    	    return&#40;0&#41;;
    	  &#125;
    	  
    	  /* here is the father wait for the child to exit */
    	  if &#40;BGRND == 0&#41;
    	    while &#40;waitpid&#40;-1, &status, 0&#41; != pid&#41;;
    	  
    	  /* free the tokenstrign */
    	  free&#40;tokenstr&#41;;
    	  BGRND = 0;
    	&#125; /* end tokenizer loop here */
          &#125; /* end else */
      &#125; /*end forever lop */
    
      return&#40;0&#41;;
    &#125;

  2. #2
    Linux Guru
    Join Date
    Oct 2001
    Location
    Täby, Sweden
    Posts
    7,578
    Could you please repost that within code tags? It's just too frustrating to read it without indentation.

  3. #3
    Just Joined!
    Join Date
    May 2003
    Posts
    6
    Yes i can

    Quote Originally Posted by Dolda2000
    Could you please repost that within code tags? It's just too frustrating to read it without indentation.

  4. #4
    Linux Guru
    Join Date
    Oct 2001
    Location
    Täby, Sweden
    Posts
    7,578
    Thank you, that was much better.
    Now, as I can see, this is a shell, and, if you don't mind me saying so, a very simple, badly written and buggy such. It seems to be written by someone whose native language is norse or danish.
    It will indeed work under Linux as well as Minix, but I can't find a reason why one would want it to run under either, to be honest with you.

    Here are the function explanations:
    strstripl - removes a number of characters off the left end of a string. Unnecessary, since there already is memmove.
    strstripr - removes a number of characters off the right end of a string. Truly unnecessary. Both of these could just as well be macros, if even that would be necessary.
    strsepp - Although I haven't been able to figure out what it stands for, it finds a substring in a string that is terminated by the seperator character that is given to the function. Also unnecessary, since there is strtok.
    read_line - Reads a line from the standard input into the given buffer. Even this is unnecessary, since it works exactly like gets, that already exists, and isn't being used for several good reasons. gets is actually better, since this function doesn't even check for EOF.
    parse - Finds words that are seperated by whitespace and enters them into the string pointer array given as args.

  5. #5
    Just Joined!
    Join Date
    May 2003
    Posts
    6
    thanks a lot for the explanation of the functions. you are right. This shell is written by one of my danish friend. I am trying to make the shell better. iam new to using Linux and Minix so therefor its little difficult to me.

    i want this shell to:

    1. A parser to read the command lines.
    i thinks this is working.
    2. Get the simple commands to work.
    3. Get ”&” to work.
    4. Get I/O redirection to work.
    This code also works but not if i put it with the shell code above.
    Code:
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    
    int main&#40;int argc, char *argv&#91;&#93;&#41; &#123;
    int fd;
    int status;
    char test&#91;80&#93; = "ls";
    argv&#91;0&#93; = test;
    	if &#40;&#40;fd = open&#40;"/home/test/test.txt", O_WRONLY&#41;&#41; == -1&#41;
    		printf&#40;"ERROR\n"&#41;;
    
    	close&#40;1&#41;;
    	dup2&#40;fd, 1&#41;;
    	close&#40;fd&#41;;
    	if &#40;execvp&#40;argv&#91;0&#93;, argv&#41; == -1&#41;
    		printf&#40;"EXEC ERROR\n"&#41;;
    	waitpid&#40;-1, &status, 0&#41;;
    
    return&#40;0&#41;;
    &#125;

    5. Get the ”ls” command to work.

    6. Get pipes to work.
    I have written the code for the pipe in another file. Its not working if i put it into the shell file.
    Here is the code:

    Code:
    #include <sys/types.h>
    #include <sys/wait.h>
    #include <stdlib.h>
    #include <stdio.h>
    #include <string.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    
    int main&#40;int argc, char *argv&#91;&#93;&#41; &#123;
    int fd1&#91;2&#93;;
    
    char cmd1&#91;80&#93; = "ls";
    char cmd2&#91;80&#93;= "sort";
    char *arg_a&#91;20&#93;;
    char *arg_b&#91;20&#93;;
    
    arg_a&#91;0&#93; = cmd1;
    arg_b&#91;0&#93; = cmd2;
    
    
    pipe&#40;fd1&#41;;
    
     if &#40;fork&#40;&#41; > 0&#41; &#123;
    	close&#40;1&#41;;
    	dup2&#40;fd1&#91;1&#93;, 1&#41;;
    	close&#40;fd1&#91;1&#93;&#41;;
    	close&#40;fd1&#91;0&#93;&#41;;
    	if &#40;execvp&#40;arg_a&#91;0&#93;, arg_a&#41; == -1&#41;
    		return&#40;-1&#41;;
    	
    &#125; else &#123;
    	close&#40;0&#41;;
    	dup2&#40;fd1&#91;0&#93;, 0&#41;;
    	close&#40;fd1&#91;0&#93;&#41;;
    	close&#40;fd1&#91;1&#93;&#41;;
    	if &#40;execvp&#40;arg_b&#91;0&#93;, arg_b&#41; == -1&#41;
    		return&#40;-1&#41;;
    		
    &#125;
    
    	
    return&#40;0&#41;;
    &#125;

    how can i improve these function?

    <Here are the function explanations:
    <strstripl - removes a number of characters off the left end of a string. <Unnecessary, since there already is memmove.
    <strstripr - removes a number of characters off the right end of a string. <Truly unnecessary. Both of these could just as well be macros, if even <that would be necessary.
    <strsepp - Although I haven't been able to figure out what it stands for, it <finds a substring in a string that is terminated by the seperator character <that is given to the function. Also unnecessary, since there is strtok.
    <read_line - Reads a line from the standard input into the given buffer. <Even this is unnecessary, since it works exactly like gets, that already <exists, and isn't being used for several good reasons. gets is actually <better, since this function doesn't even check for EOF.
    <parse - Finds words that are seperated by whitespace and enters them <into the string pointer array given as args.[/quote]

  6. #6
    Linux Guru
    Join Date
    Oct 2001
    Location
    Täby, Sweden
    Posts
    7,578
    Well, I guess I _could_ explain all that to you, but it would be pretty much, so I guess I'll try to give you some thoughts that popped up in my head on this, and then you can elaborate on it:

    1. One thing that you must realize first of all is that you shouldn't get lines of input. A newline should be considered a token just like any other.

    2. Command delimiters are &, ;, newline, && and ||. They should be treated equal until their special functions are actually needed. Ie., don't treat & seperate like your friend did. Just save in some variable somewhere what actions to perform after the command has been forked out.

    3. You can consider a pipe character to be a command delimiter. That's probably the easiest way to implement pipes. In a pipeline, only the last command is waited for.

    4. Look for I/O redirection characters after you have done word seperation.

    The first one is the most important one. Actually, it is really important.
    Just reply again if you need more information.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •