Как программа вызывает функцию? - PullRequest
0 голосов
/ 23 октября 2019

Я прохожу этот код, просто для понимания этого кода работает

Я включил текстовый файл для чтения и, но программа не вызывает функцию. Также мне нужно понять, что на самом деле делает функция? Я отслеживал, но не успешно

int printpos(const char *string, int filedes);

fatal(char *s) {
  perror(s);
  exit(1);
  }

int main() {
  int fd;
  pid_t pid; 
  char buf[10]; 

  if ((fd = open("example.txt", O_RDONLY)) == -1)
    fatal(" open failed");

  read(fd, buf, 10); 
  printpos("before fork", fd);

  switch(pid = fork()) {
    case -1: 
      fatal("fork failed");
      break;
    case 0: 
      printpos("child before read", fd),
      read(fd, buf, 10);
      printpos("child after read", fd);
      break;
    default: 
      wait((int *)0);
      printpos("parent after wait", fd);
    }
  }

int printpos(const char *string, int filedes) {
  off_t pos;
  if ((pos = lseek(filedes, 0, SEEK_CUR)) == -1)
    fatal("lseek failed"); 
  printf("%s:%ld\n", string, pos);
  }

1 Ответ

0 голосов
/ 23 октября 2019

Я взял на себя смелость преобразовать код вопроса в реальную программу, которая может быть скомпилирована и выполнена (кстати, это правильный этикет для тех, кто публикует вопросы).

            /*
            These "#include" lines inform the compiler of external functions
            and macro values used in the program.
            */
            #include <stdio.h>          // printf(), perror()
            #include <stdlib.h>         // exit(), wait(), EXIT_SUCCESS
            #include <fcntl.h>          // open(), O_RDONLY
            #include <unistd.h>         // read(), fork(), lseek()

            /*
            The following line is called a "function prototype".  It gives the
            compiler fore-knowledge that this function will be called by the
            program, prior to it's actual definition.

            Specifically, it tells the compiler that it will eventually find
            a function definition for a function named "printpos()"; that
            this function accepts a pointer to a character array (char *) for
            the first parameter, and an integer value (int) for the second
            value; and that the function will return an integer value to the
            caller.  Additionally, compiler is informed that while the first
            parameter is a pointer to a character array, the actual array
            (const char *) may not be modified by the printpos() function.

            Strictly speaking, the "string" and "fildes" labels are not 
            required, or useful, to the compiler.  Hence, the line may be 
            shortened to:

                int printpos(const char *, int);

            If the printpos() function is moved above main() (from where it
            is called), the line can be eliminated.  Why? Because if the the 
            printpos() function is fully defined prior to main(), then the 
            compiler will know of the existence of the printpos() function 
            prior to it being referenced in main().
            */
            int printpos(const char *string, int filedes);

            /*
            This is a function definition, that defines the "fatal()" function.
            This function returns no value, and accepts a pointer to a character
            array as a parameter.
            */
            void fatal(char *s) {
                perror(s);      /* Displays the string pointed to by parameter (s)
                                   followed by the error message corresponding to
                                   the current value of the global variable errno */
                exit(1);        /* Terminates the program, returning an 8-bit status
                                   value of (1) */
                }

            /*
            This is a function definition, that defines the "main()" function.
            The "main()" function is required in this program, and is where
            the program execution begins.

            This function returns an integer (int) value , and accepts no
            parameters.
            */
            int main() {
                int fd;           /* Causes the compiler to create a variable
                                     called "fd", suitable for storing an
                                     integer (int) value. */
                pid_t pid;        /* Causes the compiler to create a variable
                                     called "pid", suitable for storing a
                                     process ID (pid_t) value. */
                char buf[10];     /* Causes the compiler to create a variable
                                     called "buf", suitable for storing ten
                                     [10] characters in a sequencial array. */

                /* This is a compound statement; which can be simplified as:

                        fd = open("example.txt", O_RDONLY); // Attempts read-only access to the file "example.txt"
                                                            // Stores a "file descriptor" reference to the file in the variable "fd"
                        if(fd == -1)                        // Checks to see if the "open()" function failed.
                            fatal(" open failed");          // Prints an error and terminates the program.
                */
                if ((fd = open("example.txt", O_RDONLY)) == -1)
                    fatal(" open failed");

                read(fd, buf, 10);                      // Attempts to read 10 bytes from the file referenced by "fd" into a character array "buf"
                printpos("before fork", fd);            // Displays "before fork", followed by the byte offset current location in the file referenced by "fd"

                /* This is a compound statement; which can be simplified as:

                        pid=fork();     // Attempts to create a new process.
                        switch(pid) {   // Depending on the value of pid, take the action indicated by case values.

                */
                switch(pid = fork()) {
                    case -1:                      // If the value of pid is (-1), the fork() function has failed.
                        fatal("fork failed");     // Prints an error and terminates the program.
                        break;                    // Being that the fatal() function terminates the program, this "break" statement is not necessary.
                    case 0:                       // If the value of pid is (0), then it is the new "child" process.
                        printpos("child before read", fd); // Displays "child before read", followed by the byte offset current location in the file referenced by "fd"
                        read(fd, buf, 10);        // Attempts to read 10 bytes from the file referenced by "fd" into a character array "buf"
                        printpos("child after read", fd); // Displays "child after read", followed by the byte offset current location in the file referenced by "fd"
                        break;                    // Breaks out of the switch statement to execute code beyond the next '}' brace.
                    default:                      // if the value of pid did not match any case values, it is the parent process.
                        wait((int *)0);           // This line causes the parent process to suspend until the child process has terminated.
                        printpos("parent after wait", fd); // Displays "parent after wait", followed by the byte offset current location in the file referenced by "fd"
                    }

                /* Returns control to the caller, with an integer (int) value of EXIT_SUCCESS (0).
                   In this case, returning from the main() function causes the program to terminate.
                */
                return(EXIT_SUCCESS);
                }


            /*
            This is a function definition, that defines the "printpos()" function.

            This function's return value and parameter types must match its function
            prototype (above).

            This function accepts a pointer to a character array (char *) for the
            first parameter, and an integer value (int) for the second value;
            and the function will return an integer value to the caller.
            Additionally, while the first parameter is a pointer to a character
            array, the actual array (const char *) may not be modified by the
            printpos() function.
            */
            int printpos(const char *string, int filedes) {
                off_t pos;        /* Causes the compiler to create a variable
                                     called "pos", suitable for storing a file
                                     offset (off_t) value. */

                /* This is a compound statement; which can be simplified as:

                    pos = lseek(filedes, 0, SEEK_CUR);  // Sets the value of the pos variable to the current position of the file specified by the filedes variable.
                    if(pos == -1)                       // Checks to see if the "lseek()" function failed.

                */
                if ((pos = lseek(filedes, 0, SEEK_CUR)) == -1)
                    fatal("lseek failed");             // If the lseek() function failed, Prints an error and terminates the program.
                printf("%s:%lld\n", string, pos);    // Displays the array of characters "string" (specified by the caller), followed by the byte offset current location in the file referenced by "filedes"

                /* Returns control to the caller, with an integer (int) value of EXIT_SUCCESS (0).
                */
                return(EXIT_SUCCESS);
                }
...