Skip to content

Commit

Permalink
some refactoring, comments, use fork() instead of vfork(), print log …
Browse files Browse the repository at this point in the history
…messages in parent context

git-svn-id: https://svn.code.sf.net/p/vice-emu/code/trunk@45456 379a1393-f5fb-40a0-bcee-ef074d9b53f7
  • Loading branch information
mrdudz committed Jan 9, 2025
1 parent 2b23e88 commit a44d2d2
Showing 1 changed file with 55 additions and 12 deletions.
67 changes: 55 additions & 12 deletions vice/src/arch/shared/archdep_spawn.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,33 @@
*
*/

/*
calls an external program, waits for it to finish, and returns status
name file name of external program
- If the name contains slashes ("/"), the program at the exact
location will be executed.
- else PATH will be used to search for the binary
argv array of pointers to arguments
The char *const argv[] argument is an array of pointers to null-terminated
strings that represent the argument list available to the new program.
The first argument, by convention, should point to the filename associated with
the file being executed. The array of pointers must be terminated by a null pointer.
pstdout_redir pointer to name of file to redirect stdout to
- if file name is empty, a temporary name will be created
- no redirection if NULL
stderr_redir name of file to redirect stderr to
- no redirection if NULL
returns: -1 on errors
any other returncode of the called process
*/

/* this code is currently used to spawn sub processes in:
src/zfile.c
src/arch/gtk3/actions-help.c (fallback for gtk_show_uri_on_window)
*/
#include "vice.h"

#include "archdep_defs.h"
Expand Down Expand Up @@ -65,7 +92,7 @@
/* #define DEBUG_SPAWN */

#ifdef DEBUG_SPAWN
#define LOG(a) log_printf a
#define LOG(a) log_printf a
#else
#define LOG(a)
#endif
Expand All @@ -75,10 +102,12 @@
int archdep_spawn(const char *name, char **argv,
char **pstdout_redir, const char *stderr_redir)
{
pid_t pid;
pid_t child_pid;
int child_status;
int child_status = 0;
char *stdout_redir;

int stdout_errno = 0;
int stderr_errno = 0;

if (pstdout_redir != NULL) {
if (*pstdout_redir == NULL) {
Expand All @@ -89,35 +118,49 @@ int archdep_spawn(const char *name, char **argv,
stdout_redir = NULL;
}

child_pid = vfork();
log_message(LOG_DEFAULT, "Spawn: forking process '%s'", name);
child_pid = fork();
if (child_pid < 0) {
log_error(LOG_DEFAULT, "vfork() failed: %s.", strerror(errno));
log_error(LOG_DEFAULT, "fork() failed: %s.", strerror(errno));
return -1;
} else {
if (child_pid == 0) {
int res;
/* child - CAUTION: log system does not work here */
if (stdout_redir && freopen(stdout_redir, "w", stdout) == NULL) {
log_error(LOG_DEFAULT, "freopen(\"%s\") failed: %s.", stdout_redir, strerror(errno));
stdout_errno = errno;
_exit(-1);
}
if (stderr_redir && freopen(stderr_redir, "w", stderr) == NULL) {
log_error(LOG_DEFAULT, "freopen(\"%s\") failed: %s.", stderr_redir, strerror(errno));
stderr_errno = errno;
_exit(-1);
}
execvp(name, argv);
res = execvp(name, argv);
/* execvp should never return, except when there was some error */
_exit(-1);
}
}

if (waitpid(child_pid, &child_status, 0) != child_pid) {
log_error(LOG_DEFAULT, "waitpid() failed: %s", strerror(errno));
/* wait for the child to finish */
if ((pid = waitpid(child_pid, &child_status, 0)) != child_pid) {
log_error(LOG_DEFAULT, "waitpid(%d) got pid %d (%d): %s",
child_pid, pid, errno, strerror(errno));
return -1;
}

/* output the log messages in parent context */
if (stdout_errno) {
log_error(LOG_DEFAULT, "freopen(\"%s\") failed: %s.", stdout_redir, strerror(stdout_errno));
}
if (stderr_errno) {
log_error(LOG_DEFAULT, "freopen(\"%s\") failed: %s.", stderr_redir, strerror(stderr_errno));
}

LOG(("WIFEXITED(child_status):%d", WIFEXITED(child_status)));
if (WIFEXITED(child_status)) {
return WEXITSTATUS(child_status);
} else {
return -1;
}
return -1;
}

#elif defined(WINDOWS_COMPILE)
Expand Down

0 comments on commit a44d2d2

Please sign in to comment.