Import Upstream version 1.8.5
[hcoop/debian/openafs.git] / src / libuafs / ukernel_swig.i
CommitLineData
805e021f
CE
1/*
2 * Copyright 2010, Sine Nomine Associates.
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
10/*
11 * libuafs SWIG interface file
12 *
13 * This file specifies the libuafs interfaces for SWIG, which can then be
14 * used to easily create libuafs bindings to other languages such as Perl.
15 *
16 * For each language you want a binding for, there are two typemaps you
17 * must define for that language, since SWIG does not handle them natively.
18 * These are the 'in' typemap for READBUF and LENGTH, and the 'argout'
19 * typemap for READBUF. Search this file for 'SWIGPERL' to see existing ones
20 * for the Perl bindings.
21 */
22
23%module "AFS::ukernel"
24
25%{
26#include <afsconfig.h>
27#include <afs/param.h>
28
29#include <afs/afsutil.h>
30#include <afs/sysincludes.h>
31#include <afs_usrops.h>
32#include <afs/cmd.h>
33#include <afs/afs_args.h>
34%}
35
36%include "typemaps.i";
37
38%apply long { off_t };
39
40%rename (uafs_ParseArgs) swig_uafs_ParseArgs;
41%inline %{
42/* SWIG doesn't handle argv-like string arrays too well, so instead have
43 * a wrapper to convert a single string of all arguments into an argv-like
44 * array. Conveniently, libcmd can do this.
45 *
46 * We could instead do this with SWIG typemaps, but writing this little
47 * function instead is much more language-neutral. With typemaps, we'd have
48 * to write the converting code for each target language.
49 */
50extern int
51swig_uafs_ParseArgs(char *line)
52{
53 char *argv[1024];
54 int argc;
55 int code;
56
57 code = cmd_ParseLine(line, argv, &argc, sizeof(argv)/sizeof(argv[0]));
58 if (code) {
59 afs_com_err("AFS::ukernel", code, "parsing line: '%s'", line);
60 return code;
61 }
62
63 code = uafs_ParseArgs(argc, argv);
64
65 cmd_FreeArgv(argv);
66
67 return code;
68}
69%}
70extern int uafs_Setup(const char *mount);
71extern int uafs_Run(void);
72
73/*
74 * Define typemaps for binary read buffers. SWIG natively handles
75 * NUL-terminated strings, but uafs_read could have NULs in the middle of the
76 * string, so we need these typemaps to pay attention to the string length.
77 *
78 * (Reading in a binary buffer from e.g. uafs_write is already handled natively
79 * by SWIG. Fancy that.)
80 */
81#if defined(SWIGPERL)
82%typemap(in, numinputs=1) (char *READBUF, int LENGTH) {
83 if (!SvIOK($input)) {
84 SWIG_croak("expected an integer");
85 }
86 $2 = SvIV($input);
87 Newx($1, $2, char);
88}
89%typemap(argout, numinputs=1) char *READBUF {
90 /* some logic here copied from typemaps.i and/or SWIG itself, since I'm not
91 * a perl dev */
92
93 if (argvi >= items) {
94 EXTEND(sp, 1);
95 }
96
97 /* 'result' is the return value from the actual C function call; we assume
98 * it is an int that represents how many bytes of data were actually read into
99 * the buffer if nonnegative */
100 if (result < 0) {
101 $result = &PL_sv_undef;
102 } else {
103 $result = sv_2mortal(newSVpvn($1, result));
104 }
105
106 Safefree($1);
107 argvi++;
108}
109#else
110# error No READBUF typemap defined for the given language
111#endif
112
113extern int uafs_mkdir(char *path, int mode);
114extern int uafs_chdir(char *path);
115extern int uafs_open(char *path, int flags, int mode=0);
116extern int uafs_creat(char *path, int mode);
117extern int uafs_write(int fd, char *STRING, int LENGTH);
118extern int uafs_pwrite(int fd, char *STRING, int LENGTH, off_t offset);
119extern int uafs_read(int fd, char *READBUF, int LENGTH);
120extern int uafs_pread(int fd, char *READBUF, int LENGTH, off_t offset);
121extern int uafs_fsync(int fd);
122extern int uafs_close(int fd);
123
124%{
125#define STAT_TYPE long
126#define STAT_ARGS \
127 STAT_TYPE *adev, \
128 STAT_TYPE *aino, \
129 STAT_TYPE *amode, \
130 STAT_TYPE *anlink, \
131 STAT_TYPE *auid, \
132 STAT_TYPE *agid, \
133 STAT_TYPE *ardev, \
134 STAT_TYPE *asize, \
135 STAT_TYPE *aatime, \
136 STAT_TYPE *amtime, \
137 STAT_TYPE *actime, \
138 STAT_TYPE *ablksize, \
139 STAT_TYPE *ablocks
140
141#define STAT_COPYFROM(st) do { \
142 *adev = (st).st_dev; \
143 *aino = (st).st_ino; \
144 *amode = (st).st_mode; \
145 *anlink = (st).st_nlink; \
146 *auid = (st).st_uid; \
147 *agid = (st).st_gid; \
148 *ardev = (st).st_rdev; \
149 *asize = (st).st_size; \
150 *aatime = (st).st_atime; \
151 *amtime = (st).st_mtime; \
152 *actime = (st).st_ctime; \
153 *ablksize = (st).st_blksize; \
154 *ablocks = (st).st_blocks; \
155} while (0)
156
157int
158swig_uafs_stat(char *path, STAT_ARGS)
159{
160 int code;
161 struct stat st;
162 code = uafs_stat(path, &st);
163 if (code == 0) {
164 STAT_COPYFROM(st);
165 }
166 return code;
167}
168int
169swig_uafs_lstat(char *path, STAT_ARGS)
170{
171 int code;
172 struct stat st;
173 code = uafs_lstat(path, &st);
174 if (code == 0) {
175 STAT_COPYFROM(st);
176 }
177 return code;
178}
179int
180swig_uafs_fstat(int fd, STAT_ARGS)
181{
182 int code;
183 struct stat st;
184 code = uafs_fstat(fd, &st);
185 if (code == 0) {
186 STAT_COPYFROM(st);
187 }
188 return code;
189}
190
191#undef STAT_TYPE
192#undef STAT_ARGS
193#undef STAT_COPYFROM
194%}
195
196%define STAT_TYPE
197long
198%enddef
199%define STAT_OUT_ARGS
200STAT_TYPE *OUTPUT,
201STAT_TYPE *OUTPUT,
202STAT_TYPE *OUTPUT,
203STAT_TYPE *OUTPUT,
204STAT_TYPE *OUTPUT,
205STAT_TYPE *OUTPUT,
206STAT_TYPE *OUTPUT,
207STAT_TYPE *OUTPUT,
208STAT_TYPE *OUTPUT,
209STAT_TYPE *OUTPUT,
210STAT_TYPE *OUTPUT,
211STAT_TYPE *OUTPUT,
212STAT_TYPE *OUTPUT
213%enddef
214
215%rename (uafs_stat) swig_uafs_stat;
216%rename (uafs_lstat) swig_uafs_lstat;
217%rename (uafs_fstat) swig_uafs_fstat;
218
219extern int swig_uafs_stat(char *path, STAT_OUT_ARGS);
220extern int swig_uafs_lstat(char *path, STAT_OUT_ARGS);
221extern int swig_uafs_fstat(int fd, STAT_OUT_ARGS);
222
223extern int uafs_truncate(char *path, int len);
224extern int uafs_ftruncate(int fd, int len);
225extern int uafs_lseek(int fd, int offset, int whence);
226extern int uafs_chmod(char *path, int mode);
227extern int uafs_fchmod(int fd, int mode);
228extern int uafs_symlink(char *target, char *source);
229extern int uafs_unlink(char *path);
230extern int uafs_rmdir(char *path);
231extern int uafs_readlink(char *path, char *READBUF, int LENGTH);
232extern int uafs_link(char *existing, char *new);
233extern int uafs_rename(char *old, char *new);
234
235extern usr_DIR *uafs_opendir(char *path);
236
237%rename (uafs_readdir) swig_uafs_readdir;
238%{
239/*
240 * Language-neutral wrapper for uafs_readdir. Since the language won't know
241 * what to do with a struct usr_dirent, we could either make a SWIG typemap, or
242 * define a wrapper with multiple return arguments. Making a typemap is
243 * language-specific, so we define a wrapper, and let the typemaps.i library
244 * worry about the language-specific parts of getting multiple return values.
245 */
246char *
247swig_uafs_readdir(usr_DIR *dirp, unsigned long *d_ino, unsigned long *d_off, unsigned short *d_reclen)
248{
249 struct usr_dirent *dentry;
250
251 dentry = uafs_readdir(dirp);
252 if (!dentry) {
253 *d_ino = *d_off = *d_reclen = 0;
254 return NULL;
255 }
256
257 *d_ino = dentry->d_ino;
258 *d_off = dentry->d_off;
259 *d_reclen = dentry->d_reclen;
260
261 return strdup(dentry->d_name);
262}
263%}
264
265extern char * swig_uafs_readdir(usr_DIR *dirp, unsigned long *OUTPUT, unsigned long *OUTPUT, unsigned short *OUTPUT);
266extern int uafs_closedir(usr_DIR * dirp);
267extern void uafs_SetRxPort(int);
268extern void uafs_Shutdown(void);