~ubuntu-branches/debian/jessie/banshee-community-extensions/jessie

« back to all changes in this revision

Viewing changes to .pc/0001-Use-DBus-instead-of-NDesk.DBus.patch/src/Telepathy/Banshee.Telepathy/NDesk.DBus/Unix.cs

  • Committer: Package Import Robot
  • Author(s): Chow Loong Jin
  • Date: 2011-09-20 18:45:46 UTC
  • mfrom: (1.2.9 upstream) (5.1.8 experimental)
  • Revision ID: package-import@ubuntu.com-20110920184546-3ahue2qplydc4t0e
Tags: 2.2.0-1
* [4940fab] Imported Upstream version 2.2.0
  + Notable bug fixes:
    - Karaoke: Fix crash when switching to Now Playing
    - Lyrics: Fix crash when switching to Now Playing

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
// Copyright 2008 Alp Toker <alp@atoker.com>
2
 
// This software is made available under the MIT License
3
 
// See COPYING for details
4
 
 
5
 
using System;
6
 
using System.IO;
7
 
using System.Runtime.InteropServices;
8
 
 
9
 
namespace NDesk.Unix
10
 
{
11
 
        // size_t
12
 
        using SizeT = System.UIntPtr;
13
 
        // ssize_t
14
 
        using SSizeT = System.IntPtr;
15
 
        // socklen_t: assumed to be 4 bytes
16
 
        // uid_t: assumed to be 4 bytes
17
 
 
18
 
        sealed class UnixStream : Stream //, IDisposable
19
 
        {
20
 
                public readonly UnixSocket usock;
21
 
 
22
 
                public UnixStream (int fd)
23
 
                {
24
 
                        this.usock = new UnixSocket (fd);
25
 
                }
26
 
 
27
 
                public UnixStream (UnixSocket usock)
28
 
                {
29
 
                        this.usock = usock;
30
 
                }
31
 
 
32
 
                public override bool CanRead
33
 
                {
34
 
                        get {
35
 
                                return true;
36
 
                        }
37
 
                }
38
 
 
39
 
                public override bool CanSeek
40
 
                {
41
 
                        get {
42
 
                                return false;
43
 
                        }
44
 
                }
45
 
 
46
 
                public override bool CanWrite
47
 
                {
48
 
                        get {
49
 
                                return true;
50
 
                        }
51
 
                }
52
 
 
53
 
                public override long Length
54
 
                {
55
 
                        get {
56
 
                                throw new NotImplementedException ("Seeking is not implemented");
57
 
                        }
58
 
                }
59
 
 
60
 
                public override long Position
61
 
                {
62
 
                        get {
63
 
                                throw new NotImplementedException ("Seeking is not implemented");
64
 
                        } set {
65
 
                                throw new NotImplementedException ("Seeking is not implemented");
66
 
                        }
67
 
                }
68
 
 
69
 
                public override long Seek (long offset, SeekOrigin origin)
70
 
                {
71
 
                        throw new NotImplementedException ("Seeking is not implemented");
72
 
                }
73
 
 
74
 
                public override void SetLength (long value)
75
 
                {
76
 
                        throw new NotImplementedException ("Not implemented");
77
 
                }
78
 
 
79
 
                public override void Flush ()
80
 
                {
81
 
                }
82
 
 
83
 
                public override int Read ([In, Out] byte[] buffer, int offset, int count)
84
 
                {
85
 
                        return usock.Read (buffer, offset, count);
86
 
                }
87
 
 
88
 
                public override void Write (byte[] buffer, int offset, int count)
89
 
                {
90
 
                        usock.Write (buffer, offset, count);
91
 
                }
92
 
 
93
 
                unsafe public override int ReadByte ()
94
 
                {
95
 
                        byte value;
96
 
                        usock.Read (&value, 1);
97
 
                        return value;
98
 
                }
99
 
 
100
 
                unsafe public override void WriteByte (byte value)
101
 
                {
102
 
                        usock.Write (&value, 1);
103
 
                }
104
 
        }
105
 
 
106
 
        static class UnixUid
107
 
        {
108
 
                internal const string LIBC = "libc";
109
 
 
110
 
                [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=false)]
111
 
                static extern uint getuid ();
112
 
 
113
 
                [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=false)]
114
 
                static extern uint geteuid ();
115
 
 
116
 
                public static long GetUID ()
117
 
                {
118
 
                        long uid = getuid ();
119
 
                        return uid;
120
 
                }
