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