mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-06-30 16:28:30 +00:00
Fix race condition in makedirs()
This commit is contained in:
parent
b7c07d548c
commit
571c2c3c69
7 changed files with 90 additions and 10 deletions
|
@ -16,11 +16,11 @@
|
|||
│ TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR │
|
||||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/calls/calls.h"
|
||||
#include "libc/calls/strace.internal.h"
|
||||
#include "libc/errno.h"
|
||||
#include "libc/intrin/safemacros.internal.h"
|
||||
#include "libc/intrin/weaken.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "libc/x/x.h"
|
||||
|
@ -44,7 +44,12 @@ static int MakeDirs(const char *path, unsigned mode, int e) {
|
|||
free(dir);
|
||||
if (rc == -1) return -1;
|
||||
errno = e;
|
||||
return mkdir(path, mode);
|
||||
if (!mkdir(path, mode) || errno == EEXIST) {
|
||||
errno = e;
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -55,7 +60,7 @@ static int MakeDirs(const char *path, unsigned mode, int e) {
|
|||
* @param path is a UTF-8 string, preferably relative w/ forward slashes
|
||||
* @param mode can be, for example, 0755
|
||||
* @return 0 on success or -1 w/ errno
|
||||
* @see mkdir()
|
||||
* @threadsafe
|
||||
*/
|
||||
int makedirs(const char *path, unsigned mode) {
|
||||
return MakeDirs(path, mode, errno);
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
|
@ -24,5 +25,9 @@
|
|||
* Returns base portion of path.
|
||||
*/
|
||||
char *xbasename(const char *path) {
|
||||
return xstrdup(basename(gc(xstrdup(path))));
|
||||
char *base;
|
||||
path = xstrdup(path);
|
||||
base = xstrdup(basename(path));
|
||||
free(path);
|
||||
return base;
|
||||
}
|
||||
|
|
|
@ -17,12 +17,16 @@
|
|||
│ PERFORMANCE OF THIS SOFTWARE. │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/runtime/gc.internal.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/x/x.h"
|
||||
|
||||
/**
|
||||
* Returns directory portion of path.
|
||||
*/
|
||||
char *xdirname(const char *path) {
|
||||
return xstrdup(dirname(gc(xstrdup(path))));
|
||||
char *dirp;
|
||||
path = xstrdup(path);
|
||||
dirp = xstrdup(dirname(path));
|
||||
free(path);
|
||||
return dirp;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue