OpenCoverage

mkancesdirs.c

Absolute File Name:/home/opencoverage/opencoverage/guest-scripts/coreutils/src/gnulib/lib/mkancesdirs.c
Source codeSwitch to Preprocessed file
LineSourceCount
1/* Make a file's ancestor directories.-
2-
3 Copyright (C) 2006, 2009-2018 Free Software Foundation, Inc.-
4-
5 This program is free software: you can redistribute it and/or modify-
6 it under the terms of the GNU General Public License as published by-
7 the Free Software Foundation; either version 3 of the License, or-
8 (at your option) any later version.-
9-
10 This program is distributed in the hope that it will be useful,-
11 but WITHOUT ANY WARRANTY; without even the implied warranty of-
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the-
13 GNU General Public License for more details.-
14-
15 You should have received a copy of the GNU General Public License-
16 along with this program. If not, see <https://www.gnu.org/licenses/>. */-
17-
18/* Written by Paul Eggert. */-
19-
20#include <config.h>-
21-
22#include "mkancesdirs.h"-
23-
24#include <sys/types.h>-
25#include <sys/stat.h>-
26#include <fcntl.h>-
27-
28#include <errno.h>-
29#include <unistd.h>-
30-
31#include "dirname.h"-
32#include "savewd.h"-
33-
34/* Ensure that the ancestor directories of FILE exist, using an-
35 algorithm that should work even if two processes execute this-
36 function in parallel. Modify FILE as necessary to access the-
37 ancestor directories, but restore FILE to an equivalent value-
38 if successful.-
39-
40 WD points to the working directory, using the conventions of-
41 savewd.-
42-
43 Create any ancestor directories that don't already exist, by-
44 invoking MAKE_DIR (FILE, COMPONENT, MAKE_DIR_ARG). This function-
45 should return 0 if successful, -1 (setting errno) otherwise. If-
46 COMPONENT is relative, it is relative to the temporary working-
47 directory, which may differ from *WD.-
48-
49 Ordinarily MAKE_DIR is executed with the working directory changed-
50 to reflect the already-made prefix, and mkancesdirs returns with-
51 the working directory changed a prefix of FILE. However, if the-
52 initial working directory cannot be saved in a file descriptor,-
53 MAKE_DIR is invoked in a subprocess and this function returns in-
54 both the parent and child process, so the caller should not assume-
55 any changed state survives other than the EXITMAX component of WD,-
56 and the caller should take care that the parent does not attempt to-
57 do the work that the child is doing.-
58-
59 If successful and if this process can go ahead and create FILE,-
60 return the length of the prefix of FILE that has already been made.-
61 If successful so far but a child process is doing the actual work,-
62 return -2. If unsuccessful, return -1 and set errno. */-
63-
64ptrdiff_t-
65mkancesdirs (char *file, struct savewd *wd,-
66 int (*make_dir) (char const *, char const *, void *),-
67 void *make_dir_arg)-
68{-
69 /* Address of the previous directory separator that follows an-
70 ordinary byte in a file name in the left-to-right scan, or NULL-
71 if no such separator precedes the current location P. */-
72 char *sep = NULL;-
73-
74 /* Address of the leftmost file name component that has not yet-
75 been processed. */-
76 char *component = file;-
77-
78 char *p = file + FILE_SYSTEM_PREFIX_LEN (file);-
79 char c;-
80 bool made_dir = false;-
81-
82 /* Scan forward through FILE, creating and chdiring into directories-
83 along the way. Try MAKE_DIR before chdir, so that the procedure-
84 works even when two or more processes are executing it in-
85 parallel. Isolate each file name component by having COMPONENT-
86 point to its start and SEP point just after its end. */-
87-
88 while ((c = *p++))
(c = *p++)Description
TRUEevaluated 25026 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
FALSEevaluated 123 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
123-25026
89 if (ISSLASH (*p))
((*p) == '/')Description
TRUEevaluated 12388 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
FALSEevaluated 12638 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
12388-12638
90 {-
91 if (! ISSLASH (c))
! ((c) == '/')Description
TRUEevaluated 12388 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
FALSEnever evaluated
0-12388
92 sep = p;
executed 12388 times by 2 tests: sep = p;
Executed by:
  • ginstall
  • mkdir
12388
93 }
executed 12388 times by 2 tests: end of block
Executed by:
  • ginstall
  • mkdir
12388
94 else if (ISSLASH (c) && *p && sep)
((c) == '/')Description
TRUEevaluated 12391 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
FALSEevaluated 247 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
*pDescription
TRUEevaluated 12313 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
FALSEevaluated 78 times by 1 test
Evaluated by:
  • mkdir
sepDescription
TRUEevaluated 12310 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
FALSEevaluated 3 times by 1 test
Evaluated by:
  • ginstall
3-12391
95 {-
96 /* Don't bother to make or test for "." since it does not-
97 affect the algorithm. */-
98 if (! (sep - component == 1 && component[0] == '.'))
sep - component == 1Description
TRUEevaluated 12285 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
FALSEevaluated 25 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
component[0] == '.'Description
TRUEnever evaluated
FALSEevaluated 12285 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
0-12285
99 {-
100 int make_dir_errno = 0;-
101 int savewd_chdir_options = 0;-
102 int chdir_result;-
103-
104 /* Temporarily modify FILE to isolate this file name-
105 component. */-
106 *sep = '\0';-
107-
108 /* Invoke MAKE_DIR on this component, except don't bother-
109 with ".." since it must exist if its "parent" does. */-
110 if (sep - component == 2
sep - component == 2Description
TRUEevaluated 2 times by 1 test
Evaluated by:
  • ginstall
FALSEevaluated 12308 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
2-12308
111 && component[0] == '.' && component[1] == '.')
component[0] == '.'Description
TRUEnever evaluated
FALSEevaluated 2 times by 1 test
Evaluated by:
  • ginstall
component[1] == '.'Description
TRUEnever evaluated
FALSEnever evaluated
0-2
112 made_dir = false;
never executed: made_dir = 0 ;
0
113 else if (make_dir (file, component, make_dir_arg) < 0)
make_dir (file...e_dir_arg) < 0Description
TRUEevaluated 172 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
FALSEevaluated 12138 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
172-12138
114 make_dir_errno = errno;
executed 172 times by 2 tests: make_dir_errno = (*__errno_location ()) ;
Executed by:
  • ginstall
  • mkdir
172
115 else-
116 made_dir = true;
executed 12138 times by 2 tests: made_dir = 1 ;
Executed by:
  • ginstall
  • mkdir
12138
117-
118 if (made_dir)
made_dirDescription
TRUEevaluated 12138 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
FALSEevaluated 172 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
172-12138
119 savewd_chdir_options |= SAVEWD_CHDIR_NOFOLLOW;
executed 12138 times by 2 tests: savewd_chdir_options |= SAVEWD_CHDIR_NOFOLLOW;
Executed by:
  • ginstall
  • mkdir
12138
120-
121 chdir_result =-
122 savewd_chdir (wd, component, savewd_chdir_options, NULL);-
123-
124 /* Undo the temporary modification to FILE, unless there-
125 was a failure. */-
126 if (chdir_result != -1)
chdir_result != -1Description
TRUEevaluated 12309 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
FALSEevaluated 1 time by 1 test
Evaluated by:
  • ginstall
1-12309
127 *sep = '/';
executed 12309 times by 2 tests: *sep = '/';
Executed by:
  • ginstall
  • mkdir
12309
128-
129 if (chdir_result != 0)
chdir_result != 0Description
TRUEevaluated 5 times by 1 test
Evaluated by:
  • ginstall
FALSEevaluated 12305 times by 2 tests
Evaluated by:
  • ginstall
  • mkdir
5-12305
130 {-
131 if (make_dir_errno != 0 && errno == ENOENT)
make_dir_errno != 0Description
TRUEevaluated 4 times by 1 test
Evaluated by:
  • ginstall
FALSEevaluated 1 time by 1 test
Evaluated by:
  • ginstall
(*__errno_location ()) == 2Description
TRUEnever evaluated
FALSEevaluated 4 times by 1 test
Evaluated by:
  • ginstall
0-4
132 errno = make_dir_errno;
never executed: (*__errno_location ()) = make_dir_errno;
0
133 return chdir_result;
executed 5 times by 1 test: return chdir_result;
Executed by:
  • ginstall
5
134 }-
135 }
executed 12305 times by 2 tests: end of block
Executed by:
  • ginstall
  • mkdir
12305
136-
137 component = p;-
138 }
executed 12305 times by 2 tests: end of block
Executed by:
  • ginstall
  • mkdir
12305
139-
140 return component - file;
executed 123 times by 2 tests: return component - file;
Executed by:
  • ginstall
  • mkdir
123
141}-
Source codeSwitch to Preprocessed file

Generated by Squish Coco 4.1.2