Whamcloud - gitweb
add some real userspace definitions for CDEBUG et al
[fs/lustre-release.git] / lnet / libcfs / darwin / darwin-utils.c
1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=8:tabstop=8:
3  *
4  * Copyright (C) 2002 Cluster File Systems, Inc.
5  * Author: Phil Schwan <phil@clusterfs.com>
6  *
7  * This file is part of Lustre, http://www.lustre.org.
8  *
9  * Lustre is free software; you can redistribute it and/or
10  * modify it under the terms of version 2 of the GNU General Public
11  * License as published by the Free Software Foundation.
12  *
13  * Lustre is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with Lustre; if not, write to the Free Software
20  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  *
22  * Darwin porting library
23  * Make things easy to port
24  */
25 #define DEBUG_SUBSYSTEM S_PORTALS
26
27 #include <mach/mach_types.h>
28 #include <string.h>
29 #include <sys/errno.h>
30 #include <sys/types.h>
31 #include <sys/fcntl.h>
32 #include <portals/types.h>
33
34 #ifndef isspace
35 inline int
36 isspace(char c)
37
38         return (c == ' ' || c == '\t' || c == '\n' || c == '\12');
39 }
40 #endif
41
42 char * strpbrk(const char * cs,const char * ct)
43 {
44         const char *sc1,*sc2;
45         
46         for( sc1 = cs; *sc1 != '\0'; ++sc1) {
47                 for( sc2 = ct; *sc2 != '\0'; ++sc2) {
48                         if (*sc1 == *sc2)
49                                 return (char *) sc1;
50                 }
51         }
52         return NULL;
53 }
54
55 char * strsep(char **s, const char *ct)
56 {
57         char *sbegin = *s, *end;
58         
59         if (sbegin == NULL)
60                 return NULL;
61         end = strpbrk(sbegin, ct);
62         if (end != NULL)
63                 *end++ = '\0';
64         *s = end;
65
66         return sbegin;
67 }
68
69 size_t strnlen(const char * s, size_t count)
70 {
71         const char *sc;
72
73         for (sc = s; count-- && *sc != '\0'; ++sc)
74                 /* nothing */;
75         return sc - s;
76 }
77
78 char *
79 strstr(const char *in, const char *str)
80 {
81         char c;
82         size_t len;
83         
84         c = *str++;
85         if (!c)
86                 return (char *) in;     // Trivial empty string case
87         len = strlen(str);
88         do {
89                 char sc;
90                 do {
91                         sc = *in++;
92                         if (!sc)
93                                 return (char *) 0;
94                 } while (sc != c);
95         } while (strncmp(in, str, len) != 0);
96         return (char *) (in - 1);
97 }
98
99 char *
100 strrchr(const char *p, int ch)
101
102         const char *end = p + strlen(p); 
103         do { 
104                 if (*end == (char)ch) 
105                         return (char *)end; 
106         } while (--end >= p); 
107         return NULL;
108 }
109
110 char *
111 ul2dstr(unsigned long address, char *buf, int len)
112 {
113         char *pos = buf + len - 1;
114
115         if (len <= 0 || !buf)
116                 return NULL;
117         *pos = 0;
118         while (address) {
119                 if (!--len) break;
120                 *--pos = address % 10 + '0';
121                 address /= 10;
122         }
123         return pos;
124 }
125
126 /*
127  * miscellaneous libcfs stuff
128  */
129
130 /*
131  * Convert server error code to client format.
132  * Linux errno.h.
133  */
134
135 /* obtained by
136  *
137  *     cc /usr/include/asm/errno.h -E -dM | grep '#define E' | sort -n -k3,3
138  *
139  */
140 enum linux_errnos {
141         LINUX_EPERM              = 1,
142         LINUX_ENOENT             = 2,
143         LINUX_ESRCH              = 3,
144         LINUX_EINTR              = 4,
145         LINUX_EIO                = 5,
146         LINUX_ENXIO              = 6,
147         LINUX_E2BIG              = 7,
148         LINUX_ENOEXEC            = 8,
149         LINUX_EBADF              = 9,
150         LINUX_ECHILD             = 10,
151         LINUX_EAGAIN             = 11,
152         LINUX_ENOMEM             = 12,
153         LINUX_EACCES             = 13,
154         LINUX_EFAULT             = 14,
155         LINUX_ENOTBLK            = 15,
156         LINUX_EBUSY              = 16,
157         LINUX_EEXIST             = 17,
158         LINUX_EXDEV              = 18,
159         LINUX_ENODEV             = 19,
160         LINUX_ENOTDIR            = 20,
161         LINUX_EISDIR             = 21,
162         LINUX_EINVAL             = 22,
163         LINUX_ENFILE             = 23,
164         LINUX_EMFILE             = 24,
165         LINUX_ENOTTY             = 25,
166         LINUX_ETXTBSY            = 26,
167         LINUX_EFBIG              = 27,
168         LINUX_ENOSPC             = 28,
169         LINUX_ESPIPE             = 29,
170         LINUX_EROFS              = 30,
171         LINUX_EMLINK             = 31,
172         LINUX_EPIPE              = 32,
173         LINUX_EDOM               = 33,
174         LINUX_ERANGE             = 34,
175         LINUX_EDEADLK            = 35,
176         LINUX_ENAMETOOLONG       = 36,
177         LINUX_ENOLCK             = 37,
178         LINUX_ENOSYS             = 38,
179         LINUX_ENOTEMPTY          = 39,
180         LINUX_ELOOP              = 40,
181         LINUX_ENOMSG             = 42,
182         LINUX_EIDRM              = 43,
183         LINUX_ECHRNG             = 44,
184         LINUX_EL2NSYNC           = 45,
185         LINUX_EL3HLT             = 46,
186         LINUX_EL3RST             = 47,
187         LINUX_ELNRNG             = 48,
188         LINUX_EUNATCH            = 49,
189         LINUX_ENOCSI             = 50,
190         LINUX_EL2HLT             = 51,
191         LINUX_EBADE              = 52,
192         LINUX_EBADR              = 53,
193         LINUX_EXFULL             = 54,
194         LINUX_ENOANO             = 55,
195         LINUX_EBADRQC            = 56,
196         LINUX_EBADSLT            = 57,
197         LINUX_EBFONT             = 59,
198         LINUX_ENOSTR             = 60,
199         LINUX_ENODATA            = 61,
200         LINUX_ETIME              = 62,
201         LINUX_ENOSR              = 63,
202         LINUX_ENONET             = 64,
203         LINUX_ENOPKG             = 65,
204         LINUX_EREMOTE            = 66,
205         LINUX_ENOLINK            = 67,
206         LINUX_EADV               = 68,
207         LINUX_ESRMNT             = 69,
208         LINUX_ECOMM              = 70,
209         LINUX_EPROTO             = 71,
210         LINUX_EMULTIHOP          = 72,
211         LINUX_EDOTDOT            = 73,
212         LINUX_EBADMSG            = 74,
213         LINUX_EOVERFLOW          = 75,
214         LINUX_ENOTUNIQ           = 76,
215         LINUX_EBADFD             = 77,
216         LINUX_EREMCHG            = 78,
217         LINUX_ELIBACC            = 79,
218         LINUX_ELIBBAD            = 80,
219         LINUX_ELIBSCN            = 81,
220         LINUX_ELIBMAX            = 82,
221         LINUX_ELIBEXEC           = 83,
222         LINUX_EILSEQ             = 84,
223         LINUX_ERESTART           = 85,
224         LINUX_ESTRPIPE           = 86,
225         LINUX_EUSERS             = 87,
226         LINUX_ENOTSOCK           = 88,
227         LINUX_EDESTADDRREQ       = 89,
228         LINUX_EMSGSIZE           = 90,
229         LINUX_EPROTOTYPE         = 91,
230         LINUX_ENOPROTOOPT        = 92,
231         LINUX_EPROTONOSUPPORT    = 93,
232         LINUX_ESOCKTNOSUPPORT    = 94,
233         LINUX_EOPNOTSUPP         = 95,
234         LINUX_EPFNOSUPPORT       = 96,
235         LINUX_EAFNOSUPPORT       = 97,
236         LINUX_EADDRINUSE         = 98,
237         LINUX_EADDRNOTAVAIL      = 99,
238         LINUX_ENETDOWN           = 100,
239         LINUX_ENETUNREACH        = 101,
240         LINUX_ENETRESET          = 102,
241         LINUX_ECONNABORTED       = 103,
242         LINUX_ECONNRESET         = 104,
243         LINUX_ENOBUFS            = 105,
244         LINUX_EISCONN            = 106,
245         LINUX_ENOTCONN           = 107,
246         LINUX_ESHUTDOWN          = 108,
247         LINUX_ETOOMANYREFS       = 109,
248         LINUX_ETIMEDOUT          = 110,
249         LINUX_ECONNREFUSED       = 111,
250         LINUX_EHOSTDOWN          = 112,
251         LINUX_EHOSTUNREACH       = 113,
252         LINUX_EALREADY           = 114,
253         LINUX_EINPROGRESS        = 115,
254         LINUX_ESTALE             = 116,
255         LINUX_EUCLEAN            = 117,
256         LINUX_ENOTNAM            = 118,
257         LINUX_ENAVAIL            = 119,
258         LINUX_EISNAM             = 120,
259         LINUX_EREMOTEIO          = 121,
260         LINUX_EDQUOT             = 122,
261         LINUX_ENOMEDIUM          = 123,
262         LINUX_EMEDIUMTYPE        = 124,
263
264         /*
265          * we don't need these, but for completeness..
266          */
267         LINUX_EDEADLOCK          = LINUX_EDEADLK,
268         LINUX_EWOULDBLOCK        = LINUX_EAGAIN
269 };
270
271 int convert_server_error(__u64 ecode)
272 {
273         int sign;
274         int code;
275
276         static int errno_xlate[] = {
277                 /* success is always success */
278                 [0]                     = 0,
279                 [LINUX_EPERM]           = EPERM,
280                 [LINUX_ENOENT]          = ENOENT,
281                 [LINUX_ESRCH]           = ESRCH,
282                 [LINUX_EINTR]           = EINTR,
283                 [LINUX_EIO]             = EIO,
284                 [LINUX_ENXIO]           = ENXIO,
285                 [LINUX_E2BIG]           = E2BIG,
286                 [LINUX_ENOEXEC]         = ENOEXEC,
287                 [LINUX_EBADF]           = EBADF,
288                 [LINUX_ECHILD]          = ECHILD,
289                 [LINUX_EAGAIN]          = EAGAIN,
290                 [LINUX_ENOMEM]          = ENOMEM,
291                 [LINUX_EACCES]          = EACCES,
292                 [LINUX_EFAULT]          = EFAULT,
293                 [LINUX_ENOTBLK]         = ENOTBLK,
294                 [LINUX_EBUSY]           = EBUSY,
295                 [LINUX_EEXIST]          = EEXIST,
296                 [LINUX_EXDEV]           = EXDEV,
297                 [LINUX_ENODEV]          = ENODEV,
298                 [LINUX_ENOTDIR]         = ENOTDIR,
299                 [LINUX_EISDIR]          = EISDIR,
300                 [LINUX_EINVAL]          = EINVAL,
301                 [LINUX_ENFILE]          = ENFILE,
302                 [LINUX_EMFILE]          = EMFILE,
303                 [LINUX_ENOTTY]          = ENOTTY,
304                 [LINUX_ETXTBSY]         = ETXTBSY,
305                 [LINUX_EFBIG]           = EFBIG,
306                 [LINUX_ENOSPC]          = ENOSPC,
307                 [LINUX_ESPIPE]          = ESPIPE,
308                 [LINUX_EROFS]           = EROFS,
309                 [LINUX_EMLINK]          = EMLINK,
310                 [LINUX_EPIPE]           = EPIPE,
311                 [LINUX_EDOM]            = EDOM,
312                 [LINUX_ERANGE]          = ERANGE,
313                 [LINUX_EDEADLK]         = EDEADLK,
314                 [LINUX_ENAMETOOLONG]    = ENAMETOOLONG,
315                 [LINUX_ENOLCK]          = ENOLCK,
316                 [LINUX_ENOSYS]          = ENOSYS,
317                 [LINUX_ENOTEMPTY]       = ENOTEMPTY,
318                 [LINUX_ELOOP]           = ELOOP,
319                 [LINUX_ENOMSG]          = ENOMSG,
320                 [LINUX_EIDRM]           = EIDRM,
321                 [LINUX_ECHRNG]          = EINVAL /* ECHRNG */,
322                 [LINUX_EL2NSYNC]        = EINVAL /* EL2NSYNC */,
323                 [LINUX_EL3HLT]          = EINVAL /* EL3HLT */,
324                 [LINUX_EL3RST]          = EINVAL /* EL3RST */,
325                 [LINUX_ELNRNG]          = EINVAL /* ELNRNG */,
326                 [LINUX_EUNATCH]         = EINVAL /* EUNATCH */,
327                 [LINUX_ENOCSI]          = EINVAL /* ENOCSI */,
328                 [LINUX_EL2HLT]          = EINVAL /* EL2HLT */,
329                 [LINUX_EBADE]           = EINVAL /* EBADE */,
330                 [LINUX_EBADR]           = EBADRPC,
331                 [LINUX_EXFULL]          = EINVAL /* EXFULL */,
332                 [LINUX_ENOANO]          = EINVAL /* ENOANO */,
333                 [LINUX_EBADRQC]         = EINVAL /* EBADRQC */,
334                 [LINUX_EBADSLT]         = EINVAL /* EBADSLT */,
335                 [LINUX_EBFONT]          = EINVAL /* EBFONT */,
336                 [LINUX_ENOSTR]          = EINVAL /* ENOSTR */,
337                 [LINUX_ENODATA]         = EINVAL /* ENODATA */,
338                 [LINUX_ETIME]           = EINVAL /* ETIME */,
339                 [LINUX_ENOSR]           = EINVAL /* ENOSR */,
340                 [LINUX_ENONET]          = EINVAL /* ENONET */,
341                 [LINUX_ENOPKG]          = EINVAL /* ENOPKG */,
342                 [LINUX_EREMOTE]         = EREMOTE,
343                 [LINUX_ENOLINK]         = EINVAL /* ENOLINK */,
344                 [LINUX_EADV]            = EINVAL /* EADV */,
345                 [LINUX_ESRMNT]          = EINVAL /* ESRMNT */,
346                 [LINUX_ECOMM]           = EINVAL /* ECOMM */,
347                 [LINUX_EPROTO]          = EPROTOTYPE,
348                 [LINUX_EMULTIHOP]       = EINVAL /* EMULTIHOP */,
349                 [LINUX_EDOTDOT]         = EINVAL /* EDOTDOT */,
350                 [LINUX_EBADMSG]         = EINVAL /* EBADMSG */,
351                 [LINUX_EOVERFLOW]       = EOVERFLOW,
352                 [LINUX_ENOTUNIQ]        = EINVAL /* ENOTUNIQ */,
353                 [LINUX_EBADFD]          = EINVAL /* EBADFD */,
354                 [LINUX_EREMCHG]         = EINVAL /* EREMCHG */,
355                 [LINUX_ELIBACC]         = EINVAL /* ELIBACC */,
356                 [LINUX_ELIBBAD]         = EINVAL /* ELIBBAD */,
357                 [LINUX_ELIBSCN]         = EINVAL /* ELIBSCN */,
358                 [LINUX_ELIBMAX]         = EINVAL /* ELIBMAX */,
359                 [LINUX_ELIBEXEC]        = EINVAL /* ELIBEXEC */,
360                 [LINUX_EILSEQ]          = EILSEQ,
361                 [LINUX_ERESTART]        = ERESTART,
362                 [LINUX_ESTRPIPE]        = EINVAL /* ESTRPIPE */,
363                 [LINUX_EUSERS]          = EUSERS,
364                 [LINUX_ENOTSOCK]        = ENOTSOCK,
365                 [LINUX_EDESTADDRREQ]    = EDESTADDRREQ,
366                 [LINUX_EMSGSIZE]        = EMSGSIZE,
367                 [LINUX_EPROTOTYPE]      = EPROTOTYPE,
368                 [LINUX_ENOPROTOOPT]     = ENOPROTOOPT,
369                 [LINUX_EPROTONOSUPPORT] = EPROTONOSUPPORT,
370                 [LINUX_ESOCKTNOSUPPORT] = ESOCKTNOSUPPORT,
371                 [LINUX_EOPNOTSUPP]      = EOPNOTSUPP,
372                 [LINUX_EPFNOSUPPORT]    = EPFNOSUPPORT,
373                 [LINUX_EAFNOSUPPORT]    = EAFNOSUPPORT,
374                 [LINUX_EADDRINUSE]      = EADDRINUSE,
375                 [LINUX_EADDRNOTAVAIL]   = EADDRNOTAVAIL,
376                 [LINUX_ENETDOWN]        = ENETDOWN,
377                 [LINUX_ENETUNREACH]     = ENETUNREACH,
378                 [LINUX_ENETRESET]       = ENETRESET,
379                 [LINUX_ECONNABORTED]    = ECONNABORTED,
380                 [LINUX_ECONNRESET]      = ECONNRESET,
381                 [LINUX_ENOBUFS]         = ENOBUFS,
382                 [LINUX_EISCONN]         = EISCONN,
383                 [LINUX_ENOTCONN]        = ENOTCONN,
384                 [LINUX_ESHUTDOWN]       = ESHUTDOWN,
385                 [LINUX_ETOOMANYREFS]    = ETOOMANYREFS,
386                 [LINUX_ETIMEDOUT]       = ETIMEDOUT,
387                 [LINUX_ECONNREFUSED]    = ECONNREFUSED,
388                 [LINUX_EHOSTDOWN]       = EHOSTDOWN,
389                 [LINUX_EHOSTUNREACH]    = EHOSTUNREACH,
390                 [LINUX_EALREADY]        = EALREADY,
391                 [LINUX_EINPROGRESS]     = EINPROGRESS,
392                 [LINUX_ESTALE]          = ESTALE,
393                 [LINUX_EUCLEAN]         = EINVAL /* EUCLEAN */,
394                 [LINUX_ENOTNAM]         = EINVAL /* ENOTNAM */,
395                 [LINUX_ENAVAIL]         = EINVAL /* ENAVAIL */,
396                 [LINUX_EISNAM]          = EINVAL /* EISNAM */,
397                 [LINUX_EREMOTEIO]       = EINVAL /* EREMOTEIO */,
398                 [LINUX_EDQUOT]          = EDQUOT,
399                 [LINUX_ENOMEDIUM]       = EINVAL /* ENOMEDIUM */,
400                 [LINUX_EMEDIUMTYPE]     = EINVAL /* EMEDIUMTYPE */,
401         };
402         code = (int)ecode;
403         if (code >= 0) {
404                 sign = +1;
405         } else {
406                 sign = -1;
407                 code = -code;
408         }
409         if (code < (sizeof errno_xlate) / (sizeof errno_xlate[0]))
410                 code = errno_xlate[code];
411         else
412                 /*
413                  * Unknown error. Reserved for the future.
414                  */
415                 code = EINVAL;
416         return sign * code;
417 }
418
419 enum {
420         LINUX_O_RDONLY   =           00,
421         LINUX_O_WRONLY   =           01,
422         LINUX_O_RDWR     =           02,
423         LINUX_O_CREAT    =         0100,
424         LINUX_O_EXCL     =         0200,
425         LINUX_O_NOCTTY   =         0400,
426         LINUX_O_TRUNC    =        01000,
427         LINUX_O_APPEND   =        02000,
428         LINUX_O_NONBLOCK =        04000,
429         LINUX_O_NDELAY   =             LINUX_O_NONBLOCK,
430         LINUX_O_SYNC     =       010000,
431         LINUX_O_FSYNC    =             LINUX_O_SYNC,
432         LINUX_O_ASYNC    =       020000,
433         LINUX_O_DIRECT   =       040000,
434         LINUX_O_NOFOLLOW =      0400000
435 };
436
437 static inline void obit_convert(int *cflag, int *sflag,
438                                 unsigned cmask, unsigned smask)
439 {
440         if (*cflag & cmask != 0) {
441                 *sflag |= smask;
442                 *cflag &= ~cmask;
443         }
444 }
445
446 /*
447  * convert <fcntl.h> flag from XNU client to Linux _i386_ server.
448  */
449 int convert_client_oflag(int cflag, int *result)
450 {
451         int sflag;
452
453         cflag = 0;
454         obit_convert(&cflag, &sflag, O_RDONLY,   LINUX_O_RDONLY);
455         obit_convert(&cflag, &sflag, O_WRONLY,   LINUX_O_WRONLY);
456         obit_convert(&cflag, &sflag, O_RDWR,     LINUX_O_RDWR);
457         obit_convert(&cflag, &sflag, O_NONBLOCK, LINUX_O_NONBLOCK);
458         obit_convert(&cflag, &sflag, O_APPEND,   LINUX_O_APPEND);
459         obit_convert(&cflag, &sflag, O_ASYNC,    LINUX_O_ASYNC);
460         obit_convert(&cflag, &sflag, O_FSYNC,    LINUX_O_FSYNC);
461         obit_convert(&cflag, &sflag, O_NOFOLLOW, LINUX_O_NOFOLLOW);
462         obit_convert(&cflag, &sflag, O_CREAT,    LINUX_O_CREAT);
463         obit_convert(&cflag, &sflag, O_TRUNC,    LINUX_O_TRUNC);
464         obit_convert(&cflag, &sflag, O_EXCL,     LINUX_O_EXCL);
465         obit_convert(&cflag, &sflag, O_CREAT,    LINUX_O_CREAT);
466         obit_convert(&cflag, &sflag, O_NDELAY,   LINUX_O_NDELAY);
467         obit_convert(&cflag, &sflag, O_NOCTTY,   LINUX_O_NOCTTY);
468         /*
469          * Some more obscure BSD flags have no Linux counterparts:
470          *
471          * O_SHLOCK     0x0010
472          * O_EXLOCK     0x0020
473          * O_EVTONLY    0x8000
474          * O_POPUP      0x80000000
475          * O_ALERT      0x20000000
476          */
477         if (cflag == 0) {
478                 *result = sflag;
479                 return 0;
480         } else
481                 return -EINVAL;
482 }