121
 
 
122
 
                public static long GetEUID ()
123
 
                {
124
 
                        long euid = geteuid ();
125
 
                        return euid;
126
 
                }
127
 
        }
128
 
 
129
 
        static class UnixError
130
 
        {
131
 
                internal const string LIBC = "libc";
132
 
 
133
 
                [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=false)]
134
 
                static extern IntPtr strerror (int errnum);
135
 
 
136
 
                static string GetErrorString (int errnum)
137
 
                {
138
 
                        IntPtr strPtr = strerror (errnum);
139
 
 
140
 
                        if (strPtr == IntPtr.Zero)
141
 
                                return "Unknown Unix error";
142
 
 
143
 
                        return Marshal.PtrToStringAnsi (strPtr);
144
 
                }
145
 
 
146
 
                // FIXME: Don't hard-code this.
147
 
                const int EINTR = 4;
148
 
 
149
 
                public static bool ShouldRetry
150
 
                {
151
 
                        get {
152
 
                                int errno = System.Runtime.InteropServices.Marshal.GetLastWin32Error ();
153
 
                                return errno == EINTR;
154
 
                        }
155
 
                }
156
 
 
157
 
                public static Exception GetLastUnixException ()
158
 
                {
159
 
                        int errno = System.Runtime.InteropServices.Marshal.GetLastWin32Error ();
160
 
                        return new Exception (String.Format ("Error {0}: {1}", errno, GetErrorString (errno)));
161
 
                }
162
 
        }
163
 
 
164
 
        //[StructLayout(LayoutKind.Sequential, Pack=1)]
165
 
        unsafe struct IOVector
166
 
        {
167
 
                public IOVector (IntPtr bbase, int length)
168
 
                {
169
 
                        this.Base = (void*)bbase;
170
 
                        this.length = (SizeT)length;
171
 
                }
172
 
 
173
 
                //public IntPtr Base;
174
 
                public void* Base;
175
 
 
176
 
                public SizeT length;
177
 
                public int Length
178
 
                {
179
 
                        get {
180
 
                                return (int)length;
181
 
                        } set {
182
 
                                length = (SizeT)value;
183
 
                        }
184
 
                }
185
 
        }
186
 
 
187
 
        /*
188
 
        unsafe class SockAddr
189
 
        {
190
 
                byte[] data;
191
 
        }
192
 
        */
193
 
 
194
 
        unsafe class UnixSocket
