Add ioctl-based AFS calls for Solaris 11
[openafs.git] / src / sys / glue.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  *
9  * This file contains any necessary C glue to allow programs to communicate
10  * with the AFS kernel module.  The necessary lower-level glue is defined in
11  * syscall.s.
12  */
13
14 #include <afsconfig.h>
15 #include <afs/param.h>
16
17
18 #include <afs/afs_args.h>
19 #include <sys/file.h>
20 #include <sys/ioctl.h>
21 #include <unistd.h>
22 #include <stdio.h>
23 #include <errno.h>
24 #ifdef AFS_SUN5_ENV
25 #include <fcntl.h>
26 #endif
27 #include "afssyscalls.h"
28
29 #ifdef AFS_LINUX20_ENV
30 int proc_afs_syscall(long syscall, long param1, long param2, long param3,
31                      long param4, int *rval) {
32     struct afsprocdata syscall_data;
33     int fd = open(PROC_SYSCALL_FNAME, O_RDWR);
34     if(fd < 0)
35         fd = open(PROC_SYSCALL_ARLA_FNAME, O_RDWR);
36     if(fd < 0)
37         return -1;
38
39     syscall_data.syscall = syscall;
40     syscall_data.param1 = param1;
41     syscall_data.param2 = param2;
42     syscall_data.param3 = param3;
43     syscall_data.param4 = param4;
44
45     *rval = ioctl(fd, VIOC_SYSCALL, &syscall_data);
46
47     close(fd);
48
49     /* Callers expect us to emulate a syscall - return -1 on error, set errno */
50     if (*rval) {
51         errno = *rval;
52         *rval =  -1;
53     }
54     return 0;
55 }
56 #endif
57
58 #if defined(AFS_DARWIN80_ENV)
59 int ioctl_afs_syscall(long syscall, long param1, long param2, long param3,
60                       long param4, long param5, long param6, int *rval) {
61     struct afssysargs syscall_data;
62     void *ioctldata;
63     int code;
64     int fd = open(SYSCALL_DEV_FNAME, O_RDWR);
65     int syscallnum;
66 #ifdef AFS_DARWIN100_ENV
67     struct afssysargs64 syscall64_data;
68     if (sizeof(param1) == 8) {
69         syscallnum = VIOC_SYSCALL64;
70         ioctldata = &syscall64_data;
71         syscall64_data.syscall = (int)syscall;
72         syscall64_data.param1 = param1;
73         syscall64_data.param2 = param2;
74         syscall64_data.param3 = param3;
75         syscall64_data.param4 = param4;
76         syscall64_data.param5 = param5;
77         syscall64_data.param6 = param6;
78     } else {
79 #endif
80         syscallnum = VIOC_SYSCALL;
81         ioctldata = &syscall_data;
82         syscall_data.syscall = syscall;
83         syscall_data.param1 = param1;
84         syscall_data.param2 = param2;
85         syscall_data.param3 = param3;
86         syscall_data.param4 = param4;
87         syscall_data.param5 = param5;
88         syscall_data.param6 = param6;
89 #ifdef AFS_DARWIN100_ENV
90     }
91 #endif
92     if(fd >= 0) {
93         code = ioctl(fd, syscallnum, ioctldata);
94         close(fd);
95     } else
96         code = -1;
97
98     if (code)
99         return code;
100 #ifdef AFS_DARWIN100_ENV
101     if (sizeof(param1) == 8)
102         *rval=syscall64_data.retval;
103     else
104 #endif
105         *rval=syscall_data.retval;
106     return 0;
107 }
108 #endif
109
110 #ifdef AFS_SUN511_ENV
111 int
112 ioctl_sun_afs_syscall(long syscall, uintptr_t param1, uintptr_t param2,
113                       uintptr_t param3, uintptr_t param4, uintptr_t param5,
114                       uintptr_t param6, int *error)
115 {
116     void *ioctldata;
117     long callnum;
118     int fd, code;
119
120 # ifdef _ILP32
121     struct afssysargs32 sargs32;
122     sargs32.syscall = syscall;
123     sargs32.param1 = param1;
124     sargs32.param2 = param2;
125     sargs32.param3 = param3;
126     sargs32.param4 = param4;
127     sargs32.param5 = param5;
128     sargs32.param6 = param6;
129
130     ioctldata = &sargs32;
131     callnum = VIOC_SYSCALL32;
132 # else /* _ILP32 */
133     struct afssysargs sargs;
134     sargs.syscall = syscall;
135     sargs.param1 = param1;
136     sargs.param2 = param2;
137     sargs.param3 = param3;
138     sargs.param4 = param4;
139     sargs.param5 = param5;
140     sargs.param6 = param6;
141
142     ioctldata = &sargs;
143     callnum = VIOC_SYSCALL;
144 # endif /* !_ILP32 */
145
146     fd = open(SYSCALL_DEV_FNAME, O_RDWR);
147     if (fd < 0) {
148         return -1;
149     }
150
151     *error = 0;
152
153     code = ioctl(fd, callnum, ioctldata);
154     close(fd);
155
156     if (code) {
157         errno = code;
158         *error = code;
159     }
160
161     return 0;
162 }
163 #endif /* AFS_SUN511_ENV */