Revert "Linux: normalize error return for emulated syscalls"
[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 #ifdef AFS_SUN5_ENV
24 #include <fcntl.h>
25 #endif
26 #include "afssyscalls.h"
27
28 #ifdef AFS_LINUX20_ENV
29 int proc_afs_syscall(long syscall, long param1, long param2, long param3,
30                      long param4, int *rval) {
31   struct afsprocdata syscall_data;
32   int fd = open(PROC_SYSCALL_FNAME, O_RDWR);
33   if(fd < 0)
34       fd = open(PROC_SYSCALL_ARLA_FNAME, O_RDWR);
35   if(fd < 0)
36     return -1;
37
38   syscall_data.syscall = syscall;
39   syscall_data.param1 = param1;
40   syscall_data.param2 = param2;
41   syscall_data.param3 = param3;
42   syscall_data.param4 = param4;
43
44   *rval = ioctl(fd, VIOC_SYSCALL, &syscall_data);
45
46   close(fd);
47
48   return 0;
49 }
50 #endif
51
52 #if defined(AFS_DARWIN80_ENV)
53 int ioctl_afs_syscall(long syscall, long param1, long param2, long param3,
54                       long param4, long param5, long param6, int *rval) {
55     struct afssysargs syscall_data;
56     void *ioctldata;
57     int code;
58     int fd = open(SYSCALL_DEV_FNAME, O_RDWR);
59     int syscallnum;
60 #ifdef AFS_DARWIN100_ENV
61     struct afssysargs64 syscall64_data;
62     if (sizeof(param1) == 8) {
63         syscallnum = VIOC_SYSCALL64;
64         ioctldata = &syscall64_data;
65         syscall64_data.syscall = (int)syscall;
66         syscall64_data.param1 = param1;
67         syscall64_data.param2 = param2;
68         syscall64_data.param3 = param3;
69         syscall64_data.param4 = param4;
70         syscall64_data.param5 = param5;
71         syscall64_data.param6 = param6;
72     } else {
73 #endif
74         syscallnum = VIOC_SYSCALL;
75         ioctldata = &syscall_data;
76         syscall_data.syscall = syscall;
77         syscall_data.param1 = param1;
78         syscall_data.param2 = param2;
79         syscall_data.param3 = param3;
80         syscall_data.param4 = param4;
81         syscall_data.param5 = param5;
82         syscall_data.param6 = param6;
83 #ifdef AFS_DARWIN100_ENV
84     }
85 #endif
86     if(fd >= 0) {
87         code = ioctl(fd, syscallnum, ioctldata);
88         close(fd);
89     } else
90         code = -1;
91
92     if (code)
93         return code;
94 #ifdef AFS_DARWIN100_ENV
95     if (sizeof(param1) == 8)
96         *rval=syscall64_data.retval;
97     else
98 #endif
99         *rval=syscall_data.retval;
100     return 0;
101 }
102 #endif
103
104 #ifdef AFS_SUN511_ENV
105 int
106 ioctl_sun_afs_syscall(long syscall, uintptr_t param1, uintptr_t param2,
107                       uintptr_t param3, uintptr_t param4, uintptr_t param5,
108                       uintptr_t param6, int *error)
109 {
110     void *ioctldata;
111     long callnum;
112     int fd, code;
113
114 # ifdef _ILP32
115     struct afssysargs32 sargs32;
116     sargs32.syscall = syscall;
117     sargs32.param1 = param1;
118     sargs32.param2 = param2;
119     sargs32.param3 = param3;
120     sargs32.param4 = param4;
121     sargs32.param5 = param5;
122     sargs32.param6 = param6;
123
124     ioctldata = &sargs32;
125     callnum = VIOC_SYSCALL32;
126 # else /* _ILP32 */
127     struct afssysargs sargs;
128     sargs.syscall = syscall;
129     sargs.param1 = param1;
130     sargs.param2 = param2;
131     sargs.param3 = param3;
132     sargs.param4 = param4;
133     sargs.param5 = param5;
134     sargs.param6 = param6;
135
136     ioctldata = &sargs;
137     callnum = VIOC_SYSCALL;
138 # endif /* !_ILP32 */
139
140     fd = open(SYSCALL_DEV_FNAME, O_RDWR);
141     if (fd < 0) {
142         return -1;
143     }
144
145     *error = 0;
146
147     code = ioctl(fd, callnum, ioctldata);
148     close(fd);
149
150     if (code) {
151         errno = code;
152         *error = code;
153     }
154
155     return 0;
156 }
157 #endif /* AFS_SUN511_ENV */