File: backwards_compat.c

package info (click to toggle)
module-init-tools 3.4-1
  • links: PTS
  • area: main
  • in suites: lenny
  • size: 2,208 kB
  • ctags: 900
  • sloc: sh: 7,980; ansic: 5,036; makefile: 204
file content (64 lines) | stat: -rw-r--r-- 1,754 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
/* 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 */