diff --git a/libavformat/Makefile b/libavformat/Makefile index 9c761ba341..3595567464 100644 --- a/libavformat/Makefile +++ b/libavformat/Makefile @@ -780,6 +780,7 @@ SKIPHEADERS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpdh.h SKIPHEADERS-$(CONFIG_NETWORK) += network.h rtsp.h TESTPROGS = id3v2 \ + mkdir \ seek \ url \ seek_utils diff --git a/libavformat/tests/.gitignore b/libavformat/tests/.gitignore index f9aac1f9e0..951ccf0f37 100644 --- a/libavformat/tests/.gitignore +++ b/libavformat/tests/.gitignore @@ -1,6 +1,7 @@ /id3v2 /fifo_muxer /imf +/mkdir /movenc /noproxy /rtmpdh diff --git a/libavformat/tests/mkdir.c b/libavformat/tests/mkdir.c new file mode 100644 index 0000000000..42e5c0562d --- /dev/null +++ b/libavformat/tests/mkdir.c @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2026 Jun Zhao + * + * This file is part of FFmpeg. + * + * FFmpeg is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * FFmpeg is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with FFmpeg; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "config.h" + +#include +#include + +#if HAVE_UNISTD_H +#include +#endif + +#include "libavutil/random_seed.h" + +#include "libavformat/internal.h" +#include "libavformat/os_support.h" + +int main(void) +{ + char parent[64]; + char child[80]; + + snprintf(parent, sizeof(parent), "ff-mkdir-test-%08x", av_get_random_seed()); + snprintf(child, sizeof(child), "%s/child", parent); + + if (mkdir(parent, 0755) < 0) { + perror("mkdir parent"); + return 1; + } + + if (ff_mkdir_p(child) < 0) { + perror("ff_mkdir_p"); + rmdir(parent); + return 1; + } + + if (rmdir(child) < 0) { + perror("rmdir child"); + rmdir(parent); + return 1; + } + + if (rmdir(parent) < 0) { + perror("rmdir parent"); + return 1; + } + + return 0; +} diff --git a/libavformat/utils.c b/libavformat/utils.c index c64ff27418..cb0ae7444e 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -443,6 +443,12 @@ int ff_mkdir_p(const char *path) tmp_ch = *pos; *pos = '\0'; ret = mkdir(temp, 0755); + if (ret < 0 && errno != EEXIST) { + int err = errno; + av_free(temp); + errno = err; + return ret; + } *pos = tmp_ch; } } diff --git a/tests/fate/libavformat.mak b/tests/fate/libavformat.mak index 3b3a8a1177..989515a646 100644 --- a/tests/fate/libavformat.mak +++ b/tests/fate/libavformat.mak @@ -2,6 +2,11 @@ #fate-async: libavformat/tests/async$(EXESUF) #fate-async: CMD = run libavformat/tests/async +FATE_LIBAVFORMAT += fate-mkdir +fate-mkdir: libavformat/tests/mkdir$(EXESUF) +fate-mkdir: CMD = run libavformat/tests/mkdir$(EXESUF) +fate-mkdir: CMP = null + FATE_LIBAVFORMAT-$(CONFIG_NETWORK) += fate-noproxy fate-noproxy: libavformat/tests/noproxy$(EXESUF) fate-noproxy: CMD = run libavformat/tests/noproxy$(EXESUF)