Results 1 to 9 of 9

Thread: System Calls in C

  1. #1
    Old school, like an old fool. Flying Mullet's Avatar
    Join Date
    Apr 2003
    Location
    Napping in a peach tree.
    Posts
    19,185
    Articles
    6
    Blog Entries
    7
    Contributions
    • Former Administrator
    • Former Cid's Knight
    • Former Senior Site Staff

    Default System Calls in C

    Mulley's brain is tired from looking at C code all day and he's ready to call for help.

    I have two programs using system calls in C that I need to write and neither of them are working correctly. The first one takes two parameters, an existing folder and the name of a new folder. The program should create the new folder and copy the contents of the old folder (i.e. files) into the new folder. My program will create the new folder and create the files in the new folder, but it won't write the contents to the files. Here's what I have so far:
    Code:
    #include <fcntl.h>
    #include <stdio.h>
    #include <sys/types.h>
    #include <dirent.h>
    
    int main (int argc, char *argv[])
    {
      int count;
      char buffer[1024];
      int folderNew, fileNew, fileOld;
      DIR *folderOld;
      struct dirent * file;
    
      // ensure the proper number of command line arguments are passed in
      if (argc !=3) {
        fprintf (stderr,"need 3 args\n");
        return 1;
      }
    
      // create the new folder
      folderNew = mkdir(argv[2],00644);
      if (folderNew == -1) {
        printf ("can not create: %s\n", argv[2]);
        /* fprintf (stderr,"errstring is: %s\n",strerror(errno));; */
        return 0;
      }
    
      // open the old folder
      folderOld = opendir (argv[1]);
      if (folderOld == NULL) {
        fprintf (stderr,"can not open: %s\n", argv[1]);
        /* fprintf (stderr,"errstring is: %s\n",strerror(errno)); */
        return 0;
      }
    
    
      // copy the contents
    /*
      while ( (count = read(folderOld, buffer, sizeof(buffer))) > 0)
      {
        printf ("in loop\n");
        write (folderNew, buffer, count);
      }
    */
    
    	while (file = readdir(folderOld))
    	{
    //	 printf ("inode: %ld   file name: %s   file type: %d   offset: %ld   length: %d\n",file->d_ino, file->d_name, file->d_type, file->d_off, file->d_reclen);
    
    
    		// only copy the proper file types
    		if(file->d_type != 4)
    		{
    			// navigate to the old folder
    			chdir(argv[1]);
    
    			// open the old file
    			fileOld = open ("dummy.txt",O_RDONLY);
    			if (fileOld == -1)
    			{
    				fprintf (stderr,"can not open: %s\n", file->d_name);
    				/* fprintf (stderr,"errstring is: %s\n",strerror(errno)); */
    				return 0;
    			}
    		
    			// navigate to the new folder
    			chdir("..");
    			chdir(argv[2]);
    
    			// create the new file
    			fileNew = creat (file->d_name,00644);
    			if (fileNew == -1)
    			{
    				printf ("can not create: %s\n", file->d_name);
    				/* fprintf (stderr,"errstring is: %s\n",strerror(errno));; */
    				return 0;
    			}
    
    
    			while ( (count = read(fileOld, buffer, sizeof(buffer))) > 0)
    			{
    				write (fileNew, buffer, count);
    			}
    
    			// navigate back to the parent folder
    			chdir("..");
    
    
    		}
    
    
    	}
    
      return 0;
    }
    My second program is supposed to create two child processes. Then the parent sends a message to each child, each child sends a message to the parent, then everything shuts down gracefully. When I'm in the child process/file, it says it there is no such file or directory when I tell it to open the pipe from the parent to receive the message. Here's what I have:

    <i>parent.c</i>
    Code:
    /* a simple first example, showing output */
    
    #include <stdio.h>
    #include <sys/stat.h>
    #include <sys/types.h>
    #include <unistd.h>
    #include <fcntl.h>
    
    
    int main(int argc, char **argv)
    {
       pid_t child1pid;
       pid_t child2pid;
    
       char message1[]="Hi Child1, this is your parent!!!";
       char message2[]="Hi Child2, this is your parent!!!";
       int fd1, fd2;
       char buff[128];
       int num;
    
       /* create new named pipes in current directory with
          permissions 777 (rwx for everyone) */
       mknod("toChild1", 010777,0);
       mknod("toChild2", 010777,0);
    
       /* parent process here */
       printf("Howdy from parent process %d\n", getpid());
    
       /* split child 1 here */
       if ((child1pid=fork()) == 0) {  /* child */
         execlp("./child", "./child", "1", "toChild1", NULL);
         perror("oops, child had an error!");
    
    	   /* write to child 1 on that named pipe */
    	   fd1 = open("toChild1", O_WRONLY);
    	   num = write(fd1, message1, sizeof(message1));
    
         return 1;
       }
       else
       {
    	   /* split child 2 here */
    	   if ((child2pid=fork()) == 0) {  /* child */
    		 execlp("./child", "./child", "2", "toChild2", NULL);
    		 perror("oops, child had an error!");
    
    	   /* write to child 2 on that named pipe */
    	   fd2 = open("toChild2", O_WRONLY);
    	   num = write(fd2, message2, sizeof(message2));
    
    		 return 1;
    	   }
    	   // parent display
    	   else { /* parent */
    		 printf("parent: child1's process id is %d\n",child1pid);
    		 printf("parent: child2's process id is %d\n",child2pid);
    		 printf("parent is going to wait for children to end...\n");
    		 wait();
    		 
    	   }
       }
    
       /* remove the named pipes from the directory */
       close(fd1); 
       close(fd2); 
    
       printf("Bye from the parent!!\n");
    }
    <i>child.c</i>
    Code:
    #include <stdio.h>
    #include <fcntl.h>
    
    int main(int argc, char **argv)
    {
       if (argc < 2){
         printf ("Must supply argument!\n");
         return -1;
       }
    
       char message[]="Hi Parent!!!";
       int fd;
       char buff[128];
       int num;
    
       printf("Howdy, I'm child %s.\n", argv[1]);
       printf("Child %s stream to read is %s.\n", argv[1], argv[2]);
    
       /* read data from the pipe that the parent created */
       if ((fd = open(argv[2], O_RDONLY)) == -1) {
          perror ("on open of child stream");
    //      unlink(childName);
          return 1;
       }
    
       num = read(fd, buff, 128);
       printf ("\nChild %s received: %s\n\n", argv[1], buff);
       close(fd);
    
    //   sleep(atoi(argv[1]));
    
       printf("Bye from child %s!!!\n", argv[1]);
    }
    Figaro Castle

  2. #2
    Ominous Wanderer Tech Admin Samuraid's Avatar
    Join Date
    Oct 2001
    Posts
    5,522

    Default

    Apologies, I don't have too much time to look at this at the moment. However, in the case of the first program, you should check the return value of write() and see if the write is supposedly successful or not.

  3. #3
    Old school, like an old fool. Flying Mullet's Avatar
    Join Date
    Apr 2003
    Location
    Napping in a peach tree.
    Posts
    19,185
    Articles
    6
    Blog Entries
    7
    Contributions
    • Former Administrator
    • Former Cid's Knight
    • Former Senior Site Staff

    Default

    Turns out they were environmental problems and not code problems.

    With my copy program, I had my open and create files swapped so I accidentally overwrote the old file with a clean new one without realizing it at one point, then switched them and went on my merry way, not checking to see if there were contents to the files. Thus it was behaving as it should, copying empty files. xD

    With my parent/child program, I had the files on a memory stick and the file system format didn't allow for creation of pipes. Once I copied the files onto my hard drive and ran it the pipes were created and I was able to move forward.

    The worst part is I spent at least four hours trying to fix code that wasn't broken. It was as bad as using = instead of == to test equality and not realizing it.
    Figaro Castle

  4. #4
    Old school, like an old fool. Flying Mullet's Avatar
    Join Date
    Apr 2003
    Location
    Napping in a peach tree.
    Posts
    19,185
    Articles
    6
    Blog Entries
    7
    Contributions
    • Former Administrator
    • Former Cid's Knight
    • Former Senior Site Staff

    Default

    I do have a follow-up question, how do you concatenate a string argument to an existing string? I tried something like this and I got some nasty stack error messages and my process was killed.

    Code:
       char message[]="Hi Parent from Child ";
       strcat(message, argv[1]);
       strcat(message, "!!!");
    Figaro Castle

  5. #5
    Ominous Wanderer Tech Admin Samuraid's Avatar
    Join Date
    Oct 2001
    Posts
    5,522

    Default

    Your character array "message" needs to be large enough to accommodate "Hi Parent from Child " as well as the data in argv[1].

    The way you defined it, it will only have enough storage for "Hi Parent from Child " as well as the terminating \0 null byte.
    You probably will want to dynamically allocate a character array large enough to accommodate both:

    Code:
    const char message_prefix[] = "Hi Parent from Child ";
    char * message;
    
    /* Allocate a character array of length message_prefix + length of argv[1]
     * plus 1 extra character for the terminating null byte.
     */
    if ((message = malloc(strlen(message_prefix) + strlen(argv[1]) + 1)) == 0)
    {
       /* The allocation failed for some reason. */
       perror("malloc");
       exit(1);
    }
    
    /* Copy the message_prefix to the beginning of our string. */
    strcpy(message, message_prefix);
    
    /* concatenate argv[1] on the end */
    strcat(message, argv[1]);
    
    /* Do stuff with your string here... */
    
    /* ALWAYS free the dynamic allocations when you are done. */
    free(message);
    This has not been tested nor syntax checked at all, so have fun with it.
    You'll need to include stdlib.h if you haven't already.

  6. #6
    Old school, like an old fool. Flying Mullet's Avatar
    Join Date
    Apr 2003
    Location
    Napping in a peach tree.
    Posts
    19,185
    Articles
    6
    Blog Entries
    7
    Contributions
    • Former Administrator
    • Former Cid's Knight
    • Former Senior Site Staff

    Default

    Bah, yes, I forgot to note that message was initialized to a size of 30 when I posted that code block. Oh well, I'll try the malloc stuff instead. This reminds me why I like working with Java.
    Figaro Castle

  7. #7
    diafnaoplzkthnxbai NeoTifa's Avatar
    Join Date
    Jun 2005
    Location
    in psy's panties <3
    Posts
    3,411

    Default

    You have like 4 blank include statements. :\
    Oh gods, why? ಥ_ಥ


  8. #8
    Ominous Wanderer Tech Admin Samuraid's Avatar
    Join Date
    Oct 2001
    Posts
    5,522

    Default

    &amp;lt; = &lt;
    Etc...

    They are there if you view the HTML source of this page.

  9. #9
    diafnaoplzkthnxbai NeoTifa's Avatar
    Join Date
    Jun 2005
    Location
    in psy's panties <3
    Posts
    3,411

    Default

    Pfftttt HTML is for pussies.....
    Oh gods, why? ಥ_ಥ


Posting Permissions

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