Search code examples
cforkpidchild-process

why is the fork() function in my code not creating a child process?


I am trying to write a program that takes command line arguments to verify a date and then show all files modified after that date. For some reason, the fork() function does not seem to be creating a child process and does not execute the corresponding part of code, and I can't figure out why. any suggestions?

The fork() parts themselves are on lines 59 and 76. The rest of the code runs fine, but the findafterdate() function only executes for the parent process.

 1 #define _XOPEN_SOURCE
 2 #include <stdio.h>
 3 #include <stdlib.h>
 4 #include <string.h>
 5 #include <time.h>
 6 #include <sys/wait.h>
 7 #include <unistd.h>
 8 #include <sys/types.h>
 9 #include <sys/stat.h>
10 #include <pthread.h>
11 char date[255];
12 char startLoc[255];
13
14
15 int findafterdate(int pid, char startLocation);
16
17
18
19 int main(int argc, char* argv[]){
20     //check arguments have been used
21
22     if(argc <2){
23         fprintf(stderr, "ERROR -- no argument set. use -h for help\n");
24         exit(EXIT_FAILURE);
25     }
26
27     //check for help switch
28     if (strcmp(argv[1], "-h")==0){
29         printf("usage: %s -t \"YYYY-MM-DD hh:mm:ss\"\n", argv[0]);
30         exit(EXIT_SUCCESS);
31     }
32     //check for cutoff time switch
33     else if(strcmp(argv[1], "-t")==0){
34       //check correct argument was used
35       if (argc <= 2){
36          fprintf(stderr, "ERROR -- use the format: %s -t \"YYYY-MM-DD hh:mm:ss\"\n", argv[0]);
37          exit(EXIT_FAILURE);
38       }
39       //set global variable startLoc to argv[3], or "." if none has been given
40       if (argc <= 3){
41         printf("test");
42         strncpy(startLoc, ".", sizeof(startLoc));
43         printf("start location automatically set to launch directory\n");
44       }
45       else{
46         printf("test");
47         strncpy(startLoc, argv[3], sizeof(startLoc));
48         printf("start location set to %s\n", startLoc);
49       }
50       //check if a filename was given
51
52       if ((strncmp(argv[2], "2", 1)!=0)){
53         printf("filename identified\n");
54         struct stat filestat;
55         stat(("%s", argv[2]), &filestat);
56         printf("%s", ctime(&filestat.st_mtime));
57         strncpy(date, ("%s", ctime(&filestat.st_mtime)), sizeof(date));
58         pid_t pid;
59         pid = fork();
60         findafterdate(pid, *startLoc);
61         return 0;
62       }
63
64       //check length of string to determine whether correct YYYY-MM-DD hh:mm:ss format was used
65       else if (strlen(argv[2]) <16 || strlen(argv[2])>19){
66         fprintf(stderr, "ERROR -- Invalid date format\n");
67         exit(EXIT_FAILURE);
68       }
69       //re - format argument into tm
70       struct tm tm;
71
72       memset(&tm, 0, sizeof(struct tm));
73       strptime(argv[2], "%Y-%m-%d %H:%M:%S", &tm);
74       strftime(date, sizeof(date), "%b %d %Y %H:%M", &tm);
75       pid_t pid;
76       pid = fork();
77       findafterdate(pid, *startLoc);
78       return 0;
79     }
80 }
81 int findafterdate(int pid, char startLocation){
82     if (pid==0){
83 //      printf("child check");
84         printf("start location: %s || date : %s\n", startLocation, date);
85         execl("/usr/bin/find", "find",("%s", startLocation), "-newermt", ("%s", date), NULL);
86     }
87     else{
88         printf("listing files modified after: %s\n", date);
89         int status;
90         waitpid(pid, &status, 0);
91     }
92     return EXIT_SUCCESS;
93   }
                                                                                                                                                                                             62,2-5        Bot

The child process should print "child check" (this was added to ensure it wasn't seg faulting during the actual process) before executing "find -newermt " to show all the files under the starting directory that were modified after the date given. Instead, it simply does nothing. I cannot for the life of me figure out why this is.


Solution

  • In findafterdate(), startLocation is a char but is passed to printf() as an argument corresponding to a %s format descriptor, where a char * is expected. The compiler should have warned you about this; try compiling with warnings turned on. As a consequence, the behavior of the program is undefined.

    Undefined behavior being undefined, nothing can be said about the operation of the program.

    P.S. The call to execl() is mighty strange. What do you think that ("%s", startLocation) means which is different from plain startLocation? And arguments to execl() must be char * not char.