blob: 45320cfffdfa40924293748b7fe805200a503131 [file] [log] [blame]
/* Simple backwards compat code to exec old version */
#ifndef CONFIG_NO_BACKWARDS_COMPAT
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <asm/unistd.h>
extern long create_module(const char *, size_t);
#include "testing.h"
static void exec_old(const char *progname, char *argv[])
{
char *sep;
pid_t pid;
char ascii_pid[32];
char pathname[strlen(argv[0])+1];
char oldname[strlen(progname) + strlen(argv[0]) + sizeof(".old")];
memset(pathname, 0, strlen(argv[0])+1);
sep = strrchr(argv[0], '/');
if (sep)
memcpy(pathname, argv[0], sep - argv[0]+1);
sprintf(oldname, "%s%s.old", pathname, progname);
/* Recursion detection: we need an env var since we can't
change argv[0] (as older modutils uses it to determine
behavior). We *can* recurse in the case of old-style
pre-install etc. commands, so make sure pid is exactly the
same. */
pid = getpid();
snprintf(ascii_pid, sizeof(ascii_pid), "%lu", (unsigned long)pid);
if (strcmp(getenv("MODULE_RECURSE") ?: "", ascii_pid) == 0) {
fprintf(stderr, "WARNING: %s: I am not the old version!\n",
oldname);
return;
}
setenv("MODULE_RECURSE", ascii_pid, 1);
execvp(oldname, argv);
fprintf(stderr,
"Kernel requires old %s, but couldn't run %s: %s\n",
progname, oldname, strerror(errno));
exit(2);
}
static void try_old_version(const char *progname, char *argv[])
{
errno = 0;
if (create_module(NULL, 0) >= 0 /* Uh oh, what have I just done? */
|| errno != ENOSYS)
exec_old(progname, argv);
}
#else /* CONFIG_NO_BACKWARDS_COMPAT */
static inline void try_old_version(const char *progname, char *argv[])
{
}
#endif /* !CONFIG_NO_BACKWARDS_COMPAT */