Support the new MacOS X 10.4 ioctl interface that is a device

node. Patched from Tomas Olson <tol@it.su.se>.


git-svn-id: svn://svn.h5l.se/heimdal/trunk/heimdal@16111 ec53bebd-3082-4978-b11e-865c3cabbd6b
This commit is contained in:
Love Hörnquist Åstrand
2005-10-01 02:55:55 +00:00
parent 5be5faa722
commit c9f13ad9b3

View File

@@ -1,5 +1,5 @@
/*
* Copyright (c) 1995 - 2000, 2002, 2004 Kungliga Tekniska H<>gskolan
* Copyright (c) 1995 - 2000, 2002, 2004, 2005 Kungliga Tekniska H<>gskolan
* (Royal Institute of Technology, Stockholm, Sweden).
* All rights reserved.
*
@@ -42,11 +42,24 @@ struct procdata {
unsigned long param1;
unsigned long syscall;
};
#define VIOC_SYSCALL _IOW('C', 1, void *)
#define VIOC_SYSCALL_PROC _IOW('C', 1, void *)
struct devdata {
unsigned long syscall;
unsigned long param1;
unsigned long param2;
unsigned long param3;
unsigned long param4;
unsigned long param5;
unsigned long param6;
unsigned long retval;
};
#define VIOC_SYSCALL_DEV _IOWR('C', 2, struct devdata)
int _kafs_debug; /* this should be done in a better way */
#define UNKNOWN_ENTRY_POINT (-1)
#define NO_ENTRY_POINT 0
#define SINGLE_ENTRY_POINT 1
#define MULTIPLE_ENTRY_POINT 2
@@ -54,10 +67,11 @@ int _kafs_debug; /* this should be done in a better way */
#define SINGLE_ENTRY_POINT3 4
#define LINUX_PROC_POINT 5
#define AIX_ENTRY_POINTS 6
#define UNKNOWN_ENTRY_POINT 7
#define MACOS_DEV_POINT 7
static int afs_entry_point = UNKNOWN_ENTRY_POINT;
static int afs_syscalls[2];
static char *afs_procpath;
static char *afs_ioctlpath;
/* Magic to get AIX syscalls to work */
#ifdef _AIX
@@ -148,30 +162,30 @@ map_syscall_name_to_number (const char *str, int *res)
#endif
static int
try_proc(const char *path)
try_ioctlpath(const char *path, int entrypoint)
{
int fd;
fd = open(path, O_RDWR);
if (fd < 0)
return 1;
close(fd);
afs_procpath = strdup(path);
if (afs_procpath == NULL)
afs_ioctlpath = strdup(path);
if (afs_ioctlpath == NULL)
return 1;
afs_entry_point = LINUX_PROC_POINT;
afs_entry_point = entrypoint;
return 0;
}
static int
do_proc(struct procdata *data)
do_ioctl(void *data, unsigned long cmd)
{
int fd, ret, saved_errno;
fd = open(afs_procpath, O_RDWR);
fd = open(afs_ioctlpath, O_RDWR);
if (fd < 0) {
errno = EINVAL;
return -1;
}
ret = ioctl(fd, VIOC_SYSCALL, data);
ret = ioctl(fd, cmd, data);
saved_errno = errno;
close(fd);
errno = saved_errno;
@@ -204,7 +218,22 @@ k_pioctl(char *a_path,
data.param2 = (unsigned long)o_opcode;
data.param3 = (unsigned long)a_paramsP;
data.param4 = (unsigned long)a_followSymlinks;
return do_proc(&data);
return do_ioctl(&data, VIOC_SYSCALL_PROC);
}
case MACOS_DEV_POINT: {
struct devdata data = { AFSCALL_PIOCTL, 0, 0, 0, 0, 0, 0, 0 };
int ret;
data.param1 = (unsigned long)a_path;
data.param2 = (unsigned long)o_opcode;
data.param3 = (unsigned long)a_paramsP;
data.param4 = (unsigned long)a_followSymlinks;
ret = do_ioctl(&data, VIOC_SYSCALL_DEV);
if (ret)
return ret;
return data.retval;
}
#ifdef _AIX
case AIX_ENTRY_POINTS:
@@ -255,8 +284,15 @@ k_setpag(void)
#endif
case LINUX_PROC_POINT: {
struct procdata data = { 0, 0, 0, 0, AFSCALL_SETPAG };
return do_proc(&data);
return do_ioctl(&data, VIOC_SYSCALL_PROC);
}
case MACOS_DEV_POINT: {
struct devdata data = { AFSCALL_SETPAG, 0, 0, 0, 0, 0, 0, 0 };
int ret = do_ioctl(&data, VIOC_SYSCALL_DEV);
if (ret)
return ret;
return data.retval;
}
#ifdef _AIX
case AIX_ENTRY_POINTS:
return Setpag();
@@ -343,7 +379,10 @@ k_hasafs(void)
RETSIGTYPE (*saved_func)(int);
#endif
int saved_errno;
char *env = getenv ("AFS_SYSCALL");
char *env = NULL;
if (!issuid())
env = getenv ("AFS_SYSCALL");
/*
* Already checked presence of AFS syscalls?
@@ -364,6 +403,13 @@ k_hasafs(void)
saved_func = signal(SIGSYS, SIGSYS_handler);
#endif
if (env && (strncmp("/dev/", env, 5) == 0 || strncmp("/proc/", env, 6) == 0)) {
if (try_ioctlpath(env, LINUX_PROC_POINT) == 0)
goto done;
if (try_ioctlpath(env, MACOS_DEV_POINT) == 0)
goto done;
}
#if defined(AFS_SYSCALL) || defined(AFS_SYSCALL2) || defined(AFS_SYSCALL3)
{
int tmp;
@@ -445,11 +491,14 @@ k_hasafs(void)
goto done;
#endif
if (try_proc("/proc/fs/openafs/afs_ioctl") == 0)
if (try_ioctlpath("/proc/fs/openafs/afs_ioctl", LINUX_PROC_POINT) == 0)
goto done;
if (try_proc("/proc/fs/nnpfs/afs_ioctl") == 0)
if (try_ioctlpath("/proc/fs/nnpfs/afs_ioctl", LINUX_PROC_POINT) == 0)
goto done;
if (env && try_proc(env) == 0)
if (try_ioctlpath("/dev/openafs_ioctl", MACOS_DEV_POINT) == 0)
goto done;
if (try_ioctlpath("/dev/nnpfs_ioctl", MACOS_DEV_POINT) == 0)
goto done;
done: