From: softworkz <softwo...@hotmail.com> --- fftools/Makefile | 1 + fftools/graph/_system.c | 213 ++++++++++++++++++++++++++++++++ fftools/graph/_system.h | 27 ++++ fftools/graph/_system_support.h | 199 +++++++++++++++++++++++++++++ fftools/graph/filelauncher.c | 3 +- 5 files changed, 442 insertions(+), 1 deletion(-) create mode 100644 fftools/graph/_system.c create mode 100644 fftools/graph/_system.h create mode 100644 fftools/graph/_system_support.h
diff --git a/fftools/Makefile b/fftools/Makefile index f6492cb1d7..dba96d3740 100644 --- a/fftools/Makefile +++ b/fftools/Makefile @@ -23,6 +23,7 @@ OBJS-ffmpeg += \ fftools/ffmpeg_sched.o \ fftools/graph/graphprint.o \ fftools/graph/filelauncher.o \ + fftools/graph/_system.o \ fftools/sync_queue.o \ fftools/thread_queue.o \ fftools/textformat/avtextformat.o \ diff --git a/fftools/graph/_system.c b/fftools/graph/_system.c new file mode 100644 index 0000000000..d1568611ff --- /dev/null +++ b/fftools/graph/_system.c @@ -0,0 +1,213 @@ +/* + * Copyright (c) 1991-2018 - Free Software Foundation, Inc. + * + * 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 + */ + + + /* Copyright (C) 1991-2018 Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library 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. + + The GNU C Library 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 the GNU C Library; if not, see + <http://www.gnu.org/licenses/>. */ + +#include "config.h" + +#if defined(_WIN32) +#elif defined(__APPLE__) +#else + +#include <errno.h> +#include <signal.h> +#include <stddef.h> +#include <stdlib.h> +#include "_system_support.h" +#include <sys/types.h> // Add this include to define pid_t +#include "_system.h" + + +#define SHELL_PATH "/bin/sh" /* Path of the shell. */ +#define SHELL_NAME "sh" /* Name to give it. */ + + +#ifdef _LIBC_REENTRANT +static struct sigaction intr, quit; +static int sa_refcntr; +__libc_lock_define_initialized (static, lock); + +# define DO_LOCK() __libc_lock_lock (lock) +# define DO_UNLOCK() __libc_lock_unlock (lock) +# define INIT_LOCK() ({ __libc_lock_init (lock); sa_refcntr = 0; }) +# define ADD_REF() sa_refcntr++ +# define SUB_REF() --sa_refcntr +#else +# define DO_LOCK() +# define DO_UNLOCK() +# define INIT_LOCK() +# define ADD_REF() 0 +# define SUB_REF() 0 +#endif + + +/* Execute LINE as a shell command, returning its status. */ +static int +do_system (const char *line) +{ + int status, save; + pid_t pid; + struct sigaction sa; +#ifndef _LIBC_REENTRANT + struct sigaction intr, quit; +#endif + sigset_t omask; + + sa.sa_handler = SIG_IGN; + sa.sa_flags = 0; + __sigemptyset (&sa.sa_mask); + + DO_LOCK (); + if (ADD_REF () == 0) + { + if (__sigaction (SIGINT, &sa, &intr) < 0) + { + (void) SUB_REF (); + goto out; + } + if (__sigaction (SIGQUIT, &sa, &quit) < 0) + { + save = errno; + (void) SUB_REF (); + goto out_restore_sigint; + } + } + DO_UNLOCK (); + + /* We reuse the bitmap in the 'sa' structure. */ + __sigaddset (&sa.sa_mask, SIGCHLD); + save = errno; + if (__sigprocmask (SIG_BLOCK, &sa.sa_mask, &omask) < 0) + { +#ifndef _LIBC + if (errno == ENOSYS) + __set_errno (save); + else +#endif + { + DO_LOCK (); + if (SUB_REF () == 0) + { + save = errno; + (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); + out_restore_sigint: + (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL); + __set_errno (save); + } + out: + DO_UNLOCK (); + return -1; + } + } + +#ifdef CLEANUP_HANDLER + CLEANUP_HANDLER; +#endif + +#ifdef FORK + pid = FORK (); +#else + pid = __fork (); +#endif + if (pid == (pid_t) 0) + { + /* Child side. */ + const char *new_argv[4]; + new_argv[0] = SHELL_NAME; + new_argv[1] = "-c"; + new_argv[2] = line; + new_argv[3] = NULL; + + /* Restore the signals. */ + (void) __sigaction (SIGINT, &intr, (struct sigaction *) NULL); + (void) __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL); + (void) __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL); + pthread_mutex_init(&(lock), NULL); + sa_refcntr = 0; + /* Exec the shell. */ + (void) __execve (SHELL_PATH, (char *const *) new_argv, __environ); + _exit (127); + } + else if (pid < (pid_t) 0) + /* The fork failed. */ + status = -1; + else + /* Parent side. */ + { + /* Note the system() is a cancellation point. But since we call + waitpid() which itself is a cancellation point we do not + have to do anything here. */ + if (TEMP_FAILURE_RETRY (__waitpid (pid, &status, 0)) != pid) + status = -1; + } + +#ifdef CLEANUP_HANDLER + CLEANUP_RESET; +#endif + + save = errno; + DO_LOCK (); + if ((SUB_REF () == 0 + && (__sigaction (SIGINT, &intr, (struct sigaction *) NULL) + | __sigaction (SIGQUIT, &quit, (struct sigaction *) NULL)) != 0) + || __sigprocmask (SIG_SETMASK, &omask, (sigset_t *) NULL) != 0) + { +#ifndef _LIBC + /* glibc cannot be used on systems without waitpid. */ + if (errno == ENOSYS) + __set_errno (save); + else +#endif + status = -1; + } + DO_UNLOCK (); + + return status; +} + +int +__libc_system (const char *line) +{ + if (line == NULL) + /* Check that we have a command processor available. It might + not be available after a chroot(), for example. */ + return do_system ("exit 0") == 0; + + return do_system (line); +} +////weak_alias (__libc_system, system) + +#endif \ No newline at end of file diff --git a/fftools/graph/_system.h b/fftools/graph/_system.h new file mode 100644 index 0000000000..2780f234e0 --- /dev/null +++ b/fftools/graph/_system.h @@ -0,0 +1,27 @@ +/* + * Copyright (c) 2025 - softworkz + * + * 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 + */ + +#ifndef FFTOOLS_GRAPH_SYSTEM_H +#define FFTOOLS_GRAPH_SYSTEM_H + + +int __libc_system (const char *line); + +#endif /* FFTOOLS_GRAPH_SYSTEM_H */ diff --git a/fftools/graph/_system_support.h b/fftools/graph/_system_support.h new file mode 100644 index 0000000000..6121c9bf2e --- /dev/null +++ b/fftools/graph/_system_support.h @@ -0,0 +1,199 @@ +/* + * Copyright (c) 2025 - softworkz + * + * 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 + */ + +#ifndef FFTOOLS_GRAPH_SYSTEM_SUPPORT_H +#define FFTOOLS_GRAPH_SYSTEM_SUPPORT_H + +#include <signal.h> +#include <errno.h> +#include <stdlib.h> + +/* Platform-specific includes */ +#ifdef _WIN32 +#include <windows.h> +#include "../../compat/w32pthreads.h" + +/* Windows doesn't have these POSIX headers - provide minimal compatibility */ +/* Visual Studio doesn't define pid_t, so define it ourselves */ +////#ifndef _PID_T_DEFINED +////typedef int pid_t; +////#define _PID_T_DEFINED +////#endif + +typedef unsigned int sigset_t; + +/* Windows signal compatibility */ +#ifndef SIGQUIT +#define SIGQUIT 3 +#endif +#ifndef SIGCHLD +#define SIGCHLD 0 /* Not used on Windows */ +#endif +#define SIG_BLOCK 0 +#define SIG_SETMASK 1 + +/* Windows sigaction compatibility */ +struct sigaction { + void (*sa_handler)(int); + sigset_t sa_mask; + int sa_flags; +}; + +/* Windows signal function stubs */ +static inline int sigemptyset(sigset_t *set) { *set = 0; return 0; } +static inline int sigaddset(sigset_t *set, int sig) { *set |= (1 << sig); return 0; } +static inline int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) { + if (oldset) *oldset = 0; + return 0; +} +static inline int sigaction(int sig, const struct sigaction *act, struct sigaction *oldact) { + if (oldact) { + oldact->sa_handler = SIG_DFL; + oldact->sa_mask = 0; + oldact->sa_flags = 0; + } + return 0; +} + +/* Windows process function stubs */ +static inline pid_t fork(void) { + errno = ENOSYS; + return -1; +} + +/* Don't redefine execve if it already exists - use a wrapper name instead */ +static inline int __execve_wrapper(const char *path, char *const argv[], char *const envp[]) { + /* Use Windows system() as fallback - argv[2] should be the command */ + if (argv && argv[2]) { + return system(argv[2]); + } + return -1; +} + +static inline pid_t waitpid(pid_t pid, int *status, int options) { + if (status) *status = 0; + return pid; +} + +#else +#include <sys/types.h> +#include <sys/wait.h> +#include <unistd.h> +#include <pthread.h> +#endif + +/* Ensure environ is declared - but don't conflict with existing declarations */ +#ifndef _WIN32 +extern char **environ; +#endif + +/* glibc compatibility: TEMP_FAILURE_RETRY macro */ +#ifndef TEMP_FAILURE_RETRY +#ifdef _MSC_VER +/* Visual Studio compatible version - Windows doesn't have EINTR, so no retry needed */ +#define TEMP_FAILURE_RETRY(expression) (expression) +#elif defined(__GNUC__) +/* GCC version with statement expressions */ +#define TEMP_FAILURE_RETRY(expression) \ + (__extension__ \ + ({ long int __result; \ + do __result = (long int) (expression); \ + while (__result == -1L && errno == EINTR); \ + __result; })) +#else +/* Fallback for other compilers */ +#define TEMP_FAILURE_RETRY(expression) (expression) +#endif +#endif + +/* glibc compatibility: libc-lock macros */ +#define __libc_lock_define_initialized(CLASS, NAME) \ + CLASS pthread_mutex_t NAME = PTHREAD_MUTEX_INITIALIZER + +#define __libc_lock_lock(NAME) pthread_mutex_lock(&(NAME)) +#define __libc_lock_unlock(NAME) pthread_mutex_unlock(&(NAME)) +#define __libc_lock_init(NAME) pthread_mutex_init(&(NAME), NULL) + +/* glibc compatibility: signal functions */ +#define __sigemptyset(set) sigemptyset(set) +#define __sigaddset(set, sig) sigaddset(set, sig) +#define __sigprocmask(how, set, oldset) sigprocmask(how, set, oldset) +#define __sigaction(sig, act, oldact) sigaction(sig, act, oldact) + +/* glibc compatibility: process functions */ +#define __fork fork +#ifdef _WIN32 +#define __execve __execve_wrapper +#define __environ _environ +#else +#define __execve execve +#define __environ environ +#endif +#define __waitpid waitpid + +/* glibc compatibility: errno setting */ +#define __set_errno(val) (errno = (val)) + +/* glibc compatibility: weak alias macro - simplified for Windows */ +#ifdef _WIN32 +#define weak_alias(name, aliasname) \ + int aliasname(const char *line) { return name(line); } +#else +#define weak_alias(name, aliasname) \ + extern __typeof (name) aliasname __attribute__ ((weak, alias (#name))) +#endif + +/* Threading and cancellation support */ +#ifndef _LIBC_REENTRANT +#define _LIBC_REENTRANT 1 +#endif + +/* Optional cleanup handler support - can be defined by user if needed */ +#ifndef CLEANUP_HANDLER +#define CLEANUP_HANDLER +#endif + +#ifndef CLEANUP_RESET +#define CLEANUP_RESET +#endif + +/* Optional fork override - can be defined by user if needed */ +#ifndef FORK +#define FORK __fork +#endif + +/* Legacy wrappers for compatibility (keeping existing interface) */ +typedef pthread_mutex_t simple_lock_t; +#define SIMPLE_LOCK_INIT PTHREAD_MUTEX_INITIALIZER +static inline void simple_lock_lock(simple_lock_t *lock) { pthread_mutex_lock(lock); } +static inline void simple_lock_unlock(simple_lock_t *lock) { pthread_mutex_unlock(lock); } +static inline void simple_lock_init(simple_lock_t *lock) { pthread_mutex_init(lock, NULL); } + +static inline int sigaction_wrap(int sig, const struct sigaction *act, struct sigaction *oact) { + return sigaction(sig, act, oact); +} +static inline int sigprocmask_wrap(int how, const sigset_t *set, sigset_t *oldset) { + return sigprocmask(how, set, oldset); +} +static inline pid_t waitpid_wrap(pid_t pid, int *status, int options) { + return waitpid(pid, status, options); +} + +#endif // FFTOOLS_GRAPH_SYSTEM_SUPPORT_H \ No newline at end of file diff --git a/fftools/graph/filelauncher.c b/fftools/graph/filelauncher.c index b46967e334..2214338183 100644 --- a/fftools/graph/filelauncher.c +++ b/fftools/graph/filelauncher.c @@ -31,6 +31,7 @@ # include <sys/stat.h> # include <sys/types.h> # include <unistd.h> +# include "_system.h" #endif #include "graphprint.h" #include "libavutil/bprint.h" @@ -80,7 +81,7 @@ int ff_open_html_in_browser(const char *html_path) av_bprint_init(&buf, 0, AV_BPRINT_SIZE_AUTOMATIC); av_bprintf(&buf, "xdg-open '%s' </dev/null 1>/dev/null 2>&1 &", html_path); - int ret = system(buf.str); + int ret = __libc_system(buf.str); if (ret != -1 && WIFEXITED(ret) && WEXITSTATUS(ret) == 0) return 0; -- ffmpeg-codebot _______________________________________________ ffmpeg-devel mailing list ffmpeg-devel@ffmpeg.org https://ffmpeg.org/mailman/listinfo/ffmpeg-devel To unsubscribe, visit link above, or email ffmpeg-devel-requ...@ffmpeg.org with subject "unsubscribe".