195
 
        {
196
 
                internal const string LIBC = "libc";
197
 
 
198
 
                // Solaris provides socket functionality in libsocket rather than libc.
199
 
                // We use a dllmap in the .config to deal with this.
200
 
                internal const string LIBSOCKET = "libsocket";
201
 
 
202
 
                public const short AF_UNIX = 1;
203
 
                // FIXME: SOCK_STREAM is 2 on Solaris
204
 
                public const short SOCK_STREAM = 1;
205
 
 
206
 
                [DllImport (LIBC, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
207
 
                internal static extern IntPtr fork ();
208
 
 
209
 
                [DllImport (LIBC, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
210
 
                internal static extern int dup2 (int fd, int fd2);
211
 
                
212
 
                [DllImport (LIBC, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
213
 
                internal static extern int open ([MarshalAs(UnmanagedType.LPStr)] string path, int oflag);
214
 
 
215
 
                [DllImport (LIBC, CallingConvention = CallingConvention.Cdecl, SetLastError = true)]
216
 
                internal static extern IntPtr setsid ();
217
 
                
218
 
 
219
 
                [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
220
 
                internal static extern int close (int fd);
221
 
 
222
 
                [DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
223
 
                protected static extern int socket (int domain, int type, int protocol);
224
 
 
225
 
                [DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
226
 
                protected static extern int connect (int sockfd, byte[] serv_addr, uint addrlen);
227
 
 
228
 
                [DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
229
 
                protected static extern int bind (int sockfd, byte[] my_addr, uint addrlen);
230
 
 
231
 
                [DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
232
 
                protected static extern int listen (int sockfd, int backlog);
233
 
 
234
 
                //TODO: this prototype is probably wrong, fix it
235
 
                [DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
236
 
                protected static extern int accept (int sockfd, void* addr, ref uint addrlen);
237
 
 
238
 
                //TODO: confirm and make use of these functions
239
 
                [DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
240
 
                protected static extern int getsockopt (int s, int optname, IntPtr optval, ref uint optlen);
241
 
 
242
 
                [DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
243
 
                protected static extern int setsockopt (int s, int optname, IntPtr optval, uint optlen);
244
 
 
245
 
                [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
246
 
                unsafe static extern SSizeT read (int fd, byte* buf, SizeT count);
247
 
 
248
 
                [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
249
 
                unsafe static extern SSizeT write (int fd, byte* buf, SizeT count);
250
 
 
251
 
                [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
252
 
                unsafe static extern SSizeT readv (int fd, IOVector* iov, int iovcnt);
253
 
 
254
 
                [DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
255
 
                unsafe static extern SSizeT writev (int fd, IOVector* iov, int iovcnt);
256
 
 
257
 
                // Linux
258
 
                //[DllImport (LIBC, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
259
 
                //static extern int vmsplice (int fd, IOVector* iov, uint nr_segs, uint flags);
260
 
 
261
 
                [DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
262
 
                public static extern SSizeT recvmsg (int s, void* msg, int flags);
263
 
 
264
 
                [DllImport (LIBSOCKET, CallingConvention=CallingConvention.Cdecl, SetLastError=true)]
265
 
                public static extern SSizeT sendmsg (int s, void* msg, int flags);
266
 
 
267
 
                public int Handle;
268
 
                bool ownsHandle = false;
269
 
 
270
 
                public UnixSocket (int handle) : this (handle, false)
271
 
                {
272
 
                }
273
 
 
274
 
                public UnixSocket (int handle, bool ownsHandle)
275
 
                {
276
 
                        this.Handle = handle;
277
 
                        this.ownsHandle = ownsHandle;
278
 
                        // TODO: SafeHandle?
279
 
                }
280
 
 
281
 
                public UnixSocket ()
282
 
                {
283
 
                        //TODO: don't hard-code PF_UNIX and SOCK_STREAM or SocketType.Stream
284
 
                        //AddressFamily family, SocketType type, ProtocolType proto
285
 
 
286
 
                        int r = socket (AF_UNIX, SOCK_STREAM, 0);
287
 
                        if (r < 0)
288
 
                                throw UnixError.GetLastUnixException ();
289
 
 
290
 
                        Handle = r;
291
 
                        ownsHandle = true;
292
 
                }
293
 
 
294
 
                ~UnixSocket ()
295
 
                {
296
 
                        if (ownsHandle && Handle > 0)
297
 
                                Close ();
298
 
                }
299
 
 
300
 
                protected bool connected = false;
301
 
 
302
 
                //TODO: consider memory management
303
 
                public void Close ()
304
 
                {
305
 
                        int r = 0;
306
 
 
307
 
                        do {
308
 
                                r = close (Handle);
309
 
                        } while (r < 0 && UnixError.ShouldRetry);
310
 
 
311
 
                        if (r < 0)
312
 
                                throw UnixError.GetLastUnixException ();
313
 
 
314
 
                        Handle = -1;
315
 
                        connected = false;
316
 
                }
317
 
 
318
 
                //TODO: consider memory management
319
 
                public void Connect (byte[] remote_end)
320
 
                {
321
 
                        int r = 0;
322
 
 
323
 
                        do {
324
 
                                r = connect (Handle, remote_end, (uint)remote_end.Length);
325
 
                        } while (r < 0 && UnixError.ShouldRetry);
326
 
 
327
 
                        if (r < 0)
328
 
                                throw UnixError.GetLastUnixException ();
329
 
 
330
 
                        connected = true;
331
 
                }
332
 
 
333
 
                //assigns a name to the socket
334
 
                public void Bind (byte[] local_end)
335
 
                {
336
 
                        int r = bind (Handle, local_end, (uint)local_end.Length);
337
 
                        if (r < 0)
338
 
                                throw UnixError.GetLastUnixException ();
339
 
                }
340
 
 
341
 
                public void Listen (int backlog)
342
 
                {
343
 
                        int r = listen (Handle, backlog);
344
 
                        if (r < 0)
345
 
                                throw UnixError.GetLastUnixException ();
346
 
                }
347
 
 
348
 
                public UnixSocket Accept ()
349
 
                {
350
 
                        byte[] addr = new byte[110];
351
 
                        uint addrlen = (uint)addr.Length;
352
 
 
353
 
                        fixed (byte* addrP = addr) {
354
 
                                int r = 0;
355
 
 
356
 
                                do {
357
 
                                        r = accept (Handle, addrP, ref addrlen);
358
 
                                } while (r < 0 && UnixError.ShouldRetry);
359
 
 
360
 
                                if (r < 0)
361
 
                                        throw UnixError.GetLastUnixException ();
362
 
 
363
 
                                //TODO: use the returned addr
364
 
                                //string str = Encoding.Default.GetString (addr, 0, (int)addrlen);
365
 
                                return new UnixSocket (r, true);
366
 
                        }
367
 
                }
368
 
 
369
 
                unsafe public int Read (byte[] buf, int offset, int count)
370
 
                {
371
 
                        fixed (byte* bufP = buf)
372
 
                                return Read (bufP + offset, count);
373
 
                }
374
 
 
375
 
                public int Write (byte[] buf, int offset, int count)
376
 
                {
377
 
                        fixed (byte* bufP = buf)
378
 
                                return Write (bufP + offset, count);
379
 
                }
380
 
 
381
 
                unsafe public int Read (byte* bufP, int count)
382
 
                {
383
 
                        int r = 0;
384
 
 
385
 
                        do {
386
 
                                r = (int)read (Handle, bufP, (SizeT)count);
387
 
                        } while (r < 0 && UnixError.ShouldRetry);
388
 
 
389
 
                        if (r < 0)
390
 
                                throw UnixError.GetLastUnixException ();
391
 
 
392
 
                        return r;
393
 
                }
394
 
 
395
 
                public int Write (byte* bufP, int count)
396
 
                {
397
 
                        int r = 0;
398
 
 
399
 
                        do {
400
 
                                r = (int)write (Handle, bufP, (SizeT)count);
401
 
                        } while (r < 0 && UnixError.ShouldRetry);
402
 
 
403
 
                        if (r < 0)
404
 
                                throw UnixError.GetLastUnixException ();
405
 
 
406
 
                        return r;
407
 
                }
408
 
 
409
 
                public int RecvMsg (void* bufP, int flags)
410
 
                {
411
 
                        int r = 0;
412
 
 
413
 
                        do {
414
 
                                r = (int)recvmsg (Handle, bufP, flags);
415
 
                        } while (r < 0 && UnixError.ShouldRetry);
416
 
 
417
 
                        if (r < 0)
418
 
                                throw UnixError.GetLastUnixException ();
419
 
 
420
 
                        return r;
421
 
                }
422
 
 
423
 
                public int SendMsg (void* bufP, int flags)
424
 
                {
425
 
                        int r = 0;
426
 
 
427
 
                        do {
428
 
                                r = (int)sendmsg (Handle, bufP, flags);
429
 
                        } while (r < 0 && UnixError.ShouldRetry);
430
 
 
431
 
                        if (r < 0)
432
 
                                throw UnixError.GetLastUnixException ();
433
 
 
434
 
                        return r;
435
 
                }
436
 
 
437
 
                public int ReadV (IOVector* iov, int count)
438
 
                {
439
 
                        //FIXME: Handle EINTR here or elsewhere
440
 
                        //FIXME: handle r != count
441
 
                        //TODO: check offset correctness
442
 
 
443
 
                        int r = (int)readv (Handle, iov, count);
444
 
                        if (r < 0)
445
 
                                throw UnixError.GetLastUnixException ();
446
 
 
447
 
                        return r;
448
 
                }
449
 
 
450
 
                public int WriteV (IOVector* iov, int count)
451
 
                {
452
 
                        //FIXME: Handle EINTR here or elsewhere
453
 
                        //FIXME: handle r != count
454
 
                        //TODO: check offset correctness
455
 
 
456
 
                        int r = (int)writev (Handle, iov, count);
457
 
                        if (r < 0)
458
 
                                throw UnixError.GetLastUnixException ();
459
 
 
460
 
                        return r;
461
 
                }
462
 
 
463
 
                public int Write (IOVector[] iov, int offset, int count)
464
 
                {
465
 
                        //FIXME: Handle EINTR here or elsewhere
466
 
                        //FIXME: handle r != count
467
 
                        //TODO: check offset correctness
468
 
 
469
 
                        fixed (IOVector* bufP = &iov[offset]) {
470
 
                                int r = (int)writev (Handle, bufP + offset, count);
471
 
                                if (r < 0)
472
 
                                        throw UnixError.GetLastUnixException ();
473
 
 
474
 
                                return r;
475
 
                        }
476
 
                }
477
 
 
478
 
                public int Write (IOVector[] iov)
479
 
                {
480
 
                        return Write (iov, 0, iov.Length);
481
 
                }
482
 
 
483
 
        }
484
 
}