~ubuntu-branches/ubuntu/maverick/python3.1/maverick

« back to all changes in this revision

Viewing changes to Modules/posixmodule.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2009-03-23 00:01:27 UTC
  • Revision ID: james.westby@ubuntu.com-20090323000127-5fstfxju4ufrhthq
Tags: upstream-3.1~a1+20090322
ImportĀ upstreamĀ versionĀ 3.1~a1+20090322

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
/* POSIX module implementation */
 
3
 
 
4
/* This file is also used for Windows NT/MS-Win and OS/2.  In that case the
 
5
   module actually calls itself 'nt' or 'os2', not 'posix', and a few
 
6
   functions are either unimplemented or implemented differently.  The source
 
7
   assumes that for Windows NT, the macro 'MS_WINDOWS' is defined independent
 
8
   of the compiler used.  Different compilers define their own feature
 
9
   test macro, e.g. '__BORLANDC__' or '_MSC_VER'.  For OS/2, the compiler
 
10
   independent macro PYOS_OS2 should be defined.  On OS/2 the default
 
11
   compiler is assumed to be IBM's VisualAge C++ (VACPP).  PYCC_GCC is used
 
12
   as the compiler specific macro for the EMX port of gcc to OS/2. */
 
13
 
 
14
/* See also ../Dos/dosmodule.c */
 
15
 
 
16
#ifdef __APPLE__
 
17
   /*
 
18
    * Step 1 of support for weak-linking a number of symbols existing on 
 
19
    * OSX 10.4 and later, see the comment in the #ifdef __APPLE__ block
 
20
    * at the end of this file for more information.
 
21
    */
 
22
#  pragma weak lchown
 
23
#  pragma weak statvfs
 
24
#  pragma weak fstatvfs
 
25
 
 
26
#endif /* __APPLE__ */
 
27
 
 
28
#define PY_SSIZE_T_CLEAN
 
29
 
 
30
#include "Python.h"
 
31
#include "structseq.h"
 
32
 
 
33
#if defined(__VMS)
 
34
#    include <unixio.h>
 
35
#endif /* defined(__VMS) */
 
36
 
 
37
#ifdef __cplusplus
 
38
extern "C" {
 
39
#endif
 
40
 
 
41
PyDoc_STRVAR(posix__doc__,
 
42
"This module provides access to operating system functionality that is\n\
 
43
standardized by the C Standard and the POSIX standard (a thinly\n\
 
44
disguised Unix interface).  Refer to the library manual and\n\
 
45
corresponding Unix manual entries for more information on calls.");
 
46
 
 
47
 
 
48
#if defined(PYOS_OS2)
 
49
#define  INCL_DOS
 
50
#define  INCL_DOSERRORS
 
51
#define  INCL_DOSPROCESS
 
52
#define  INCL_NOPMAPI
 
53
#include <os2.h>
 
54
#if defined(PYCC_GCC)
 
55
#include <ctype.h>
 
56
#include <io.h>
 
57
#include <stdio.h>
 
58
#include <process.h>
 
59
#endif
 
60
#include "osdefs.h"
 
61
#endif
 
62
 
 
63
#ifdef HAVE_SYS_TYPES_H
 
64
#include <sys/types.h>
 
65
#endif /* HAVE_SYS_TYPES_H */
 
66
 
 
67
#ifdef HAVE_SYS_STAT_H
 
68
#include <sys/stat.h>
 
69
#endif /* HAVE_SYS_STAT_H */
 
70
 
 
71
#ifdef HAVE_SYS_WAIT_H
 
72
#include <sys/wait.h>           /* For WNOHANG */
 
73
#endif
 
74
 
 
75
#ifdef HAVE_SIGNAL_H
 
76
#include <signal.h>
 
77
#endif
 
78
 
 
79
#ifdef HAVE_FCNTL_H
 
80
#include <fcntl.h>
 
81
#endif /* HAVE_FCNTL_H */
 
82
 
 
83
#ifdef HAVE_GRP_H
 
84
#include <grp.h>
 
85
#endif
 
86
 
 
87
#ifdef HAVE_SYSEXITS_H
 
88
#include <sysexits.h>
 
89
#endif /* HAVE_SYSEXITS_H */
 
90
 
 
91
#ifdef HAVE_SYS_LOADAVG_H
 
92
#include <sys/loadavg.h>
 
93
#endif
 
94
 
 
95
#ifdef HAVE_LANGINFO_H
 
96
#include <langinfo.h>
 
97
#endif
 
98
 
 
99
/* Various compilers have only certain posix functions */
 
100
/* XXX Gosh I wish these were all moved into pyconfig.h */
 
101
#if defined(PYCC_VACPP) && defined(PYOS_OS2)
 
102
#include <process.h>
 
103
#else
 
104
#if defined(__WATCOMC__) && !defined(__QNX__)           /* Watcom compiler */
 
105
#define HAVE_GETCWD     1
 
106
#define HAVE_OPENDIR    1
 
107
#define HAVE_SYSTEM     1
 
108
#if defined(__OS2__)
 
109
#define HAVE_EXECV      1
 
110
#define HAVE_WAIT       1
 
111
#endif
 
112
#include <process.h>
 
113
#else
 
114
#ifdef __BORLANDC__             /* Borland compiler */
 
115
#define HAVE_EXECV      1
 
116
#define HAVE_GETCWD     1
 
117
#define HAVE_OPENDIR    1
 
118
#define HAVE_PIPE       1
 
119
#define HAVE_SYSTEM     1
 
120
#define HAVE_WAIT       1
 
121
#else
 
122
#ifdef _MSC_VER         /* Microsoft compiler */
 
123
#define HAVE_GETCWD     1
 
124
#define HAVE_SPAWNV     1
 
125
#define HAVE_EXECV      1
 
126
#define HAVE_PIPE       1
 
127
#define HAVE_SYSTEM     1
 
128
#define HAVE_CWAIT      1
 
129
#define HAVE_FSYNC      1
 
130
#define fsync _commit
 
131
#else
 
132
#if defined(PYOS_OS2) && defined(PYCC_GCC) || defined(__VMS)
 
133
/* Everything needed is defined in PC/os2emx/pyconfig.h or vms/pyconfig.h */
 
134
#else                   /* all other compilers */
 
135
/* Unix functions that the configure script doesn't check for */
 
136
#define HAVE_EXECV      1
 
137
#define HAVE_FORK       1
 
138
#if defined(__USLC__) && defined(__SCO_VERSION__)       /* SCO UDK Compiler */
 
139
#define HAVE_FORK1      1
 
140
#endif
 
141
#define HAVE_GETCWD     1
 
142
#define HAVE_GETEGID    1
 
143
#define HAVE_GETEUID    1
 
144
#define HAVE_GETGID     1
 
145
#define HAVE_GETPPID    1
 
146
#define HAVE_GETUID     1
 
147
#define HAVE_KILL       1
 
148
#define HAVE_OPENDIR    1
 
149
#define HAVE_PIPE       1
 
150
#define HAVE_SYSTEM     1
 
151
#define HAVE_WAIT       1
 
152
#define HAVE_TTYNAME    1
 
153
#endif  /* PYOS_OS2 && PYCC_GCC && __VMS */
 
154
#endif  /* _MSC_VER */
 
155
#endif  /* __BORLANDC__ */
 
156
#endif  /* ! __WATCOMC__ || __QNX__ */
 
157
#endif /* ! __IBMC__ */
 
158
 
 
159
#ifndef _MSC_VER
 
160
 
 
161
#if defined(__sgi)&&_COMPILER_VERSION>=700
 
162
/* declare ctermid_r if compiling with MIPSPro 7.x in ANSI C mode
 
163
   (default) */
 
164
extern char        *ctermid_r(char *);
 
165
#endif
 
166
 
 
167
#ifndef HAVE_UNISTD_H
 
168
#if defined(PYCC_VACPP)
 
169
extern int mkdir(char *);
 
170
#else
 
171
#if ( defined(__WATCOMC__) || defined(_MSC_VER) ) && !defined(__QNX__)
 
172
extern int mkdir(const char *);
 
173
#else
 
174
extern int mkdir(const char *, mode_t);
 
175
#endif
 
176
#endif
 
177
#if defined(__IBMC__) || defined(__IBMCPP__)
 
178
extern int chdir(char *);
 
179
extern int rmdir(char *);
 
180
#else
 
181
extern int chdir(const char *);
 
182
extern int rmdir(const char *);
 
183
#endif
 
184
#ifdef __BORLANDC__
 
185
extern int chmod(const char *, int);
 
186
#else
 
187
extern int chmod(const char *, mode_t);
 
188
#endif
 
189
/*#ifdef HAVE_FCHMOD
 
190
extern int fchmod(int, mode_t);
 
191
#endif*/
 
192
/*#ifdef HAVE_LCHMOD
 
193
extern int lchmod(const char *, mode_t);
 
194
#endif*/
 
195
extern int chown(const char *, uid_t, gid_t);
 
196
extern char *getcwd(char *, int);
 
197
extern char *strerror(int);
 
198
extern int link(const char *, const char *);
 
199
extern int rename(const char *, const char *);
 
200
extern int stat(const char *, struct stat *);
 
201
extern int unlink(const char *);
 
202
#ifdef HAVE_SYMLINK
 
203
extern int symlink(const char *, const char *);
 
204
#endif /* HAVE_SYMLINK */
 
205
#ifdef HAVE_LSTAT
 
206
extern int lstat(const char *, struct stat *);
 
207
#endif /* HAVE_LSTAT */
 
208
#endif /* !HAVE_UNISTD_H */
 
209
 
 
210
#endif /* !_MSC_VER */
 
211
 
 
212
#ifdef HAVE_UTIME_H
 
213
#include <utime.h>
 
214
#endif /* HAVE_UTIME_H */
 
215
 
 
216
#ifdef HAVE_SYS_UTIME_H
 
217
#include <sys/utime.h>
 
218
#define HAVE_UTIME_H /* pretend we do for the rest of this file */
 
219
#endif /* HAVE_SYS_UTIME_H */
 
220
 
 
221
#ifdef HAVE_SYS_TIMES_H
 
222
#include <sys/times.h>
 
223
#endif /* HAVE_SYS_TIMES_H */
 
224
 
 
225
#ifdef HAVE_SYS_PARAM_H
 
226
#include <sys/param.h>
 
227
#endif /* HAVE_SYS_PARAM_H */
 
228
 
 
229
#ifdef HAVE_SYS_UTSNAME_H
 
230
#include <sys/utsname.h>
 
231
#endif /* HAVE_SYS_UTSNAME_H */
 
232
 
 
233
#ifdef HAVE_DIRENT_H
 
234
#include <dirent.h>
 
235
#define NAMLEN(dirent) strlen((dirent)->d_name)
 
236
#else
 
237
#if defined(__WATCOMC__) && !defined(__QNX__)
 
238
#include <direct.h>
 
239
#define NAMLEN(dirent) strlen((dirent)->d_name)
 
240
#else
 
241
#define dirent direct
 
242
#define NAMLEN(dirent) (dirent)->d_namlen
 
243
#endif
 
244
#ifdef HAVE_SYS_NDIR_H
 
245
#include <sys/ndir.h>
 
246
#endif
 
247
#ifdef HAVE_SYS_DIR_H
 
248
#include <sys/dir.h>
 
249
#endif
 
250
#ifdef HAVE_NDIR_H
 
251
#include <ndir.h>
 
252
#endif
 
253
#endif
 
254
 
 
255
#ifdef _MSC_VER
 
256
#ifdef HAVE_DIRECT_H
 
257
#include <direct.h>
 
258
#endif
 
259
#ifdef HAVE_IO_H
 
260
#include <io.h>
 
261
#endif
 
262
#ifdef HAVE_PROCESS_H
 
263
#include <process.h>
 
264
#endif
 
265
#include "osdefs.h"
 
266
#include <windows.h>
 
267
#include <shellapi.h>   /* for ShellExecute() */
 
268
#endif /* _MSC_VER */
 
269
 
 
270
#if defined(PYCC_VACPP) && defined(PYOS_OS2)
 
271
#include <io.h>
 
272
#endif /* OS2 */
 
273
 
 
274
#ifndef MAXPATHLEN
 
275
#if defined(PATH_MAX) && PATH_MAX > 1024
 
276
#define MAXPATHLEN PATH_MAX
 
277
#else
 
278
#define MAXPATHLEN 1024
 
279
#endif
 
280
#endif /* MAXPATHLEN */
 
281
 
 
282
#ifdef UNION_WAIT
 
283
/* Emulate some macros on systems that have a union instead of macros */
 
284
 
 
285
#ifndef WIFEXITED
 
286
#define WIFEXITED(u_wait) (!(u_wait).w_termsig && !(u_wait).w_coredump)
 
287
#endif
 
288
 
 
289
#ifndef WEXITSTATUS
 
290
#define WEXITSTATUS(u_wait) (WIFEXITED(u_wait)?((u_wait).w_retcode):-1)
 
291
#endif
 
292
 
 
293
#ifndef WTERMSIG
 
294
#define WTERMSIG(u_wait) ((u_wait).w_termsig)
 
295
#endif
 
296
 
 
297
#define WAIT_TYPE union wait
 
298
#define WAIT_STATUS_INT(s) (s.w_status)
 
299
 
 
300
#else /* !UNION_WAIT */
 
301
#define WAIT_TYPE int
 
302
#define WAIT_STATUS_INT(s) (s)
 
303
#endif /* UNION_WAIT */
 
304
 
 
305
/* Don't use the "_r" form if we don't need it (also, won't have a
 
306
   prototype for it, at least on Solaris -- maybe others as well?). */
 
307
#if defined(HAVE_CTERMID_R) && defined(WITH_THREAD)
 
308
#define USE_CTERMID_R
 
309
#endif
 
310
 
 
311
/* choose the appropriate stat and fstat functions and return structs */
 
312
#undef STAT
 
313
#if defined(MS_WIN64) || defined(MS_WINDOWS)
 
314
#       define STAT win32_stat
 
315
#       define FSTAT win32_fstat
 
316
#       define STRUCT_STAT struct win32_stat
 
317
#else
 
318
#       define STAT stat
 
319
#       define FSTAT fstat
 
320
#       define STRUCT_STAT struct stat
 
321
#endif
 
322
 
 
323
#if defined(MAJOR_IN_MKDEV)
 
324
#include <sys/mkdev.h>
 
325
#else
 
326
#if defined(MAJOR_IN_SYSMACROS)
 
327
#include <sys/sysmacros.h>
 
328
#endif
 
329
#if defined(HAVE_MKNOD) && defined(HAVE_SYS_MKDEV_H)
 
330
#include <sys/mkdev.h>
 
331
#endif
 
332
#endif
 
333
 
 
334
#if defined _MSC_VER && _MSC_VER >= 1400
 
335
/* Microsoft CRT in VS2005 and higher will verify that a filehandle is
 
336
 * valid and throw an assertion if it isn't.
 
337
 * Normally, an invalid fd is likely to be a C program error and therefore
 
338
 * an assertion can be useful, but it does contradict the POSIX standard
 
339
 * which for write(2) states:
 
340
 *    "Otherwise, -1 shall be returned and errno set to indicate the error."
 
341
 *    "[EBADF] The fildes argument is not a valid file descriptor open for
 
342
 *     writing."
 
343
 * Furthermore, python allows the user to enter any old integer
 
344
 * as a fd and should merely raise a python exception on error.
 
345
 * The Microsoft CRT doesn't provide an official way to check for the
 
346
 * validity of a file descriptor, but we can emulate its internal behaviour
 
347
 * by using the exported __pinfo data member and knowledge of the 
 
348
 * internal structures involved.
 
349
 * The structures below must be updated for each version of visual studio
 
350
 * according to the file internal.h in the CRT source, until MS comes
 
351
 * up with a less hacky way to do this.
 
352
 * (all of this is to avoid globally modifying the CRT behaviour using
 
353
 * _set_invalid_parameter_handler() and _CrtSetReportMode())
 
354
 */
 
355
#if _MSC_VER >= 1500 /* VS 2008 */
 
356
typedef struct {
 
357
        intptr_t osfhnd;
 
358
        char osfile;
 
359
        char pipech;
 
360
        int lockinitflag;
 
361
        CRITICAL_SECTION lock;
 
362
#ifndef _SAFECRT_IMPL
 
363
        char textmode : 7;
 
364
        char unicode : 1;
 
365
        char pipech2[2];
 
366
        __int64 startpos;
 
367
        BOOL utf8translations;
 
368
        char dbcsBuffer;
 
369
        BOOL dbcsBufferUsed;
 
370
#endif  /* _SAFECRT_IMPL */
 
371
    }   ioinfo;
 
372
#elif _MSC_VER >= 1400  /* VS 2005 */
 
373
typedef struct {
 
374
        intptr_t osfhnd;
 
375
        char osfile;
 
376
        char pipech;
 
377
        int lockinitflag;
 
378
        CRITICAL_SECTION lock;
 
379
#ifndef _SAFECRT_IMPL
 
380
        char textmode : 7;
 
381
        char unicode : 1;
 
382
        char pipech2[2];
 
383
        __int64 startpos;
 
384
        BOOL utf8translations;
 
385
#ifndef _DEBUG
 
386
        /* padding hack.  8 byte extra length observed at
 
387
         * runtime, for 32 and 64 bits when not in _DEBUG
 
388
         */
 
389
        __int32 _padding[2];
 
390
#endif
 
391
#endif  /* _SAFECRT_IMPL */
 
392
    }   ioinfo;
 
393
#endif
 
394
 
 
395
extern __declspec(dllimport) ioinfo * __pioinfo[];
 
396
#define IOINFO_L2E 5
 
397
#define IOINFO_ARRAY_ELTS   (1 << IOINFO_L2E)
 
398
#define IOINFO_ARRAYS 64
 
399
#define _NHANDLE_           (IOINFO_ARRAYS * IOINFO_ARRAY_ELTS)
 
400
#define FOPEN 0x01
 
401
#define _NO_CONSOLE_FILENO (intptr_t)-2
 
402
 
 
403
/* This function emulates what the windows CRT does to validate file handles */
 
404
int
 
405
_PyVerify_fd(int fd)
 
406
{
 
407
        const int i1 = fd >> IOINFO_L2E;
 
408
        const int i2 = fd & ((1 << IOINFO_L2E) - 1);
 
409
 
 
410
        /* See that it isn't a special CLEAR fileno */
 
411
        if (fd != _NO_CONSOLE_FILENO) {
 
412
                /* Microsoft CRT would check that 0<=fd<_nhandle but we can't do that.  Instead
 
413
                 * we check pointer validity and other info
 
414
                 */
 
415
                if (0 <= i1 && i1 < IOINFO_ARRAYS && __pioinfo[i1] != NULL) {
 
416
                        /* finally, check that the file is open */
 
417
                        if (__pioinfo[i1][i2].osfile & FOPEN)
 
418
                                return 1;
 
419
                }
 
420
        }
 
421
        errno = EBADF;
 
422
        return 0;
 
423
}
 
424
 
 
425
/* the special case of checking dup2.  The target fd must be in a sensible range */
 
426
static int
 
427
_PyVerify_fd_dup2(int fd1, int fd2)
 
428
{
 
429
        if (!_PyVerify_fd(fd1))
 
430
                return 0;
 
431
        if (fd2 == _NO_CONSOLE_FILENO)
 
432
                return 0;
 
433
        if ((unsigned)fd2 < _NHANDLE_)
 
434
                return 1;
 
435
        else
 
436
                return 0;
 
437
}
 
438
#else
 
439
/* dummy version. _PyVerify_fd() is already defined in fileobject.h */
 
440
#define _PyVerify_fd_dup2(A, B) (1)
 
441
#endif
 
442
 
 
443
/* Return a dictionary corresponding to the POSIX environment table */
 
444
#ifdef WITH_NEXT_FRAMEWORK
 
445
/* On Darwin/MacOSX a shared library or framework has no access to
 
446
** environ directly, we must obtain it with _NSGetEnviron().
 
447
*/
 
448
#include <crt_externs.h>
 
449
static char **environ;
 
450
#elif !defined(_MSC_VER) && ( !defined(__WATCOMC__) || defined(__QNX__) )
 
451
extern char **environ;
 
452
#endif /* !_MSC_VER */
 
453
 
 
454
static PyObject *
 
455
convertenviron(void)
 
456
{
 
457
        PyObject *d;
 
458
#ifdef MS_WINDOWS
 
459
        wchar_t **e;
 
460
#else
 
461
        char **e;
 
462
#endif
 
463
        d = PyDict_New();
 
464
        if (d == NULL)
 
465
                return NULL;
 
466
#ifdef WITH_NEXT_FRAMEWORK
 
467
        if (environ == NULL)
 
468
                environ = *_NSGetEnviron();
 
469
#endif
 
470
#ifdef MS_WINDOWS
 
471
        /* _wenviron must be initialized in this way if the program is started
 
472
           through main() instead of wmain(). */
 
473
        _wgetenv(L"");
 
474
        if (_wenviron == NULL)
 
475
                return d;
 
476
        /* This part ignores errors */
 
477
        for (e = _wenviron; *e != NULL; e++) {
 
478
                PyObject *k;
 
479
                PyObject *v;
 
480
                wchar_t *p = wcschr(*e, L'=');
 
481
                if (p == NULL)
 
482
                        continue;
 
483
                k = PyUnicode_FromWideChar(*e, (Py_ssize_t)(p-*e));
 
484
                if (k == NULL) {
 
485
                        PyErr_Clear();
 
486
                        continue;
 
487
                }
 
488
                v = PyUnicode_FromWideChar(p+1, wcslen(p+1));
 
489
                if (v == NULL) {
 
490
                        PyErr_Clear();
 
491
                        Py_DECREF(k);
 
492
                        continue;
 
493
                }
 
494
                if (PyDict_GetItem(d, k) == NULL) {
 
495
                        if (PyDict_SetItem(d, k, v) != 0)
 
496
                                PyErr_Clear();
 
497
                }
 
498
                Py_DECREF(k);
 
499
                Py_DECREF(v);
 
500
        }
 
501
#else
 
502
        if (environ == NULL)
 
503
                return d;
 
504
        /* This part ignores errors */
 
505
        for (e = environ; *e != NULL; e++) {
 
506
                PyObject *k;
 
507
                PyObject *v;
 
508
                char *p = strchr(*e, '=');
 
509
                if (p == NULL)
 
510
                        continue;
 
511
                k = PyUnicode_FromStringAndSize(*e, (int)(p-*e));
 
512
                if (k == NULL) {
 
513
                        PyErr_Clear();
 
514
                        continue;
 
515
                }
 
516
                v = PyUnicode_FromString(p+1);
 
517
                if (v == NULL) {
 
518
                        PyErr_Clear();
 
519
                        Py_DECREF(k);
 
520
                        continue;
 
521
                }
 
522
                if (PyDict_GetItem(d, k) == NULL) {
 
523
                        if (PyDict_SetItem(d, k, v) != 0)
 
524
                                PyErr_Clear();
 
525
                }
 
526
                Py_DECREF(k);
 
527
                Py_DECREF(v);
 
528
        }
 
529
#endif
 
530
#if defined(PYOS_OS2)
 
531
    {
 
532
        APIRET rc;
 
533
        char   buffer[1024]; /* OS/2 Provides a Documented Max of 1024 Chars */
 
534
 
 
535
        rc = DosQueryExtLIBPATH(buffer, BEGIN_LIBPATH);
 
536
        if (rc == NO_ERROR) { /* (not a type, envname is NOT 'BEGIN_LIBPATH') */
 
537
            PyObject *v = PyBytes_FromString(buffer);
 
538
            PyDict_SetItemString(d, "BEGINLIBPATH", v);
 
539
            Py_DECREF(v);
 
540
        }
 
541
        rc = DosQueryExtLIBPATH(buffer, END_LIBPATH);
 
542
        if (rc == NO_ERROR) { /* (not a typo, envname is NOT 'END_LIBPATH') */
 
543
            PyObject *v = PyBytes_FromString(buffer);
 
544
            PyDict_SetItemString(d, "ENDLIBPATH", v);
 
545
            Py_DECREF(v);
 
546
        }
 
547
    }
 
548
#endif
 
549
        return d;
 
550
}
 
551
 
 
552
 
 
553
/* Set a POSIX-specific error from errno, and return NULL */
 
554
 
 
555
static PyObject *
 
556
posix_error(void)
 
557
{
 
558
        return PyErr_SetFromErrno(PyExc_OSError);
 
559
}
 
560
static PyObject *
 
561
posix_error_with_filename(char* name)
 
562
{
 
563
        return PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
 
564
}
 
565
 
 
566
#ifdef Py_WIN_WIDE_FILENAMES
 
567
static PyObject *
 
568
posix_error_with_unicode_filename(Py_UNICODE* name)
 
569
{
 
570
        return PyErr_SetFromErrnoWithUnicodeFilename(PyExc_OSError, name);
 
571
}
 
572
#endif /* Py_WIN_WIDE_FILENAMES */
 
573
 
 
574
 
 
575
static PyObject *
 
576
posix_error_with_allocated_filename(char* name)
 
577
{
 
578
        PyObject *rc = PyErr_SetFromErrnoWithFilename(PyExc_OSError, name);
 
579
        PyMem_Free(name);
 
580
        return rc;
 
581
}
 
582
 
 
583
#ifdef MS_WINDOWS
 
584
static PyObject *
 
585
win32_error(char* function, char* filename)
 
586
{
 
587
        /* XXX We should pass the function name along in the future.
 
588
           (winreg.c also wants to pass the function name.)
 
589
           This would however require an additional param to the
 
590
           Windows error object, which is non-trivial.
 
591
        */
 
592
        errno = GetLastError();
 
593
        if (filename)
 
594
                return PyErr_SetFromWindowsErrWithFilename(errno, filename);
 
595
        else
 
596
                return PyErr_SetFromWindowsErr(errno);
 
597
}
 
598
 
 
599
#ifdef Py_WIN_WIDE_FILENAMES
 
600
static PyObject *
 
601
win32_error_unicode(char* function, Py_UNICODE* filename)
 
602
{
 
603
        /* XXX - see win32_error for comments on 'function' */
 
604
        errno = GetLastError();
 
605
        if (filename)
 
606
                return PyErr_SetFromWindowsErrWithUnicodeFilename(errno, filename);
 
607
        else
 
608
                return PyErr_SetFromWindowsErr(errno);
 
609
}
 
610
 
 
611
static int
 
612
convert_to_unicode(PyObject **param)
 
613
{
 
614
        if (PyUnicode_CheckExact(*param))
 
615
                Py_INCREF(*param);
 
616
        else if (PyUnicode_Check(*param))
 
617
                /* For a Unicode subtype that's not a Unicode object,
 
618
                   return a true Unicode object with the same data. */
 
619
                *param = PyUnicode_FromUnicode(PyUnicode_AS_UNICODE(*param),
 
620
                                               PyUnicode_GET_SIZE(*param));
 
621
        else
 
622
                *param = PyUnicode_FromEncodedObject(*param,
 
623
                                                     Py_FileSystemDefaultEncoding,
 
624
                                                     "strict");
 
625
        return (*param) != NULL;
 
626
}
 
627
 
 
628
#endif /* Py_WIN_WIDE_FILENAMES */
 
629
 
 
630
#endif
 
631
 
 
632
#if defined(PYOS_OS2)
 
633
/**********************************************************************
 
634
 *         Helper Function to Trim and Format OS/2 Messages
 
635
 **********************************************************************/
 
636
    static void
 
637
os2_formatmsg(char *msgbuf, int msglen, char *reason)
 
638
{
 
639
    msgbuf[msglen] = '\0'; /* OS/2 Doesn't Guarantee a Terminator */
 
640
 
 
641
    if (strlen(msgbuf) > 0) { /* If Non-Empty Msg, Trim CRLF */
 
642
        char *lastc = &msgbuf[ strlen(msgbuf)-1 ];
 
643
 
 
644
        while (lastc > msgbuf && isspace(Py_CHARMASK(*lastc)))
 
645
            *lastc-- = '\0'; /* Trim Trailing Whitespace (CRLF) */
 
646
    }
 
647
 
 
648
    /* Add Optional Reason Text */
 
649
    if (reason) {
 
650
        strcat(msgbuf, " : ");
 
651
        strcat(msgbuf, reason);
 
652
    }
 
653
}
 
654
 
 
655
/**********************************************************************
 
656
 *             Decode an OS/2 Operating System Error Code
 
657
 *
 
658
 * A convenience function to lookup an OS/2 error code and return a
 
659
 * text message we can use to raise a Python exception.
 
660
 *
 
661
 * Notes:
 
662
 *   The messages for errors returned from the OS/2 kernel reside in
 
663
 *   the file OSO001.MSG in the \OS2 directory hierarchy.
 
664
 *
 
665
 **********************************************************************/
 
666
    static char *
 
667
os2_strerror(char *msgbuf, int msgbuflen, int errorcode, char *reason)
 
668
{
 
669
    APIRET rc;
 
670
    ULONG  msglen;
 
671
 
 
672
    /* Retrieve Kernel-Related Error Message from OSO001.MSG File */
 
673
    Py_BEGIN_ALLOW_THREADS
 
674
    rc = DosGetMessage(NULL, 0, msgbuf, msgbuflen,
 
675
                       errorcode, "oso001.msg", &msglen);
 
676
    Py_END_ALLOW_THREADS
 
677
 
 
678
    if (rc == NO_ERROR)
 
679
        os2_formatmsg(msgbuf, msglen, reason);
 
680
    else
 
681
        PyOS_snprintf(msgbuf, msgbuflen,
 
682
                      "unknown OS error #%d", errorcode);
 
683
 
 
684
    return msgbuf;
 
685
}
 
686
 
 
687
/* Set an OS/2-specific error and return NULL.  OS/2 kernel
 
688
   errors are not in a global variable e.g. 'errno' nor are
 
689
   they congruent with posix error numbers. */
 
690
 
 
691
static PyObject * os2_error(int code)
 
692
{
 
693
    char text[1024];
 
694
    PyObject *v;
 
695
 
 
696
    os2_strerror(text, sizeof(text), code, "");
 
697
 
 
698
    v = Py_BuildValue("(is)", code, text);
 
699
    if (v != NULL) {
 
700
        PyErr_SetObject(PyExc_OSError, v);
 
701
        Py_DECREF(v);
 
702
    }
 
703
    return NULL; /* Signal to Python that an Exception is Pending */
 
704
}
 
705
 
 
706
#endif /* OS2 */
 
707
 
 
708
/* POSIX generic methods */
 
709
 
 
710
static PyObject *
 
711
posix_fildes(PyObject *fdobj, int (*func)(int))
 
712
{
 
713
        int fd;
 
714
        int res;
 
715
        fd = PyObject_AsFileDescriptor(fdobj);
 
716
        if (fd < 0)
 
717
                return NULL;
 
718
        if (!_PyVerify_fd(fd))
 
719
                return posix_error();
 
720
        Py_BEGIN_ALLOW_THREADS
 
721
        res = (*func)(fd);
 
722
        Py_END_ALLOW_THREADS
 
723
        if (res < 0)
 
724
                return posix_error();
 
725
        Py_INCREF(Py_None);
 
726
        return Py_None;
 
727
}
 
728
 
 
729
#ifdef Py_WIN_WIDE_FILENAMES
 
730
static int
 
731
unicode_file_names(void)
 
732
{
 
733
        static int canusewide = -1;
 
734
        if (canusewide == -1) {
 
735
                /* As per doc for ::GetVersion(), this is the correct test for
 
736
                   the Windows NT family. */
 
737
                canusewide = (GetVersion() < 0x80000000) ? 1 : 0;
 
738
        }
 
739
        return canusewide;
 
740
}
 
741
#endif
 
742
 
 
743
static PyObject *
 
744
posix_1str(PyObject *args, char *format, int (*func)(const char*))
 
745
{
 
746
        char *path1 = NULL;
 
747
        int res;
 
748
        if (!PyArg_ParseTuple(args, format,
 
749
                              Py_FileSystemDefaultEncoding, &path1))
 
750
                return NULL;
 
751
        Py_BEGIN_ALLOW_THREADS
 
752
        res = (*func)(path1);
 
753
        Py_END_ALLOW_THREADS
 
754
        if (res < 0)
 
755
                return posix_error_with_allocated_filename(path1);
 
756
        PyMem_Free(path1);
 
757
        Py_INCREF(Py_None);
 
758
        return Py_None;
 
759
}
 
760
 
 
761
static PyObject *
 
762
posix_2str(PyObject *args,
 
763
           char *format,
 
764
           int (*func)(const char *, const char *))
 
765
{
 
766
        char *path1 = NULL, *path2 = NULL;
 
767
        int res;
 
768
        if (!PyArg_ParseTuple(args, format,
 
769
                              Py_FileSystemDefaultEncoding, &path1,
 
770
                              Py_FileSystemDefaultEncoding, &path2))
 
771
                return NULL;
 
772
        Py_BEGIN_ALLOW_THREADS
 
773
        res = (*func)(path1, path2);
 
774
        Py_END_ALLOW_THREADS
 
775
        PyMem_Free(path1);
 
776
        PyMem_Free(path2);
 
777
        if (res != 0)
 
778
                /* XXX how to report both path1 and path2??? */
 
779
                return posix_error();
 
780
        Py_INCREF(Py_None);
 
781
        return Py_None;
 
782
}
 
783
 
 
784
#ifdef Py_WIN_WIDE_FILENAMES
 
785
static PyObject*
 
786
win32_1str(PyObject* args, char* func, 
 
787
           char* format, BOOL (__stdcall *funcA)(LPCSTR), 
 
788
           char* wformat, BOOL (__stdcall *funcW)(LPWSTR))
 
789
{
 
790
        PyObject *uni;
 
791
        char *ansi;
 
792
        BOOL result;
 
793
        if (unicode_file_names()) {
 
794
                if (!PyArg_ParseTuple(args, wformat, &uni))
 
795
                        PyErr_Clear();
 
796
                else {
 
797
                        Py_BEGIN_ALLOW_THREADS
 
798
                        result = funcW(PyUnicode_AsUnicode(uni));
 
799
                        Py_END_ALLOW_THREADS
 
800
                        if (!result)
 
801
                                return win32_error_unicode(func, PyUnicode_AsUnicode(uni));
 
802
                        Py_INCREF(Py_None);
 
803
                        return Py_None;
 
804
                }
 
805
        }
 
806
        if (!PyArg_ParseTuple(args, format, &ansi))
 
807
                return NULL;
 
808
        Py_BEGIN_ALLOW_THREADS
 
809
        result = funcA(ansi);
 
810
        Py_END_ALLOW_THREADS
 
811
        if (!result)
 
812
                return win32_error(func, ansi);
 
813
        Py_INCREF(Py_None);
 
814
        return Py_None;
 
815
 
 
816
}
 
817
 
 
818
/* This is a reimplementation of the C library's chdir function,
 
819
   but one that produces Win32 errors instead of DOS error codes.
 
820
   chdir is essentially a wrapper around SetCurrentDirectory; however,
 
821
   it also needs to set "magic" environment variables indicating
 
822
   the per-drive current directory, which are of the form =<drive>: */
 
823
static BOOL __stdcall
 
824
win32_chdir(LPCSTR path)
 
825
{
 
826
        char new_path[MAX_PATH+1];
 
827
        int result;
 
828
        char env[4] = "=x:";
 
829
 
 
830
        if(!SetCurrentDirectoryA(path))
 
831
                return FALSE;
 
832
        result = GetCurrentDirectoryA(MAX_PATH+1, new_path);
 
833
        if (!result)
 
834
                return FALSE;
 
835
        /* In the ANSI API, there should not be any paths longer
 
836
           than MAX_PATH. */
 
837
        assert(result <= MAX_PATH+1);
 
838
        if (strncmp(new_path, "\\\\", 2) == 0 ||
 
839
            strncmp(new_path, "//", 2) == 0)
 
840
            /* UNC path, nothing to do. */
 
841
            return TRUE;
 
842
        env[1] = new_path[0];
 
843
        return SetEnvironmentVariableA(env, new_path);
 
844
}
 
845
 
 
846
/* The Unicode version differs from the ANSI version
 
847
   since the current directory might exceed MAX_PATH characters */
 
848
static BOOL __stdcall
 
849
win32_wchdir(LPCWSTR path)
 
850
{
 
851
        wchar_t _new_path[MAX_PATH+1], *new_path = _new_path;
 
852
        int result;
 
853
        wchar_t env[4] = L"=x:";
 
854
 
 
855
        if(!SetCurrentDirectoryW(path))
 
856
                return FALSE;
 
857
        result = GetCurrentDirectoryW(MAX_PATH+1, new_path);
 
858
        if (!result)
 
859
                return FALSE;
 
860
        if (result > MAX_PATH+1) {
 
861
                new_path = malloc(result * sizeof(wchar_t));
 
862
                if (!new_path) {
 
863
                        SetLastError(ERROR_OUTOFMEMORY);
 
864
                        return FALSE;
 
865
                }
 
866
                result = GetCurrentDirectoryW(result, new_path);
 
867
                if (!result) {
 
868
                        free(new_path);
 
869
                        return FALSE;
 
870
                }
 
871
        }
 
872
        if (wcsncmp(new_path, L"\\\\", 2) == 0 ||
 
873
            wcsncmp(new_path, L"//", 2) == 0)
 
874
            /* UNC path, nothing to do. */
 
875
            return TRUE;
 
876
        env[1] = new_path[0];
 
877
        result = SetEnvironmentVariableW(env, new_path);
 
878
        if (new_path != _new_path)
 
879
                free(new_path);
 
880
        return result;
 
881
}
 
882
#endif
 
883
 
 
884
#ifdef MS_WINDOWS
 
885
/* The CRT of Windows has a number of flaws wrt. its stat() implementation:
 
886
   - time stamps are restricted to second resolution
 
887
   - file modification times suffer from forth-and-back conversions between
 
888
     UTC and local time
 
889
   Therefore, we implement our own stat, based on the Win32 API directly.
 
890
*/
 
891
#define HAVE_STAT_NSEC 1 
 
892
 
 
893
struct win32_stat{
 
894
    int st_dev;
 
895
    __int64 st_ino;
 
896
    unsigned short st_mode;
 
897
    int st_nlink;
 
898
    int st_uid;
 
899
    int st_gid;
 
900
    int st_rdev;
 
901
    __int64 st_size;
 
902
    int st_atime;
 
903
    int st_atime_nsec;
 
904
    int st_mtime;
 
905
    int st_mtime_nsec;
 
906
    int st_ctime;
 
907
    int st_ctime_nsec;
 
908
};
 
909
 
 
910
static __int64 secs_between_epochs = 11644473600; /* Seconds between 1.1.1601 and 1.1.1970 */
 
911
 
 
912
static void
 
913
FILE_TIME_to_time_t_nsec(FILETIME *in_ptr, int *time_out, int* nsec_out)
 
914
{
 
915
        /* XXX endianness. Shouldn't matter, as all Windows implementations are little-endian */
 
916
        /* Cannot simply cast and dereference in_ptr, 
 
917
           since it might not be aligned properly */
 
918
        __int64 in;
 
919
        memcpy(&in, in_ptr, sizeof(in));
 
920
        *nsec_out = (int)(in % 10000000) * 100; /* FILETIME is in units of 100 nsec. */
 
921
        /* XXX Win32 supports time stamps past 2038; we currently don't */
 
922
        *time_out = Py_SAFE_DOWNCAST((in / 10000000) - secs_between_epochs, __int64, int);
 
923
}
 
924
 
 
925
static void
 
926
time_t_to_FILE_TIME(int time_in, int nsec_in, FILETIME *out_ptr)
 
927
{
 
928
        /* XXX endianness */
 
929
        __int64 out;
 
930
        out = time_in + secs_between_epochs;
 
931
        out = out * 10000000 + nsec_in / 100;
 
932
        memcpy(out_ptr, &out, sizeof(out));
 
933
}
 
934
 
 
935
/* Below, we *know* that ugo+r is 0444 */
 
936
#if _S_IREAD != 0400
 
937
#error Unsupported C library
 
938
#endif
 
939
static int
 
940
attributes_to_mode(DWORD attr)
 
941
{
 
942
        int m = 0;
 
943
        if (attr & FILE_ATTRIBUTE_DIRECTORY)
 
944
                m |= _S_IFDIR | 0111; /* IFEXEC for user,group,other */
 
945
        else
 
946
                m |= _S_IFREG;
 
947
        if (attr & FILE_ATTRIBUTE_READONLY)
 
948
                m |= 0444;
 
949
        else
 
950
                m |= 0666;
 
951
        return m;
 
952
}
 
953
 
 
954
static int
 
955
attribute_data_to_stat(WIN32_FILE_ATTRIBUTE_DATA *info, struct win32_stat *result)
 
956
{
 
957
        memset(result, 0, sizeof(*result));
 
958
        result->st_mode = attributes_to_mode(info->dwFileAttributes);
 
959
        result->st_size = (((__int64)info->nFileSizeHigh)<<32) + info->nFileSizeLow;
 
960
        FILE_TIME_to_time_t_nsec(&info->ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
 
961
        FILE_TIME_to_time_t_nsec(&info->ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
 
962
        FILE_TIME_to_time_t_nsec(&info->ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
 
963
 
 
964
        return 0;
 
965
}
 
966
 
 
967
/* Emulate GetFileAttributesEx[AW] on Windows 95 */
 
968
static int checked = 0;
 
969
static BOOL (CALLBACK *gfaxa)(LPCSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
 
970
static BOOL (CALLBACK *gfaxw)(LPCWSTR, GET_FILEEX_INFO_LEVELS, LPVOID);
 
971
static void
 
972
check_gfax()
 
973
{
 
974
        HINSTANCE hKernel32;
 
975
        if (checked)
 
976
            return;
 
977
        checked = 1;
 
978
        hKernel32 = GetModuleHandle("KERNEL32");
 
979
        *(FARPROC*)&gfaxa = GetProcAddress(hKernel32, "GetFileAttributesExA");
 
980
        *(FARPROC*)&gfaxw = GetProcAddress(hKernel32, "GetFileAttributesExW");
 
981
}
 
982
 
 
983
static BOOL
 
984
attributes_from_dir(LPCSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
 
985
{
 
986
        HANDLE hFindFile;
 
987
        WIN32_FIND_DATAA FileData;
 
988
        hFindFile = FindFirstFileA(pszFile, &FileData);
 
989
        if (hFindFile == INVALID_HANDLE_VALUE)
 
990
                return FALSE;
 
991
        FindClose(hFindFile);
 
992
        pfad->dwFileAttributes = FileData.dwFileAttributes;
 
993
        pfad->ftCreationTime   = FileData.ftCreationTime;
 
994
        pfad->ftLastAccessTime = FileData.ftLastAccessTime;
 
995
        pfad->ftLastWriteTime  = FileData.ftLastWriteTime;
 
996
        pfad->nFileSizeHigh    = FileData.nFileSizeHigh;
 
997
        pfad->nFileSizeLow     = FileData.nFileSizeLow;
 
998
        return TRUE;
 
999
}
 
1000
 
 
1001
static BOOL
 
1002
attributes_from_dir_w(LPCWSTR pszFile, LPWIN32_FILE_ATTRIBUTE_DATA pfad)
 
1003
{
 
1004
        HANDLE hFindFile;
 
1005
        WIN32_FIND_DATAW FileData;
 
1006
        hFindFile = FindFirstFileW(pszFile, &FileData);
 
1007
        if (hFindFile == INVALID_HANDLE_VALUE)
 
1008
                return FALSE;
 
1009
        FindClose(hFindFile);
 
1010
        pfad->dwFileAttributes = FileData.dwFileAttributes;
 
1011
        pfad->ftCreationTime   = FileData.ftCreationTime;
 
1012
        pfad->ftLastAccessTime = FileData.ftLastAccessTime;
 
1013
        pfad->ftLastWriteTime  = FileData.ftLastWriteTime;
 
1014
        pfad->nFileSizeHigh    = FileData.nFileSizeHigh;
 
1015
        pfad->nFileSizeLow     = FileData.nFileSizeLow;
 
1016
        return TRUE;
 
1017
}
 
1018
 
 
1019
static BOOL WINAPI
 
1020
Py_GetFileAttributesExA(LPCSTR pszFile, 
 
1021
                       GET_FILEEX_INFO_LEVELS level,
 
1022
                       LPVOID pv)
 
1023
{
 
1024
        BOOL result;
 
1025
        LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
 
1026
        /* First try to use the system's implementation, if that is
 
1027
           available and either succeeds to gives an error other than
 
1028
           that it isn't implemented. */
 
1029
        check_gfax();
 
1030
        if (gfaxa) {
 
1031
                result = gfaxa(pszFile, level, pv);
 
1032
                if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
 
1033
                        return result;
 
1034
        }
 
1035
        /* It's either not present, or not implemented.
 
1036
           Emulate using FindFirstFile. */
 
1037
        if (level != GetFileExInfoStandard) {
 
1038
                SetLastError(ERROR_INVALID_PARAMETER);
 
1039
                return FALSE;
 
1040
        }
 
1041
        /* Use GetFileAttributes to validate that the file name
 
1042
           does not contain wildcards (which FindFirstFile would
 
1043
           accept). */
 
1044
        if (GetFileAttributesA(pszFile) == 0xFFFFFFFF)
 
1045
                return FALSE;
 
1046
        return attributes_from_dir(pszFile, pfad);
 
1047
}
 
1048
 
 
1049
static BOOL WINAPI
 
1050
Py_GetFileAttributesExW(LPCWSTR pszFile, 
 
1051
                       GET_FILEEX_INFO_LEVELS level,
 
1052
                       LPVOID pv)
 
1053
{
 
1054
        BOOL result;
 
1055
        LPWIN32_FILE_ATTRIBUTE_DATA pfad = pv;
 
1056
        /* First try to use the system's implementation, if that is
 
1057
           available and either succeeds to gives an error other than
 
1058
           that it isn't implemented. */
 
1059
        check_gfax();
 
1060
        if (gfaxa) {
 
1061
                result = gfaxw(pszFile, level, pv);
 
1062
                if (result || GetLastError() != ERROR_CALL_NOT_IMPLEMENTED)
 
1063
                        return result;
 
1064
        }
 
1065
        /* It's either not present, or not implemented.
 
1066
           Emulate using FindFirstFile. */
 
1067
        if (level != GetFileExInfoStandard) {
 
1068
                SetLastError(ERROR_INVALID_PARAMETER);
 
1069
                return FALSE;
 
1070
        }
 
1071
        /* Use GetFileAttributes to validate that the file name
 
1072
           does not contain wildcards (which FindFirstFile would
 
1073
           accept). */
 
1074
        if (GetFileAttributesW(pszFile) == 0xFFFFFFFF)
 
1075
                return FALSE;
 
1076
        return attributes_from_dir_w(pszFile, pfad);
 
1077
}
 
1078
 
 
1079
static int 
 
1080
win32_stat(const char* path, struct win32_stat *result)
 
1081
{
 
1082
        WIN32_FILE_ATTRIBUTE_DATA info;
 
1083
        int code;
 
1084
        char *dot;
 
1085
        /* XXX not supported on Win95 and NT 3.x */
 
1086
        if (!Py_GetFileAttributesExA(path, GetFileExInfoStandard, &info)) {
 
1087
                if (GetLastError() != ERROR_SHARING_VIOLATION) {
 
1088
                        /* Protocol violation: we explicitly clear errno, instead of
 
1089
                           setting it to a POSIX error. Callers should use GetLastError. */
 
1090
                        errno = 0;
 
1091
                        return -1;
 
1092
                } else {
 
1093
                        /* Could not get attributes on open file. Fall back to
 
1094
                           reading the directory. */
 
1095
                        if (!attributes_from_dir(path, &info)) {
 
1096
                                /* Very strange. This should not fail now */
 
1097
                                errno = 0;
 
1098
                                return -1;
 
1099
                        }
 
1100
                }
 
1101
        }
 
1102
        code = attribute_data_to_stat(&info, result);
 
1103
        if (code != 0)
 
1104
                return code;
 
1105
        /* Set S_IFEXEC if it is an .exe, .bat, ... */
 
1106
        dot = strrchr(path, '.');
 
1107
        if (dot) {
 
1108
                if (stricmp(dot, ".bat") == 0 ||
 
1109
                stricmp(dot, ".cmd") == 0 ||
 
1110
                stricmp(dot, ".exe") == 0 ||
 
1111
                stricmp(dot, ".com") == 0)
 
1112
                result->st_mode |= 0111;
 
1113
        }
 
1114
        return code;
 
1115
}
 
1116
 
 
1117
static int 
 
1118
win32_wstat(const wchar_t* path, struct win32_stat *result)
 
1119
{
 
1120
        int code;
 
1121
        const wchar_t *dot;
 
1122
        WIN32_FILE_ATTRIBUTE_DATA info;
 
1123
        /* XXX not supported on Win95 and NT 3.x */
 
1124
        if (!Py_GetFileAttributesExW(path, GetFileExInfoStandard, &info)) {
 
1125
                if (GetLastError() != ERROR_SHARING_VIOLATION) {
 
1126
                        /* Protocol violation: we explicitly clear errno, instead of
 
1127
                           setting it to a POSIX error. Callers should use GetLastError. */
 
1128
                        errno = 0;
 
1129
                        return -1;
 
1130
                } else {
 
1131
                        /* Could not get attributes on open file. Fall back to
 
1132
                           reading the directory. */
 
1133
                        if (!attributes_from_dir_w(path, &info)) {
 
1134
                                /* Very strange. This should not fail now */
 
1135
                                errno = 0;
 
1136
                                return -1;
 
1137
                        }
 
1138
                }
 
1139
        }
 
1140
        code = attribute_data_to_stat(&info, result);
 
1141
        if (code < 0)
 
1142
                return code;
 
1143
        /* Set IFEXEC if it is an .exe, .bat, ... */
 
1144
        dot = wcsrchr(path, '.');
 
1145
        if (dot) {
 
1146
                if (_wcsicmp(dot, L".bat") == 0 ||
 
1147
                    _wcsicmp(dot, L".cmd") == 0 ||
 
1148
                    _wcsicmp(dot, L".exe") == 0 ||
 
1149
                    _wcsicmp(dot, L".com") == 0)
 
1150
                        result->st_mode |= 0111;
 
1151
        }
 
1152
        return code;
 
1153
}
 
1154
 
 
1155
static int
 
1156
win32_fstat(int file_number, struct win32_stat *result)
 
1157
{
 
1158
        BY_HANDLE_FILE_INFORMATION info;
 
1159
        HANDLE h;
 
1160
        int type;
 
1161
    
 
1162
        h = (HANDLE)_get_osfhandle(file_number);
 
1163
    
 
1164
        /* Protocol violation: we explicitly clear errno, instead of
 
1165
           setting it to a POSIX error. Callers should use GetLastError. */
 
1166
        errno = 0;
 
1167
 
 
1168
        if (h == INVALID_HANDLE_VALUE) {
 
1169
                /* This is really a C library error (invalid file handle).
 
1170
                   We set the Win32 error to the closes one matching. */
 
1171
                SetLastError(ERROR_INVALID_HANDLE);
 
1172
                return -1;
 
1173
        }
 
1174
        memset(result, 0, sizeof(*result));
 
1175
 
 
1176
        type = GetFileType(h);
 
1177
        if (type == FILE_TYPE_UNKNOWN) {
 
1178
            DWORD error = GetLastError();
 
1179
            if (error != 0) {
 
1180
                return -1;
 
1181
            }
 
1182
            /* else: valid but unknown file */
 
1183
        }
 
1184
 
 
1185
        if (type != FILE_TYPE_DISK) {
 
1186
                if (type == FILE_TYPE_CHAR)
 
1187
                        result->st_mode = _S_IFCHR;
 
1188
                else if (type == FILE_TYPE_PIPE)
 
1189
                        result->st_mode = _S_IFIFO;
 
1190
                return 0;
 
1191
        }
 
1192
 
 
1193
        if (!GetFileInformationByHandle(h, &info)) {
 
1194
                return -1;
 
1195
        }
 
1196
 
 
1197
        /* similar to stat() */
 
1198
        result->st_mode = attributes_to_mode(info.dwFileAttributes);
 
1199
        result->st_size = (((__int64)info.nFileSizeHigh)<<32) + info.nFileSizeLow;
 
1200
        FILE_TIME_to_time_t_nsec(&info.ftCreationTime, &result->st_ctime, &result->st_ctime_nsec);
 
1201
        FILE_TIME_to_time_t_nsec(&info.ftLastWriteTime, &result->st_mtime, &result->st_mtime_nsec);
 
1202
        FILE_TIME_to_time_t_nsec(&info.ftLastAccessTime, &result->st_atime, &result->st_atime_nsec);
 
1203
        /* specific to fstat() */
 
1204
        result->st_nlink = info.nNumberOfLinks;
 
1205
        result->st_ino = (((__int64)info.nFileIndexHigh)<<32) + info.nFileIndexLow;
 
1206
        return 0;
 
1207
}
 
1208
 
 
1209
#endif /* MS_WINDOWS */
 
1210
 
 
1211
PyDoc_STRVAR(stat_result__doc__,
 
1212
"stat_result: Result from stat or lstat.\n\n\
 
1213
This object may be accessed either as a tuple of\n\
 
1214
  (mode, ino, dev, nlink, uid, gid, size, atime, mtime, ctime)\n\
 
1215
or via the attributes st_mode, st_ino, st_dev, st_nlink, st_uid, and so on.\n\
 
1216
\n\
 
1217
Posix/windows: If your platform supports st_blksize, st_blocks, st_rdev,\n\
 
1218
or st_flags, they are available as attributes only.\n\
 
1219
\n\
 
1220
See os.stat for more information.");
 
1221
 
 
1222
static PyStructSequence_Field stat_result_fields[] = {
 
1223
        {"st_mode",    "protection bits"},
 
1224
        {"st_ino",     "inode"},
 
1225
        {"st_dev",     "device"},
 
1226
        {"st_nlink",   "number of hard links"},
 
1227
        {"st_uid",     "user ID of owner"},
 
1228
        {"st_gid",     "group ID of owner"},
 
1229
        {"st_size",    "total size, in bytes"},
 
1230
        /* The NULL is replaced with PyStructSequence_UnnamedField later. */
 
1231
        {NULL,   "integer time of last access"},
 
1232
        {NULL,   "integer time of last modification"},
 
1233
        {NULL,   "integer time of last change"},
 
1234
        {"st_atime",   "time of last access"},
 
1235
        {"st_mtime",   "time of last modification"},
 
1236
        {"st_ctime",   "time of last change"},
 
1237
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
 
1238
        {"st_blksize", "blocksize for filesystem I/O"},
 
1239
#endif
 
1240
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
 
1241
        {"st_blocks",  "number of blocks allocated"},
 
1242
#endif
 
1243
#ifdef HAVE_STRUCT_STAT_ST_RDEV
 
1244
        {"st_rdev",    "device type (if inode device)"},
 
1245
#endif
 
1246
#ifdef HAVE_STRUCT_STAT_ST_FLAGS
 
1247
        {"st_flags",   "user defined flags for file"},
 
1248
#endif
 
1249
#ifdef HAVE_STRUCT_STAT_ST_GEN
 
1250
        {"st_gen",    "generation number"},
 
1251
#endif
 
1252
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
 
1253
        {"st_birthtime",   "time of creation"},
 
1254
#endif
 
1255
        {0}
 
1256
};
 
1257
 
 
1258
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
 
1259
#define ST_BLKSIZE_IDX 13
 
1260
#else
 
1261
#define ST_BLKSIZE_IDX 12
 
1262
#endif
 
1263
 
 
1264
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
 
1265
#define ST_BLOCKS_IDX (ST_BLKSIZE_IDX+1)
 
1266
#else
 
1267
#define ST_BLOCKS_IDX ST_BLKSIZE_IDX
 
1268
#endif
 
1269
 
 
1270
#ifdef HAVE_STRUCT_STAT_ST_RDEV
 
1271
#define ST_RDEV_IDX (ST_BLOCKS_IDX+1)
 
1272
#else
 
1273
#define ST_RDEV_IDX ST_BLOCKS_IDX
 
1274
#endif
 
1275
 
 
1276
#ifdef HAVE_STRUCT_STAT_ST_FLAGS
 
1277
#define ST_FLAGS_IDX (ST_RDEV_IDX+1)
 
1278
#else
 
1279
#define ST_FLAGS_IDX ST_RDEV_IDX
 
1280
#endif
 
1281
 
 
1282
#ifdef HAVE_STRUCT_STAT_ST_GEN
 
1283
#define ST_GEN_IDX (ST_FLAGS_IDX+1)
 
1284
#else
 
1285
#define ST_GEN_IDX ST_FLAGS_IDX
 
1286
#endif
 
1287
 
 
1288
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
 
1289
#define ST_BIRTHTIME_IDX (ST_GEN_IDX+1)
 
1290
#else
 
1291
#define ST_BIRTHTIME_IDX ST_GEN_IDX
 
1292
#endif
 
1293
 
 
1294
static PyStructSequence_Desc stat_result_desc = {
 
1295
        "stat_result", /* name */
 
1296
        stat_result__doc__, /* doc */
 
1297
        stat_result_fields,
 
1298
        10
 
1299
};
 
1300
 
 
1301
PyDoc_STRVAR(statvfs_result__doc__,
 
1302
"statvfs_result: Result from statvfs or fstatvfs.\n\n\
 
1303
This object may be accessed either as a tuple of\n\
 
1304
  (bsize, frsize, blocks, bfree, bavail, files, ffree, favail, flag, namemax),\n\
 
1305
or via the attributes f_bsize, f_frsize, f_blocks, f_bfree, and so on.\n\
 
1306
\n\
 
1307
See os.statvfs for more information.");
 
1308
 
 
1309
static PyStructSequence_Field statvfs_result_fields[] = {
 
1310
        {"f_bsize",  },
 
1311
        {"f_frsize", },
 
1312
        {"f_blocks", },
 
1313
        {"f_bfree",  },
 
1314
        {"f_bavail", },
 
1315
        {"f_files",  },
 
1316
        {"f_ffree",  },
 
1317
        {"f_favail", },
 
1318
        {"f_flag",   },
 
1319
        {"f_namemax",},
 
1320
        {0}
 
1321
};
 
1322
 
 
1323
static PyStructSequence_Desc statvfs_result_desc = {
 
1324
        "statvfs_result", /* name */
 
1325
        statvfs_result__doc__, /* doc */
 
1326
        statvfs_result_fields,
 
1327
        10
 
1328
};
 
1329
 
 
1330
static int initialized;
 
1331
static PyTypeObject StatResultType;
 
1332
static PyTypeObject StatVFSResultType;
 
1333
static newfunc structseq_new;
 
1334
 
 
1335
static PyObject *
 
1336
statresult_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
 
1337
{
 
1338
        PyStructSequence *result;
 
1339
        int i;
 
1340
 
 
1341
        result = (PyStructSequence*)structseq_new(type, args, kwds);
 
1342
        if (!result)
 
1343
                return NULL;
 
1344
        /* If we have been initialized from a tuple,
 
1345
           st_?time might be set to None. Initialize it
 
1346
           from the int slots.  */
 
1347
        for (i = 7; i <= 9; i++) {
 
1348
                if (result->ob_item[i+3] == Py_None) {
 
1349
                        Py_DECREF(Py_None);
 
1350
                        Py_INCREF(result->ob_item[i]);
 
1351
                        result->ob_item[i+3] = result->ob_item[i];
 
1352
                }
 
1353
        }
 
1354
        return (PyObject*)result;
 
1355
}
 
1356
 
 
1357
 
 
1358
 
 
1359
/* If true, st_?time is float. */
 
1360
static int _stat_float_times = 1;
 
1361
 
 
1362
PyDoc_STRVAR(stat_float_times__doc__,
 
1363
"stat_float_times([newval]) -> oldval\n\n\
 
1364
Determine whether os.[lf]stat represents time stamps as float objects.\n\
 
1365
If newval is True, future calls to stat() return floats, if it is False,\n\
 
1366
future calls return ints. \n\
 
1367
If newval is omitted, return the current setting.\n");
 
1368
 
 
1369
static PyObject*
 
1370
stat_float_times(PyObject* self, PyObject *args)
 
1371
{
 
1372
        int newval = -1;
 
1373
        if (!PyArg_ParseTuple(args, "|i:stat_float_times", &newval))
 
1374
                return NULL;
 
1375
        if (newval == -1)
 
1376
                /* Return old value */
 
1377
                return PyBool_FromLong(_stat_float_times);
 
1378
        _stat_float_times = newval;
 
1379
        Py_INCREF(Py_None);
 
1380
        return Py_None;
 
1381
}
 
1382
 
 
1383
static void
 
1384
fill_time(PyObject *v, int index, time_t sec, unsigned long nsec)
 
1385
{
 
1386
        PyObject *fval,*ival;
 
1387
#if SIZEOF_TIME_T > SIZEOF_LONG
 
1388
        ival = PyLong_FromLongLong((PY_LONG_LONG)sec);
 
1389
#else
 
1390
        ival = PyLong_FromLong((long)sec);
 
1391
#endif
 
1392
        if (!ival)
 
1393
                return;
 
1394
        if (_stat_float_times) {
 
1395
                fval = PyFloat_FromDouble(sec + 1e-9*nsec);
 
1396
        } else {
 
1397
                fval = ival;
 
1398
                Py_INCREF(fval);
 
1399
        }
 
1400
        PyStructSequence_SET_ITEM(v, index, ival);
 
1401
        PyStructSequence_SET_ITEM(v, index+3, fval);
 
1402
}
 
1403
 
 
1404
/* pack a system stat C structure into the Python stat tuple
 
1405
   (used by posix_stat() and posix_fstat()) */
 
1406
static PyObject*
 
1407
_pystat_fromstructstat(STRUCT_STAT *st)
 
1408
{
 
1409
        unsigned long ansec, mnsec, cnsec;
 
1410
        PyObject *v = PyStructSequence_New(&StatResultType);
 
1411
        if (v == NULL)
 
1412
                return NULL;
 
1413
 
 
1414
        PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long)st->st_mode));
 
1415
#ifdef HAVE_LARGEFILE_SUPPORT
 
1416
        PyStructSequence_SET_ITEM(v, 1,
 
1417
                                  PyLong_FromLongLong((PY_LONG_LONG)st->st_ino));
 
1418
#else
 
1419
        PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long)st->st_ino));
 
1420
#endif
 
1421
#if defined(HAVE_LONG_LONG) && !defined(MS_WINDOWS)
 
1422
        PyStructSequence_SET_ITEM(v, 2,
 
1423
                                  PyLong_FromLongLong((PY_LONG_LONG)st->st_dev));
 
1424
#else
 
1425
        PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long)st->st_dev));
 
1426
#endif
 
1427
        PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long)st->st_nlink));
 
1428
        PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long)st->st_uid));
 
1429
        PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long)st->st_gid));
 
1430
#ifdef HAVE_LARGEFILE_SUPPORT
 
1431
        PyStructSequence_SET_ITEM(v, 6,
 
1432
                                  PyLong_FromLongLong((PY_LONG_LONG)st->st_size));
 
1433
#else
 
1434
        PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong(st->st_size));
 
1435
#endif
 
1436
 
 
1437
#if defined(HAVE_STAT_TV_NSEC)
 
1438
        ansec = st->st_atim.tv_nsec;
 
1439
        mnsec = st->st_mtim.tv_nsec;
 
1440
        cnsec = st->st_ctim.tv_nsec;
 
1441
#elif defined(HAVE_STAT_TV_NSEC2)
 
1442
        ansec = st->st_atimespec.tv_nsec;
 
1443
        mnsec = st->st_mtimespec.tv_nsec;
 
1444
        cnsec = st->st_ctimespec.tv_nsec;
 
1445
#elif defined(HAVE_STAT_NSEC)
 
1446
        ansec = st->st_atime_nsec;
 
1447
        mnsec = st->st_mtime_nsec;
 
1448
        cnsec = st->st_ctime_nsec;
 
1449
#else
 
1450
        ansec = mnsec = cnsec = 0;
 
1451
#endif
 
1452
        fill_time(v, 7, st->st_atime, ansec);
 
1453
        fill_time(v, 8, st->st_mtime, mnsec);
 
1454
        fill_time(v, 9, st->st_ctime, cnsec);
 
1455
 
 
1456
#ifdef HAVE_STRUCT_STAT_ST_BLKSIZE
 
1457
        PyStructSequence_SET_ITEM(v, ST_BLKSIZE_IDX,
 
1458
                         PyLong_FromLong((long)st->st_blksize));
 
1459
#endif
 
1460
#ifdef HAVE_STRUCT_STAT_ST_BLOCKS
 
1461
        PyStructSequence_SET_ITEM(v, ST_BLOCKS_IDX,
 
1462
                         PyLong_FromLong((long)st->st_blocks));
 
1463
#endif
 
1464
#ifdef HAVE_STRUCT_STAT_ST_RDEV
 
1465
        PyStructSequence_SET_ITEM(v, ST_RDEV_IDX,
 
1466
                         PyLong_FromLong((long)st->st_rdev));
 
1467
#endif
 
1468
#ifdef HAVE_STRUCT_STAT_ST_GEN
 
1469
        PyStructSequence_SET_ITEM(v, ST_GEN_IDX,
 
1470
                         PyLong_FromLong((long)st->st_gen));
 
1471
#endif
 
1472
#ifdef HAVE_STRUCT_STAT_ST_BIRTHTIME
 
1473
        {
 
1474
          PyObject *val;
 
1475
          unsigned long bsec,bnsec;
 
1476
          bsec = (long)st->st_birthtime;
 
1477
#ifdef HAVE_STAT_TV_NSEC2
 
1478
          bnsec = st->st_birthtimespec.tv_nsec;
 
1479
#else
 
1480
          bnsec = 0;
 
1481
#endif
 
1482
          if (_stat_float_times) {
 
1483
            val = PyFloat_FromDouble(bsec + 1e-9*bnsec);
 
1484
          } else {
 
1485
            val = PyLong_FromLong((long)bsec);
 
1486
          }
 
1487
          PyStructSequence_SET_ITEM(v, ST_BIRTHTIME_IDX,
 
1488
                                    val);
 
1489
        }
 
1490
#endif
 
1491
#ifdef HAVE_STRUCT_STAT_ST_FLAGS
 
1492
        PyStructSequence_SET_ITEM(v, ST_FLAGS_IDX,
 
1493
                         PyLong_FromLong((long)st->st_flags));
 
1494
#endif
 
1495
 
 
1496
        if (PyErr_Occurred()) {
 
1497
                Py_DECREF(v);
 
1498
                return NULL;
 
1499
        }
 
1500
 
 
1501
        return v;
 
1502
}
 
1503
 
 
1504
#ifdef MS_WINDOWS
 
1505
 
 
1506
/* IsUNCRoot -- test whether the supplied path is of the form \\SERVER\SHARE\,
 
1507
   where / can be used in place of \ and the trailing slash is optional.
 
1508
   Both SERVER and SHARE must have at least one character.
 
1509
*/
 
1510
 
 
1511
#define ISSLASHA(c) ((c) == '\\' || (c) == '/')
 
1512
#define ISSLASHW(c) ((c) == L'\\' || (c) == L'/')
 
1513
#ifndef ARRAYSIZE
 
1514
#define ARRAYSIZE(a) (sizeof(a) / sizeof(a[0]))
 
1515
#endif
 
1516
 
 
1517
static BOOL
 
1518
IsUNCRootA(char *path, int pathlen)
 
1519
{
 
1520
        #define ISSLASH ISSLASHA
 
1521
 
 
1522
        int i, share;
 
1523
 
 
1524
        if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
 
1525
                /* minimum UNCRoot is \\x\y */
 
1526
                return FALSE;
 
1527
        for (i = 2; i < pathlen ; i++)
 
1528
                if (ISSLASH(path[i])) break;
 
1529
        if (i == 2 || i == pathlen)
 
1530
                /* do not allow \\\SHARE or \\SERVER */
 
1531
                return FALSE;
 
1532
        share = i+1;
 
1533
        for (i = share; i < pathlen; i++)
 
1534
                if (ISSLASH(path[i])) break;
 
1535
        return (i != share && (i == pathlen || i == pathlen-1));
 
1536
 
 
1537
        #undef ISSLASH
 
1538
}
 
1539
 
 
1540
#ifdef Py_WIN_WIDE_FILENAMES
 
1541
static BOOL
 
1542
IsUNCRootW(Py_UNICODE *path, int pathlen)
 
1543
{
 
1544
        #define ISSLASH ISSLASHW
 
1545
 
 
1546
        int i, share;
 
1547
 
 
1548
        if (pathlen < 5 || !ISSLASH(path[0]) || !ISSLASH(path[1]))
 
1549
                /* minimum UNCRoot is \\x\y */
 
1550
                return FALSE;
 
1551
        for (i = 2; i < pathlen ; i++)
 
1552
                if (ISSLASH(path[i])) break;
 
1553
        if (i == 2 || i == pathlen)
 
1554
                /* do not allow \\\SHARE or \\SERVER */
 
1555
                return FALSE;
 
1556
        share = i+1;
 
1557
        for (i = share; i < pathlen; i++)
 
1558
                if (ISSLASH(path[i])) break;
 
1559
        return (i != share && (i == pathlen || i == pathlen-1));
 
1560
 
 
1561
        #undef ISSLASH
 
1562
}
 
1563
#endif /* Py_WIN_WIDE_FILENAMES */
 
1564
#endif /* MS_WINDOWS */
 
1565
 
 
1566
static PyObject *
 
1567
posix_do_stat(PyObject *self, PyObject *args,
 
1568
              char *format,
 
1569
#ifdef __VMS
 
1570
              int (*statfunc)(const char *, STRUCT_STAT *, ...),
 
1571
#else
 
1572
              int (*statfunc)(const char *, STRUCT_STAT *),
 
1573
#endif
 
1574
              char *wformat,
 
1575
              int (*wstatfunc)(const Py_UNICODE *, STRUCT_STAT *))
 
1576
{
 
1577
        STRUCT_STAT st;
 
1578
        char *path = NULL;      /* pass this to stat; do not free() it */
 
1579
        char *pathfree = NULL;  /* this memory must be free'd */
 
1580
        int res;
 
1581
        PyObject *result;
 
1582
 
 
1583
#ifdef Py_WIN_WIDE_FILENAMES
 
1584
        /* If on wide-character-capable OS see if argument
 
1585
           is Unicode and if so use wide API.  */
 
1586
        if (unicode_file_names()) {
 
1587
                PyUnicodeObject *po;
 
1588
                if (PyArg_ParseTuple(args, wformat, &po)) {
 
1589
                        Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
 
1590
 
 
1591
                        Py_BEGIN_ALLOW_THREADS
 
1592
                                /* PyUnicode_AS_UNICODE result OK without
 
1593
                                   thread lock as it is a simple dereference. */
 
1594
                        res = wstatfunc(wpath, &st);
 
1595
                        Py_END_ALLOW_THREADS
 
1596
 
 
1597
                        if (res != 0)
 
1598
                                return win32_error_unicode("stat", wpath);
 
1599
                        return _pystat_fromstructstat(&st);
 
1600
                }
 
1601
                /* Drop the argument parsing error as narrow strings
 
1602
                   are also valid. */
 
1603
                PyErr_Clear();
 
1604
        }
 
1605
#endif
 
1606
 
 
1607
        if (!PyArg_ParseTuple(args, format,
 
1608
                              Py_FileSystemDefaultEncoding, &path))
 
1609
                return NULL;
 
1610
        pathfree = path;
 
1611
 
 
1612
        Py_BEGIN_ALLOW_THREADS
 
1613
        res = (*statfunc)(path, &st);
 
1614
        Py_END_ALLOW_THREADS
 
1615
 
 
1616
        if (res != 0) {
 
1617
#ifdef MS_WINDOWS
 
1618
                result = win32_error("stat", pathfree);
 
1619
#else
 
1620
                result = posix_error_with_filename(pathfree);
 
1621
#endif
 
1622
        } 
 
1623
        else
 
1624
                result = _pystat_fromstructstat(&st);
 
1625
 
 
1626
        PyMem_Free(pathfree);
 
1627
        return result;
 
1628
}
 
1629
 
 
1630
/* POSIX methods */
 
1631
 
 
1632
PyDoc_STRVAR(posix_access__doc__,
 
1633
"access(path, mode) -> True if granted, False otherwise\n\n\
 
1634
Use the real uid/gid to test for access to a path.  Note that most\n\
 
1635
operations will use the effective uid/gid, therefore this routine can\n\
 
1636
be used in a suid/sgid environment to test if the invoking user has the\n\
 
1637
specified access to the path.  The mode argument can be F_OK to test\n\
 
1638
existence, or the inclusive-OR of R_OK, W_OK, and X_OK.");
 
1639
 
 
1640
static PyObject *
 
1641
posix_access(PyObject *self, PyObject *args)
 
1642
{
 
1643
        char *path;
 
1644
        int mode;
 
1645
        
 
1646
#ifdef Py_WIN_WIDE_FILENAMES
 
1647
        DWORD attr;
 
1648
        if (unicode_file_names()) {
 
1649
                PyUnicodeObject *po;
 
1650
                if (PyArg_ParseTuple(args, "Ui:access", &po, &mode)) {
 
1651
                        Py_BEGIN_ALLOW_THREADS
 
1652
                        /* PyUnicode_AS_UNICODE OK without thread lock as
 
1653
                           it is a simple dereference. */
 
1654
                        attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
 
1655
                        Py_END_ALLOW_THREADS
 
1656
                        goto finish;
 
1657
                }
 
1658
                /* Drop the argument parsing error as narrow strings
 
1659
                   are also valid. */
 
1660
                PyErr_Clear();
 
1661
        }
 
1662
        if (!PyArg_ParseTuple(args, "eti:access",
 
1663
                              Py_FileSystemDefaultEncoding, &path, &mode))
 
1664
                return 0;
 
1665
        Py_BEGIN_ALLOW_THREADS
 
1666
        attr = GetFileAttributesA(path);
 
1667
        Py_END_ALLOW_THREADS
 
1668
        PyMem_Free(path);
 
1669
finish:
 
1670
        if (attr == 0xFFFFFFFF)
 
1671
                /* File does not exist, or cannot read attributes */
 
1672
                return PyBool_FromLong(0);
 
1673
        /* Access is possible if either write access wasn't requested, or
 
1674
           the file isn't read-only, or if it's a directory, as there are
 
1675
           no read-only directories on Windows. */
 
1676
        return PyBool_FromLong(!(mode & 2) 
 
1677
                               || !(attr & FILE_ATTRIBUTE_READONLY)
 
1678
                               || (attr & FILE_ATTRIBUTE_DIRECTORY));
 
1679
#else
 
1680
        int res;
 
1681
        if (!PyArg_ParseTuple(args, "eti:access", 
 
1682
                              Py_FileSystemDefaultEncoding, &path, &mode))
 
1683
                return NULL;
 
1684
        Py_BEGIN_ALLOW_THREADS
 
1685
        res = access(path, mode);
 
1686
        Py_END_ALLOW_THREADS
 
1687
        PyMem_Free(path);
 
1688
        return PyBool_FromLong(res == 0);
 
1689
#endif
 
1690
}
 
1691
 
 
1692
#ifndef F_OK
 
1693
#define F_OK 0
 
1694
#endif
 
1695
#ifndef R_OK
 
1696
#define R_OK 4
 
1697
#endif
 
1698
#ifndef W_OK
 
1699
#define W_OK 2
 
1700
#endif
 
1701
#ifndef X_OK
 
1702
#define X_OK 1
 
1703
#endif
 
1704
 
 
1705
#ifdef HAVE_TTYNAME
 
1706
PyDoc_STRVAR(posix_ttyname__doc__,
 
1707
"ttyname(fd) -> string\n\n\
 
1708
Return the name of the terminal device connected to 'fd'.");
 
1709
 
 
1710
static PyObject *
 
1711
posix_ttyname(PyObject *self, PyObject *args)
 
1712
{
 
1713
        int id;
 
1714
        char *ret;
 
1715
 
 
1716
        if (!PyArg_ParseTuple(args, "i:ttyname", &id))
 
1717
                return NULL;
 
1718
 
 
1719
#if defined(__VMS)
 
1720
        /* file descriptor 0 only, the default input device (stdin) */
 
1721
        if (id == 0) {
 
1722
                ret = ttyname();
 
1723
        }
 
1724
        else {
 
1725
                ret = NULL;
 
1726
        }
 
1727
#else
 
1728
        ret = ttyname(id);
 
1729
#endif
 
1730
        if (ret == NULL)
 
1731
                return posix_error();
 
1732
        return PyUnicode_FromString(ret);
 
1733
}
 
1734
#endif
 
1735
 
 
1736
#ifdef HAVE_CTERMID
 
1737
PyDoc_STRVAR(posix_ctermid__doc__,
 
1738
"ctermid() -> string\n\n\
 
1739
Return the name of the controlling terminal for this process.");
 
1740
 
 
1741
static PyObject *
 
1742
posix_ctermid(PyObject *self, PyObject *noargs)
 
1743
{
 
1744
        char *ret;
 
1745
        char buffer[L_ctermid];
 
1746
 
 
1747
#ifdef USE_CTERMID_R
 
1748
        ret = ctermid_r(buffer);
 
1749
#else
 
1750
        ret = ctermid(buffer);
 
1751
#endif
 
1752
        if (ret == NULL)
 
1753
                return posix_error();
 
1754
        return PyUnicode_FromString(buffer);
 
1755
}
 
1756
#endif
 
1757
 
 
1758
PyDoc_STRVAR(posix_chdir__doc__,
 
1759
"chdir(path)\n\n\
 
1760
Change the current working directory to the specified path.");
 
1761
 
 
1762
static PyObject *
 
1763
posix_chdir(PyObject *self, PyObject *args)
 
1764
{
 
1765
#ifdef MS_WINDOWS
 
1766
        return win32_1str(args, "chdir", "y:chdir", win32_chdir, "U:chdir", win32_wchdir);
 
1767
#elif defined(PYOS_OS2) && defined(PYCC_GCC)
 
1768
        return posix_1str(args, "et:chdir", _chdir2);
 
1769
#elif defined(__VMS)
 
1770
        return posix_1str(args, "et:chdir", (int (*)(const char *))chdir);
 
1771
#else
 
1772
        return posix_1str(args, "et:chdir", chdir);
 
1773
#endif
 
1774
}
 
1775
 
 
1776
#ifdef HAVE_FCHDIR
 
1777
PyDoc_STRVAR(posix_fchdir__doc__,
 
1778
"fchdir(fildes)\n\n\
 
1779
Change to the directory of the given file descriptor.  fildes must be\n\
 
1780
opened on a directory, not a file.");
 
1781
 
 
1782
static PyObject *
 
1783
posix_fchdir(PyObject *self, PyObject *fdobj)
 
1784
{
 
1785
        return posix_fildes(fdobj, fchdir);
 
1786
}
 
1787
#endif /* HAVE_FCHDIR */
 
1788
 
 
1789
 
 
1790
PyDoc_STRVAR(posix_chmod__doc__,
 
1791
"chmod(path, mode)\n\n\
 
1792
Change the access permissions of a file.");
 
1793
 
 
1794
static PyObject *
 
1795
posix_chmod(PyObject *self, PyObject *args)
 
1796
{
 
1797
        char *path = NULL;
 
1798
        int i;
 
1799
        int res;
 
1800
#ifdef Py_WIN_WIDE_FILENAMES
 
1801
        DWORD attr;
 
1802
        if (unicode_file_names()) {
 
1803
                PyUnicodeObject *po;
 
1804
                if (PyArg_ParseTuple(args, "Ui|:chmod", &po, &i)) {
 
1805
                        Py_BEGIN_ALLOW_THREADS
 
1806
                        attr = GetFileAttributesW(PyUnicode_AS_UNICODE(po));
 
1807
                        if (attr != 0xFFFFFFFF) {
 
1808
                                if (i & _S_IWRITE)
 
1809
                                        attr &= ~FILE_ATTRIBUTE_READONLY;
 
1810
                                else
 
1811
                                        attr |= FILE_ATTRIBUTE_READONLY;
 
1812
                                res = SetFileAttributesW(PyUnicode_AS_UNICODE(po), attr);
 
1813
                        }
 
1814
                        else
 
1815
                                res = 0;
 
1816
                        Py_END_ALLOW_THREADS
 
1817
                        if (!res)
 
1818
                                return win32_error_unicode("chmod",
 
1819
                                                PyUnicode_AS_UNICODE(po));
 
1820
                        Py_INCREF(Py_None);
 
1821
                        return Py_None;
 
1822
                }
 
1823
                /* Drop the argument parsing error as narrow strings
 
1824
                   are also valid. */
 
1825
                PyErr_Clear();
 
1826
        }
 
1827
        if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
 
1828
                              &path, &i))
 
1829
                return NULL;
 
1830
        Py_BEGIN_ALLOW_THREADS
 
1831
        attr = GetFileAttributesA(path);
 
1832
        if (attr != 0xFFFFFFFF) {
 
1833
                if (i & _S_IWRITE)
 
1834
                        attr &= ~FILE_ATTRIBUTE_READONLY;
 
1835
                else
 
1836
                        attr |= FILE_ATTRIBUTE_READONLY;
 
1837
                res = SetFileAttributesA(path, attr);
 
1838
        }
 
1839
        else
 
1840
                res = 0;
 
1841
        Py_END_ALLOW_THREADS
 
1842
        if (!res) {
 
1843
                win32_error("chmod", path);
 
1844
                PyMem_Free(path);
 
1845
                return NULL;
 
1846
        }
 
1847
        PyMem_Free(path);
 
1848
        Py_INCREF(Py_None);
 
1849
        return Py_None;
 
1850
#else /* Py_WIN_WIDE_FILENAMES */
 
1851
        if (!PyArg_ParseTuple(args, "eti:chmod", Py_FileSystemDefaultEncoding,
 
1852
                              &path, &i))
 
1853
                return NULL;
 
1854
        Py_BEGIN_ALLOW_THREADS
 
1855
        res = chmod(path, i);
 
1856
        Py_END_ALLOW_THREADS
 
1857
        if (res < 0)
 
1858
                return posix_error_with_allocated_filename(path);
 
1859
        PyMem_Free(path);
 
1860
        Py_INCREF(Py_None);
 
1861
        return Py_None;
 
1862
#endif
 
1863
}
 
1864
 
 
1865
#ifdef HAVE_FCHMOD
 
1866
PyDoc_STRVAR(posix_fchmod__doc__,
 
1867
"fchmod(fd, mode)\n\n\
 
1868
Change the access permissions of the file given by file\n\
 
1869
descriptor fd.");
 
1870
 
 
1871
static PyObject *
 
1872
posix_fchmod(PyObject *self, PyObject *args)
 
1873
{
 
1874
        int fd, mode, res;
 
1875
        if (!PyArg_ParseTuple(args, "ii:fchmod", &fd, &mode))
 
1876
                return NULL;
 
1877
        Py_BEGIN_ALLOW_THREADS
 
1878
        res = fchmod(fd, mode);
 
1879
        Py_END_ALLOW_THREADS
 
1880
        if (res < 0)
 
1881
                return posix_error();
 
1882
        Py_RETURN_NONE;
 
1883
}
 
1884
#endif /* HAVE_FCHMOD */
 
1885
 
 
1886
#ifdef HAVE_LCHMOD
 
1887
PyDoc_STRVAR(posix_lchmod__doc__,
 
1888
"lchmod(path, mode)\n\n\
 
1889
Change the access permissions of a file. If path is a symlink, this\n\
 
1890
affects the link itself rather than the target.");
 
1891
 
 
1892
static PyObject *
 
1893
posix_lchmod(PyObject *self, PyObject *args)
 
1894
{
 
1895
        char *path = NULL;
 
1896
        int i;
 
1897
        int res;
 
1898
        if (!PyArg_ParseTuple(args, "eti:lchmod", Py_FileSystemDefaultEncoding,
 
1899
                              &path, &i))
 
1900
                return NULL;
 
1901
        Py_BEGIN_ALLOW_THREADS
 
1902
        res = lchmod(path, i);
 
1903
        Py_END_ALLOW_THREADS
 
1904
        if (res < 0)
 
1905
                return posix_error_with_allocated_filename(path);
 
1906
        PyMem_Free(path);
 
1907
        Py_RETURN_NONE;
 
1908
}
 
1909
#endif /* HAVE_LCHMOD */
 
1910
 
 
1911
 
 
1912
#ifdef HAVE_CHFLAGS
 
1913
PyDoc_STRVAR(posix_chflags__doc__,
 
1914
"chflags(path, flags)\n\n\
 
1915
Set file flags.");
 
1916
 
 
1917
static PyObject *
 
1918
posix_chflags(PyObject *self, PyObject *args)
 
1919
{
 
1920
        char *path;
 
1921
        unsigned long flags;
 
1922
        int res;
 
1923
        if (!PyArg_ParseTuple(args, "etk:chflags",
 
1924
                              Py_FileSystemDefaultEncoding, &path, &flags))
 
1925
                return NULL;
 
1926
        Py_BEGIN_ALLOW_THREADS
 
1927
        res = chflags(path, flags);
 
1928
        Py_END_ALLOW_THREADS
 
1929
        if (res < 0)
 
1930
                return posix_error_with_allocated_filename(path);
 
1931
        PyMem_Free(path);
 
1932
        Py_INCREF(Py_None);
 
1933
        return Py_None;
 
1934
}
 
1935
#endif /* HAVE_CHFLAGS */
 
1936
 
 
1937
#ifdef HAVE_LCHFLAGS
 
1938
PyDoc_STRVAR(posix_lchflags__doc__,
 
1939
"lchflags(path, flags)\n\n\
 
1940
Set file flags.\n\
 
1941
This function will not follow symbolic links.");
 
1942
 
 
1943
static PyObject *
 
1944
posix_lchflags(PyObject *self, PyObject *args)
 
1945
{
 
1946
        char *path;
 
1947
        unsigned long flags;
 
1948
        int res;
 
1949
        if (!PyArg_ParseTuple(args, "etk:lchflags",
 
1950
                              Py_FileSystemDefaultEncoding, &path, &flags))
 
1951
                return NULL;
 
1952
        Py_BEGIN_ALLOW_THREADS
 
1953
        res = lchflags(path, flags);
 
1954
        Py_END_ALLOW_THREADS
 
1955
        if (res < 0)
 
1956
                return posix_error_with_allocated_filename(path);
 
1957
        PyMem_Free(path);
 
1958
        Py_INCREF(Py_None);
 
1959
        return Py_None;
 
1960
}
 
1961
#endif /* HAVE_LCHFLAGS */
 
1962
 
 
1963
#ifdef HAVE_CHROOT
 
1964
PyDoc_STRVAR(posix_chroot__doc__,
 
1965
"chroot(path)\n\n\
 
1966
Change root directory to path.");
 
1967
 
 
1968
static PyObject *
 
1969
posix_chroot(PyObject *self, PyObject *args)
 
1970
{
 
1971
        return posix_1str(args, "et:chroot", chroot);
 
1972
}
 
1973
#endif
 
1974
 
 
1975
#ifdef HAVE_FSYNC
 
1976
PyDoc_STRVAR(posix_fsync__doc__,
 
1977
"fsync(fildes)\n\n\
 
1978
force write of file with filedescriptor to disk.");
 
1979
 
 
1980
static PyObject *
 
1981
posix_fsync(PyObject *self, PyObject *fdobj)
 
1982
{
 
1983
       return posix_fildes(fdobj, fsync);
 
1984
}
 
1985
#endif /* HAVE_FSYNC */
 
1986
 
 
1987
#ifdef HAVE_FDATASYNC
 
1988
 
 
1989
#ifdef __hpux
 
1990
extern int fdatasync(int); /* On HP-UX, in libc but not in unistd.h */
 
1991
#endif
 
1992
 
 
1993
PyDoc_STRVAR(posix_fdatasync__doc__,
 
1994
"fdatasync(fildes)\n\n\
 
1995
force write of file with filedescriptor to disk.\n\
 
1996
 does not force update of metadata.");
 
1997
 
 
1998
static PyObject *
 
1999
posix_fdatasync(PyObject *self, PyObject *fdobj)
 
2000
{
 
2001
       return posix_fildes(fdobj, fdatasync);
 
2002
}
 
2003
#endif /* HAVE_FDATASYNC */
 
2004
 
 
2005
 
 
2006
#ifdef HAVE_CHOWN
 
2007
PyDoc_STRVAR(posix_chown__doc__,
 
2008
"chown(path, uid, gid)\n\n\
 
2009
Change the owner and group id of path to the numeric uid and gid.");
 
2010
 
 
2011
static PyObject *
 
2012
posix_chown(PyObject *self, PyObject *args)
 
2013
{
 
2014
        char *path = NULL;
 
2015
        long uid, gid;
 
2016
        int res;
 
2017
        if (!PyArg_ParseTuple(args, "etll:chown",
 
2018
                              Py_FileSystemDefaultEncoding, &path,
 
2019
                              &uid, &gid))
 
2020
                return NULL;
 
2021
        Py_BEGIN_ALLOW_THREADS
 
2022
        res = chown(path, (uid_t) uid, (gid_t) gid);
 
2023
        Py_END_ALLOW_THREADS
 
2024
        if (res < 0)
 
2025
                return posix_error_with_allocated_filename(path);
 
2026
        PyMem_Free(path);
 
2027
        Py_INCREF(Py_None);
 
2028
        return Py_None;
 
2029
}
 
2030
#endif /* HAVE_CHOWN */
 
2031
 
 
2032
#ifdef HAVE_FCHOWN
 
2033
PyDoc_STRVAR(posix_fchown__doc__,
 
2034
"fchown(fd, uid, gid)\n\n\
 
2035
Change the owner and group id of the file given by file descriptor\n\
 
2036
fd to the numeric uid and gid.");
 
2037
 
 
2038
static PyObject *
 
2039
posix_fchown(PyObject *self, PyObject *args)
 
2040
{
 
2041
        int fd, uid, gid;
 
2042
        int res;
 
2043
        if (!PyArg_ParseTuple(args, "iii:chown", &fd, &uid, &gid))
 
2044
                return NULL;
 
2045
        Py_BEGIN_ALLOW_THREADS
 
2046
        res = fchown(fd, (uid_t) uid, (gid_t) gid);
 
2047
        Py_END_ALLOW_THREADS
 
2048
        if (res < 0)
 
2049
                return posix_error();
 
2050
        Py_RETURN_NONE;
 
2051
}
 
2052
#endif /* HAVE_FCHOWN */
 
2053
 
 
2054
#ifdef HAVE_LCHOWN
 
2055
PyDoc_STRVAR(posix_lchown__doc__,
 
2056
"lchown(path, uid, gid)\n\n\
 
2057
Change the owner and group id of path to the numeric uid and gid.\n\
 
2058
This function will not follow symbolic links.");
 
2059
 
 
2060
static PyObject *
 
2061
posix_lchown(PyObject *self, PyObject *args)
 
2062
{
 
2063
        char *path = NULL;
 
2064
        int uid, gid;
 
2065
        int res;
 
2066
        if (!PyArg_ParseTuple(args, "etii:lchown",
 
2067
                              Py_FileSystemDefaultEncoding, &path,
 
2068
                              &uid, &gid))
 
2069
                return NULL;
 
2070
        Py_BEGIN_ALLOW_THREADS
 
2071
        res = lchown(path, (uid_t) uid, (gid_t) gid);
 
2072
        Py_END_ALLOW_THREADS
 
2073
        if (res < 0)
 
2074
                return posix_error_with_allocated_filename(path);
 
2075
        PyMem_Free(path);
 
2076
        Py_INCREF(Py_None);
 
2077
        return Py_None;
 
2078
}
 
2079
#endif /* HAVE_LCHOWN */
 
2080
 
 
2081
 
 
2082
#ifdef HAVE_GETCWD
 
2083
static PyObject *
 
2084
posix_getcwd(int use_bytes)
 
2085
{
 
2086
        char buf[1026];
 
2087
        char *res;
 
2088
 
 
2089
#ifdef Py_WIN_WIDE_FILENAMES
 
2090
        if (!use_bytes && unicode_file_names()) {
 
2091
                wchar_t wbuf[1026];
 
2092
                wchar_t *wbuf2 = wbuf;
 
2093
                PyObject *resobj;
 
2094
                DWORD len;
 
2095
                Py_BEGIN_ALLOW_THREADS
 
2096
                len = GetCurrentDirectoryW(sizeof wbuf/ sizeof wbuf[0], wbuf);
 
2097
                /* If the buffer is large enough, len does not include the
 
2098
                   terminating \0. If the buffer is too small, len includes
 
2099
                   the space needed for the terminator. */
 
2100
                if (len >= sizeof wbuf/ sizeof wbuf[0]) {
 
2101
                        wbuf2 = malloc(len * sizeof(wchar_t));
 
2102
                        if (wbuf2)
 
2103
                                len = GetCurrentDirectoryW(len, wbuf2);
 
2104
                }
 
2105
                Py_END_ALLOW_THREADS
 
2106
                if (!wbuf2) {
 
2107
                        PyErr_NoMemory();
 
2108
                        return NULL;
 
2109
                }
 
2110
                if (!len) {
 
2111
                        if (wbuf2 != wbuf) free(wbuf2);
 
2112
                        return win32_error("getcwdu", NULL);
 
2113
                }
 
2114
                resobj = PyUnicode_FromWideChar(wbuf2, len);
 
2115
                if (wbuf2 != wbuf) free(wbuf2);
 
2116
                return resobj;
 
2117
        }
 
2118
#endif
 
2119
 
 
2120
        Py_BEGIN_ALLOW_THREADS
 
2121
#if defined(PYOS_OS2) && defined(PYCC_GCC)
 
2122
        res = _getcwd2(buf, sizeof buf);
 
2123
#else
 
2124
        res = getcwd(buf, sizeof buf);
 
2125
#endif
 
2126
        Py_END_ALLOW_THREADS
 
2127
        if (res == NULL)
 
2128
                return posix_error();
 
2129
        if (use_bytes)
 
2130
                return PyBytes_FromStringAndSize(buf, strlen(buf));
 
2131
        return PyUnicode_Decode(buf, strlen(buf), Py_FileSystemDefaultEncoding,"strict");
 
2132
}
 
2133
 
 
2134
PyDoc_STRVAR(posix_getcwd__doc__,
 
2135
"getcwd() -> path\n\n\
 
2136
Return a unicode string representing the current working directory.");
 
2137
 
 
2138
static PyObject *
 
2139
posix_getcwd_unicode(PyObject *self)
 
2140
{
 
2141
    return posix_getcwd(0);
 
2142
}
 
2143
 
 
2144
PyDoc_STRVAR(posix_getcwdb__doc__,
 
2145
"getcwdb() -> path\n\n\
 
2146
Return a bytes string representing the current working directory.");
 
2147
 
 
2148
static PyObject *
 
2149
posix_getcwd_bytes(PyObject *self)
 
2150
{
 
2151
    return posix_getcwd(1);
 
2152
}
 
2153
#endif
 
2154
 
 
2155
 
 
2156
#ifdef HAVE_LINK
 
2157
PyDoc_STRVAR(posix_link__doc__,
 
2158
"link(src, dst)\n\n\
 
2159
Create a hard link to a file.");
 
2160
 
 
2161
static PyObject *
 
2162
posix_link(PyObject *self, PyObject *args)
 
2163
{
 
2164
        return posix_2str(args, "etet:link", link);
 
2165
}
 
2166
#endif /* HAVE_LINK */
 
2167
 
 
2168
 
 
2169
PyDoc_STRVAR(posix_listdir__doc__,
 
2170
"listdir(path) -> list_of_strings\n\n\
 
2171
Return a list containing the names of the entries in the directory.\n\
 
2172
\n\
 
2173
        path: path of directory to list\n\
 
2174
\n\
 
2175
The list is in arbitrary order.  It does not include the special\n\
 
2176
entries '.' and '..' even if they are present in the directory.");
 
2177
 
 
2178
static PyObject *
 
2179
posix_listdir(PyObject *self, PyObject *args)
 
2180
{
 
2181
        /* XXX Should redo this putting the (now four) versions of opendir
 
2182
           in separate files instead of having them all here... */
 
2183
#if defined(MS_WINDOWS) && !defined(HAVE_OPENDIR)
 
2184
 
 
2185
        PyObject *d, *v;
 
2186
        HANDLE hFindFile;
 
2187
        BOOL result;
 
2188
        WIN32_FIND_DATA FileData;
 
2189
        char namebuf[MAX_PATH+5]; /* Overallocate for \\*.*\0 */
 
2190
        char *bufptr = namebuf;
 
2191
        Py_ssize_t len = sizeof(namebuf)-5; /* only claim to have space for MAX_PATH */
 
2192
 
 
2193
#ifdef Py_WIN_WIDE_FILENAMES
 
2194
        /* If on wide-character-capable OS see if argument
 
2195
           is Unicode and if so use wide API.  */
 
2196
        if (unicode_file_names()) {
 
2197
                PyObject *po;
 
2198
                if (PyArg_ParseTuple(args, "U:listdir", &po)) {
 
2199
                        WIN32_FIND_DATAW wFileData;
 
2200
                        Py_UNICODE *wnamebuf;
 
2201
                        Py_UNICODE wch;
 
2202
                        /* Overallocate for \\*.*\0 */
 
2203
                        len = PyUnicode_GET_SIZE(po);
 
2204
                        wnamebuf = malloc((len + 5) * sizeof(wchar_t));
 
2205
                        if (!wnamebuf) {
 
2206
                                PyErr_NoMemory();
 
2207
                                return NULL;
 
2208
                        }
 
2209
                        wcscpy(wnamebuf, PyUnicode_AS_UNICODE(po));
 
2210
                        wch = len > 0 ? wnamebuf[len-1] : '\0';
 
2211
                        if (wch != L'/' && wch != L'\\' && wch != L':')
 
2212
                                wnamebuf[len++] = L'\\';
 
2213
                        wcscpy(wnamebuf + len, L"*.*");
 
2214
                        if ((d = PyList_New(0)) == NULL) {
 
2215
                                free(wnamebuf);
 
2216
                                return NULL;
 
2217
                        }
 
2218
                        hFindFile = FindFirstFileW(wnamebuf, &wFileData);
 
2219
                        if (hFindFile == INVALID_HANDLE_VALUE) {
 
2220
                                int error = GetLastError();
 
2221
                                if (error == ERROR_FILE_NOT_FOUND) {
 
2222
                                        free(wnamebuf);
 
2223
                                        return d;
 
2224
                                }
 
2225
                                Py_DECREF(d);
 
2226
                                win32_error_unicode("FindFirstFileW", wnamebuf);
 
2227
                                free(wnamebuf);
 
2228
                                return NULL;
 
2229
                        }
 
2230
                        do {
 
2231
                                /* Skip over . and .. */
 
2232
                                if (wcscmp(wFileData.cFileName, L".") != 0 &&
 
2233
                                    wcscmp(wFileData.cFileName, L"..") != 0) {
 
2234
                                        v = PyUnicode_FromUnicode(wFileData.cFileName, wcslen(wFileData.cFileName));
 
2235
                                        if (v == NULL) {
 
2236
                                                Py_DECREF(d);
 
2237
                                                d = NULL;
 
2238
                                                break;
 
2239
                                        }
 
2240
                                        if (PyList_Append(d, v) != 0) {
 
2241
                                                Py_DECREF(v);
 
2242
                                                Py_DECREF(d);
 
2243
                                                d = NULL;
 
2244
                                                break;
 
2245
                                        }
 
2246
                                        Py_DECREF(v);
 
2247
                                }
 
2248
                                Py_BEGIN_ALLOW_THREADS
 
2249
                                result = FindNextFileW(hFindFile, &wFileData);
 
2250
                                Py_END_ALLOW_THREADS
 
2251
                                /* FindNextFile sets error to ERROR_NO_MORE_FILES if
 
2252
                                   it got to the end of the directory. */
 
2253
                                if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
 
2254
                                    Py_DECREF(d);
 
2255
                                    win32_error_unicode("FindNextFileW", wnamebuf);
 
2256
                                    FindClose(hFindFile);
 
2257
                                    free(wnamebuf);
 
2258
                                    return NULL;
 
2259
                                }
 
2260
                        } while (result == TRUE);
 
2261
 
 
2262
                        if (FindClose(hFindFile) == FALSE) {
 
2263
                                Py_DECREF(d);
 
2264
                                win32_error_unicode("FindClose", wnamebuf);
 
2265
                                free(wnamebuf);
 
2266
                                return NULL;
 
2267
                        }
 
2268
                        free(wnamebuf);
 
2269
                        return d;
 
2270
                }
 
2271
                /* Drop the argument parsing error as narrow strings
 
2272
                   are also valid. */
 
2273
                PyErr_Clear();
 
2274
        }
 
2275
#endif
 
2276
 
 
2277
        if (!PyArg_ParseTuple(args, "et#:listdir",
 
2278
                              Py_FileSystemDefaultEncoding, &bufptr, &len))
 
2279
                return NULL;
 
2280
        if (len > 0) {
 
2281
                char ch = namebuf[len-1];
 
2282
                if (ch != SEP && ch != ALTSEP && ch != ':')
 
2283
                        namebuf[len++] = '/';
 
2284
        }
 
2285
        strcpy(namebuf + len, "*.*");
 
2286
 
 
2287
        if ((d = PyList_New(0)) == NULL)
 
2288
                return NULL;
 
2289
 
 
2290
        hFindFile = FindFirstFile(namebuf, &FileData);
 
2291
        if (hFindFile == INVALID_HANDLE_VALUE) {
 
2292
                int error = GetLastError();
 
2293
                if (error == ERROR_FILE_NOT_FOUND)
 
2294
                        return d;
 
2295
                Py_DECREF(d);
 
2296
                return win32_error("FindFirstFile", namebuf);
 
2297
        }
 
2298
        do {
 
2299
                /* Skip over . and .. */
 
2300
                if (strcmp(FileData.cFileName, ".") != 0 &&
 
2301
                    strcmp(FileData.cFileName, "..") != 0) {
 
2302
                        v = PyBytes_FromString(FileData.cFileName);
 
2303
                        if (v == NULL) {
 
2304
                                Py_DECREF(d);
 
2305
                                d = NULL;
 
2306
                                break;
 
2307
                        }
 
2308
                        if (PyList_Append(d, v) != 0) {
 
2309
                                Py_DECREF(v);
 
2310
                                Py_DECREF(d);
 
2311
                                d = NULL;
 
2312
                                break;
 
2313
                        }
 
2314
                        Py_DECREF(v);
 
2315
                }
 
2316
                Py_BEGIN_ALLOW_THREADS
 
2317
                result = FindNextFile(hFindFile, &FileData);
 
2318
                Py_END_ALLOW_THREADS
 
2319
                /* FindNextFile sets error to ERROR_NO_MORE_FILES if
 
2320
                   it got to the end of the directory. */
 
2321
                if (!result && GetLastError() != ERROR_NO_MORE_FILES) {
 
2322
                    Py_DECREF(d);
 
2323
                    win32_error("FindNextFile", namebuf);
 
2324
                    FindClose(hFindFile);
 
2325
                    return NULL;
 
2326
                }
 
2327
        } while (result == TRUE);
 
2328
 
 
2329
        if (FindClose(hFindFile) == FALSE) {
 
2330
                Py_DECREF(d);
 
2331
                return win32_error("FindClose", namebuf);
 
2332
        }
 
2333
 
 
2334
        return d;
 
2335
 
 
2336
#elif defined(PYOS_OS2)
 
2337
 
 
2338
#ifndef MAX_PATH
 
2339
#define MAX_PATH    CCHMAXPATH
 
2340
#endif
 
2341
    char *name, *pt;
 
2342
    Py_ssize_t len;
 
2343
    PyObject *d, *v;
 
2344
    char namebuf[MAX_PATH+5];
 
2345
    HDIR  hdir = 1;
 
2346
    ULONG srchcnt = 1;
 
2347
    FILEFINDBUF3   ep;
 
2348
    APIRET rc;
 
2349
 
 
2350
    if (!PyArg_ParseTuple(args, "et#:listdir", 
 
2351
                          Py_FileSystemDefaultEncoding, &name, &len))
 
2352
        return NULL;
 
2353
    if (len >= MAX_PATH) {
 
2354
        PyMem_Free(name);
 
2355
        PyErr_SetString(PyExc_ValueError, "path too long");
 
2356
        return NULL;
 
2357
    }
 
2358
    strcpy(namebuf, name);
 
2359
    for (pt = namebuf; *pt; pt++)
 
2360
        if (*pt == ALTSEP)
 
2361
            *pt = SEP;
 
2362
    if (namebuf[len-1] != SEP)
 
2363
        namebuf[len++] = SEP;
 
2364
    strcpy(namebuf + len, "*.*");
 
2365
 
 
2366
    if ((d = PyList_New(0)) == NULL) {
 
2367
        PyMem_Free(name);
 
2368
        return NULL;
 
2369
    }
 
2370
 
 
2371
    rc = DosFindFirst(namebuf,         /* Wildcard Pattern to Match */
 
2372
                      &hdir,           /* Handle to Use While Search Directory */
 
2373
                      FILE_READONLY | FILE_HIDDEN | FILE_SYSTEM | FILE_DIRECTORY,
 
2374
                      &ep, sizeof(ep), /* Structure to Receive Directory Entry */
 
2375
                      &srchcnt,        /* Max and Actual Count of Entries Per Iteration */
 
2376
                      FIL_STANDARD);   /* Format of Entry (EAs or Not) */
 
2377
 
 
2378
    if (rc != NO_ERROR) {
 
2379
        errno = ENOENT;
 
2380
        return posix_error_with_allocated_filename(name);
 
2381
    }
 
2382
 
 
2383
    if (srchcnt > 0) { /* If Directory is NOT Totally Empty, */
 
2384
        do {
 
2385
            if (ep.achName[0] == '.'
 
2386
            && (ep.achName[1] == '\0' || (ep.achName[1] == '.' && ep.achName[2] == '\0')))
 
2387
                continue; /* Skip Over "." and ".." Names */
 
2388
 
 
2389
            strcpy(namebuf, ep.achName);
 
2390
 
 
2391
            /* Leave Case of Name Alone -- In Native Form */
 
2392
            /* (Removed Forced Lowercasing Code) */
 
2393
 
 
2394
            v = PyBytes_FromString(namebuf);
 
2395
            if (v == NULL) {
 
2396
                Py_DECREF(d);
 
2397
                d = NULL;
 
2398
                break;
 
2399
            }
 
2400
            if (PyList_Append(d, v) != 0) {
 
2401
                Py_DECREF(v);
 
2402
                Py_DECREF(d);
 
2403
                d = NULL;
 
2404
                break;
 
2405
            }
 
2406
            Py_DECREF(v);
 
2407
        } while (DosFindNext(hdir, &ep, sizeof(ep), &srchcnt) == NO_ERROR && srchcnt > 0);
 
2408
    }
 
2409
 
 
2410
    PyMem_Free(name);
 
2411
    return d;
 
2412
#else
 
2413
 
 
2414
        char *name = NULL;
 
2415
        PyObject *d, *v;
 
2416
        DIR *dirp;
 
2417
        struct dirent *ep;
 
2418
        int arg_is_unicode = 1;
 
2419
 
 
2420
        errno = 0;
 
2421
        if (!PyArg_ParseTuple(args, "U:listdir", &v)) {
 
2422
                arg_is_unicode = 0;
 
2423
                PyErr_Clear();
 
2424
        }
 
2425
        if (!PyArg_ParseTuple(args, "et:listdir", Py_FileSystemDefaultEncoding, &name))
 
2426
                return NULL;
 
2427
        if ((dirp = opendir(name)) == NULL) {
 
2428
                return posix_error_with_allocated_filename(name);
 
2429
        }
 
2430
        if ((d = PyList_New(0)) == NULL) {
 
2431
                closedir(dirp);
 
2432
                PyMem_Free(name);
 
2433
                return NULL;
 
2434
        }
 
2435
        for (;;) {
 
2436
                errno = 0;
 
2437
                Py_BEGIN_ALLOW_THREADS
 
2438
                ep = readdir(dirp);
 
2439
                Py_END_ALLOW_THREADS
 
2440
                if (ep == NULL) {
 
2441
                        if (errno == 0) {
 
2442
                                break;
 
2443
                        } else {
 
2444
                                closedir(dirp);
 
2445
                                Py_DECREF(d);
 
2446
                                return posix_error_with_allocated_filename(name);
 
2447
                        }
 
2448
                }
 
2449
                if (ep->d_name[0] == '.' &&
 
2450
                    (NAMLEN(ep) == 1 ||
 
2451
                     (ep->d_name[1] == '.' && NAMLEN(ep) == 2)))
 
2452
                        continue;
 
2453
                v = PyBytes_FromStringAndSize(ep->d_name, NAMLEN(ep));
 
2454
                if (v == NULL) {
 
2455
                        Py_DECREF(d);
 
2456
                        d = NULL;
 
2457
                        break;
 
2458
                }
 
2459
                if (arg_is_unicode) {
 
2460
                        PyObject *w;
 
2461
 
 
2462
                        w = PyUnicode_FromEncodedObject(v,
 
2463
                                        Py_FileSystemDefaultEncoding,
 
2464
                                        "strict");
 
2465
                        if (w != NULL) {
 
2466
                                Py_DECREF(v);
 
2467
                                v = w;
 
2468
                        }
 
2469
                        else {
 
2470
                                /* Ignore undecodable filenames, as discussed
 
2471
                                 * in issue 3187. To include these,
 
2472
                                 * use getcwdb(). */
 
2473
                                PyErr_Clear();
 
2474
                                Py_DECREF(v);
 
2475
                                continue;
 
2476
                        }
 
2477
                }
 
2478
                if (PyList_Append(d, v) != 0) {
 
2479
                        Py_DECREF(v);
 
2480
                        Py_DECREF(d);
 
2481
                        d = NULL;
 
2482
                        break;
 
2483
                }
 
2484
                Py_DECREF(v);
 
2485
        }
 
2486
        closedir(dirp);
 
2487
        PyMem_Free(name);
 
2488
 
 
2489
        return d;
 
2490
 
 
2491
#endif /* which OS */
 
2492
}  /* end of posix_listdir */
 
2493
 
 
2494
#ifdef MS_WINDOWS
 
2495
/* A helper function for abspath on win32 */
 
2496
static PyObject *
 
2497
posix__getfullpathname(PyObject *self, PyObject *args)
 
2498
{
 
2499
        /* assume encoded strings won't more than double no of chars */
 
2500
        char inbuf[MAX_PATH*2];
 
2501
        char *inbufp = inbuf;
 
2502
        Py_ssize_t insize = sizeof(inbuf);
 
2503
        char outbuf[MAX_PATH*2];
 
2504
        char *temp;
 
2505
#ifdef Py_WIN_WIDE_FILENAMES
 
2506
        if (unicode_file_names()) {
 
2507
                PyUnicodeObject *po;
 
2508
                if (PyArg_ParseTuple(args, "U|:_getfullpathname", &po)) {
 
2509
                        Py_UNICODE *wpath = PyUnicode_AS_UNICODE(po);
 
2510
                        Py_UNICODE woutbuf[MAX_PATH*2], *woutbufp = woutbuf;
 
2511
                        Py_UNICODE *wtemp;
 
2512
                        DWORD result;
 
2513
                        PyObject *v;
 
2514
                        result = GetFullPathNameW(wpath,
 
2515
                                                   sizeof(woutbuf)/sizeof(woutbuf[0]),
 
2516
                                                    woutbuf, &wtemp);
 
2517
                        if (result > sizeof(woutbuf)/sizeof(woutbuf[0])) {
 
2518
                                woutbufp = malloc(result * sizeof(Py_UNICODE));
 
2519
                                if (!woutbufp)
 
2520
                                        return PyErr_NoMemory();
 
2521
                                result = GetFullPathNameW(wpath, result, woutbufp, &wtemp);
 
2522
                        }
 
2523
                        if (result)
 
2524
                                v = PyUnicode_FromUnicode(woutbufp, wcslen(woutbufp));
 
2525
                        else
 
2526
                                v = win32_error_unicode("GetFullPathNameW", wpath);
 
2527
                        if (woutbufp != woutbuf)
 
2528
                                free(woutbufp);
 
2529
                        return v;
 
2530
                }
 
2531
                /* Drop the argument parsing error as narrow strings
 
2532
                   are also valid. */
 
2533
                PyErr_Clear();
 
2534
        }
 
2535
#endif
 
2536
        if (!PyArg_ParseTuple (args, "et#:_getfullpathname",
 
2537
                               Py_FileSystemDefaultEncoding, &inbufp,
 
2538
                               &insize))
 
2539
                return NULL;
 
2540
        if (!GetFullPathName(inbuf, sizeof(outbuf)/sizeof(outbuf[0]),
 
2541
                             outbuf, &temp))
 
2542
                return win32_error("GetFullPathName", inbuf);
 
2543
        if (PyUnicode_Check(PyTuple_GetItem(args, 0))) {
 
2544
                return PyUnicode_Decode(outbuf, strlen(outbuf),
 
2545
                        Py_FileSystemDefaultEncoding, NULL);
 
2546
        }
 
2547
        return PyBytes_FromString(outbuf);
 
2548
} /* end of posix__getfullpathname */
 
2549
#endif /* MS_WINDOWS */
 
2550
 
 
2551
PyDoc_STRVAR(posix_mkdir__doc__,
 
2552
"mkdir(path [, mode=0777])\n\n\
 
2553
Create a directory.");
 
2554
 
 
2555
static PyObject *
 
2556
posix_mkdir(PyObject *self, PyObject *args)
 
2557
{
 
2558
        int res;
 
2559
        char *path = NULL;
 
2560
        int mode = 0777;
 
2561
 
 
2562
#ifdef Py_WIN_WIDE_FILENAMES
 
2563
        if (unicode_file_names()) {
 
2564
                PyUnicodeObject *po;
 
2565
                if (PyArg_ParseTuple(args, "U|i:mkdir", &po, &mode)) {
 
2566
                        Py_BEGIN_ALLOW_THREADS
 
2567
                        /* PyUnicode_AS_UNICODE OK without thread lock as
 
2568
                           it is a simple dereference. */
 
2569
                        res = CreateDirectoryW(PyUnicode_AS_UNICODE(po), NULL);
 
2570
                        Py_END_ALLOW_THREADS
 
2571
                        if (!res)
 
2572
                                return win32_error_unicode("mkdir", PyUnicode_AS_UNICODE(po));
 
2573
                        Py_INCREF(Py_None);
 
2574
                        return Py_None;
 
2575
                }
 
2576
                /* Drop the argument parsing error as narrow strings
 
2577
                   are also valid. */
 
2578
                PyErr_Clear();
 
2579
        }
 
2580
        if (!PyArg_ParseTuple(args, "et|i:mkdir",
 
2581
                              Py_FileSystemDefaultEncoding, &path, &mode))
 
2582
                return NULL;
 
2583
        Py_BEGIN_ALLOW_THREADS
 
2584
        /* PyUnicode_AS_UNICODE OK without thread lock as
 
2585
           it is a simple dereference. */
 
2586
        res = CreateDirectoryA(path, NULL);
 
2587
        Py_END_ALLOW_THREADS
 
2588
        if (!res) {
 
2589
                win32_error("mkdir", path);
 
2590
                PyMem_Free(path);
 
2591
                return NULL;
 
2592
        }
 
2593
        PyMem_Free(path);
 
2594
        Py_INCREF(Py_None);
 
2595
        return Py_None;
 
2596
#else
 
2597
 
 
2598
        if (!PyArg_ParseTuple(args, "et|i:mkdir",
 
2599
                              Py_FileSystemDefaultEncoding, &path, &mode))
 
2600
                return NULL;
 
2601
        Py_BEGIN_ALLOW_THREADS
 
2602
#if ( defined(__WATCOMC__) || defined(PYCC_VACPP) ) && !defined(__QNX__)
 
2603
        res = mkdir(path);
 
2604
#else
 
2605
        res = mkdir(path, mode);
 
2606
#endif
 
2607
        Py_END_ALLOW_THREADS
 
2608
        if (res < 0)
 
2609
                return posix_error_with_allocated_filename(path);
 
2610
        PyMem_Free(path);
 
2611
        Py_INCREF(Py_None);
 
2612
        return Py_None;
 
2613
#endif
 
2614
}
 
2615
 
 
2616
 
 
2617
/* sys/resource.h is needed for at least: wait3(), wait4(), broken nice. */
 
2618
#if defined(HAVE_SYS_RESOURCE_H)
 
2619
#include <sys/resource.h>
 
2620
#endif
 
2621
 
 
2622
 
 
2623
#ifdef HAVE_NICE
 
2624
PyDoc_STRVAR(posix_nice__doc__,
 
2625
"nice(inc) -> new_priority\n\n\
 
2626
Decrease the priority of process by inc and return the new priority.");
 
2627
 
 
2628
static PyObject *
 
2629
posix_nice(PyObject *self, PyObject *args)
 
2630
{
 
2631
        int increment, value;
 
2632
 
 
2633
        if (!PyArg_ParseTuple(args, "i:nice", &increment))
 
2634
                return NULL;
 
2635
 
 
2636
        /* There are two flavours of 'nice': one that returns the new
 
2637
           priority (as required by almost all standards out there) and the
 
2638
           Linux/FreeBSD/BSDI one, which returns '0' on success and advices
 
2639
           the use of getpriority() to get the new priority.
 
2640
 
 
2641
           If we are of the nice family that returns the new priority, we
 
2642
           need to clear errno before the call, and check if errno is filled
 
2643
           before calling posix_error() on a returnvalue of -1, because the
 
2644
           -1 may be the actual new priority! */
 
2645
 
 
2646
        errno = 0;
 
2647
        value = nice(increment);
 
2648
#if defined(HAVE_BROKEN_NICE) && defined(HAVE_GETPRIORITY)
 
2649
        if (value == 0)
 
2650
                value = getpriority(PRIO_PROCESS, 0);
 
2651
#endif
 
2652
        if (value == -1 && errno != 0)
 
2653
                /* either nice() or getpriority() returned an error */
 
2654
                return posix_error();
 
2655
        return PyLong_FromLong((long) value);
 
2656
}
 
2657
#endif /* HAVE_NICE */
 
2658
 
 
2659
PyDoc_STRVAR(posix_rename__doc__,
 
2660
"rename(old, new)\n\n\
 
2661
Rename a file or directory.");
 
2662
 
 
2663
static PyObject *
 
2664
posix_rename(PyObject *self, PyObject *args)
 
2665
{
 
2666
#ifdef MS_WINDOWS
 
2667
        PyObject *o1, *o2;
 
2668
        char *p1, *p2;
 
2669
        BOOL result;
 
2670
        if (unicode_file_names()) {
 
2671
            if (!PyArg_ParseTuple(args, "OO:rename", &o1, &o2))
 
2672
                goto error;
 
2673
            if (!convert_to_unicode(&o1))
 
2674
                goto error;
 
2675
            if (!convert_to_unicode(&o2)) {
 
2676
                Py_DECREF(o1);
 
2677
                goto error;
 
2678
            }
 
2679
            Py_BEGIN_ALLOW_THREADS
 
2680
            result = MoveFileW(PyUnicode_AsUnicode(o1),
 
2681
                               PyUnicode_AsUnicode(o2));
 
2682
            Py_END_ALLOW_THREADS
 
2683
            Py_DECREF(o1);
 
2684
            Py_DECREF(o2);
 
2685
            if (!result)
 
2686
                    return win32_error("rename", NULL);
 
2687
            Py_INCREF(Py_None);
 
2688
            return Py_None;
 
2689
error:
 
2690
            PyErr_Clear();
 
2691
        }
 
2692
        if (!PyArg_ParseTuple(args, "ss:rename", &p1, &p2))
 
2693
                return NULL;
 
2694
        Py_BEGIN_ALLOW_THREADS
 
2695
        result = MoveFileA(p1, p2);
 
2696
        Py_END_ALLOW_THREADS
 
2697
        if (!result)
 
2698
                return win32_error("rename", NULL);
 
2699
        Py_INCREF(Py_None);
 
2700
        return Py_None;
 
2701
#else
 
2702
        return posix_2str(args, "etet:rename", rename);
 
2703
#endif
 
2704
}
 
2705
 
 
2706
 
 
2707
PyDoc_STRVAR(posix_rmdir__doc__,
 
2708
"rmdir(path)\n\n\
 
2709
Remove a directory.");
 
2710
 
 
2711
static PyObject *
 
2712
posix_rmdir(PyObject *self, PyObject *args)
 
2713
{
 
2714
#ifdef MS_WINDOWS
 
2715
        return win32_1str(args, "rmdir", "y:rmdir", RemoveDirectoryA, "U:rmdir", RemoveDirectoryW);
 
2716
#else
 
2717
        return posix_1str(args, "et:rmdir", rmdir);
 
2718
#endif
 
2719
}
 
2720
 
 
2721
 
 
2722
PyDoc_STRVAR(posix_stat__doc__,
 
2723
"stat(path) -> stat result\n\n\
 
2724
Perform a stat system call on the given path.");
 
2725
 
 
2726
static PyObject *
 
2727
posix_stat(PyObject *self, PyObject *args)
 
2728
{
 
2729
#ifdef MS_WINDOWS
 
2730
        return posix_do_stat(self, args, "et:stat", STAT, "U:stat", win32_wstat);
 
2731
#else
 
2732
        return posix_do_stat(self, args, "et:stat", STAT, NULL, NULL);
 
2733
#endif
 
2734
}
 
2735
 
 
2736
 
 
2737
#ifdef HAVE_SYSTEM
 
2738
PyDoc_STRVAR(posix_system__doc__,
 
2739
"system(command) -> exit_status\n\n\
 
2740
Execute the command (a string) in a subshell.");
 
2741
 
 
2742
static PyObject *
 
2743
posix_system(PyObject *self, PyObject *args)
 
2744
{
 
2745
        long sts;
 
2746
#ifdef MS_WINDOWS
 
2747
        wchar_t *command;
 
2748
        if (!PyArg_ParseTuple(args, "u:system", &command))
 
2749
                return NULL;
 
2750
#else
 
2751
        char *command;
 
2752
        if (!PyArg_ParseTuple(args, "s:system", &command))
 
2753
                return NULL;
 
2754
#endif
 
2755
        Py_BEGIN_ALLOW_THREADS
 
2756
#ifdef MS_WINDOWS
 
2757
        sts = _wsystem(command);
 
2758
#else
 
2759
        sts = system(command);
 
2760
#endif
 
2761
        Py_END_ALLOW_THREADS
 
2762
        return PyLong_FromLong(sts);
 
2763
}
 
2764
#endif
 
2765
 
 
2766
 
 
2767
PyDoc_STRVAR(posix_umask__doc__,
 
2768
"umask(new_mask) -> old_mask\n\n\
 
2769
Set the current numeric umask and return the previous umask.");
 
2770
 
 
2771
static PyObject *
 
2772
posix_umask(PyObject *self, PyObject *args)
 
2773
{
 
2774
        int i;
 
2775
        if (!PyArg_ParseTuple(args, "i:umask", &i))
 
2776
                return NULL;
 
2777
        i = (int)umask(i);
 
2778
        if (i < 0)
 
2779
                return posix_error();
 
2780
        return PyLong_FromLong((long)i);
 
2781
}
 
2782
 
 
2783
 
 
2784
PyDoc_STRVAR(posix_unlink__doc__,
 
2785
"unlink(path)\n\n\
 
2786
Remove a file (same as remove(path)).");
 
2787
 
 
2788
PyDoc_STRVAR(posix_remove__doc__,
 
2789
"remove(path)\n\n\
 
2790
Remove a file (same as unlink(path)).");
 
2791
 
 
2792
static PyObject *
 
2793
posix_unlink(PyObject *self, PyObject *args)
 
2794
{
 
2795
#ifdef MS_WINDOWS
 
2796
        return win32_1str(args, "remove", "y:remove", DeleteFileA, "U:remove", DeleteFileW);
 
2797
#else
 
2798
        return posix_1str(args, "et:remove", unlink);
 
2799
#endif
 
2800
}
 
2801
 
 
2802
 
 
2803
#ifdef HAVE_UNAME
 
2804
PyDoc_STRVAR(posix_uname__doc__,
 
2805
"uname() -> (sysname, nodename, release, version, machine)\n\n\
 
2806
Return a tuple identifying the current operating system.");
 
2807
 
 
2808
static PyObject *
 
2809
posix_uname(PyObject *self, PyObject *noargs)
 
2810
{
 
2811
        struct utsname u;
 
2812
        int res;
 
2813
 
 
2814
        Py_BEGIN_ALLOW_THREADS
 
2815
        res = uname(&u);
 
2816
        Py_END_ALLOW_THREADS
 
2817
        if (res < 0)
 
2818
                return posix_error();
 
2819
        return Py_BuildValue("(sssss)",
 
2820
                             u.sysname,
 
2821
                             u.nodename,
 
2822
                             u.release,
 
2823
                             u.version,
 
2824
                             u.machine);
 
2825
}
 
2826
#endif /* HAVE_UNAME */
 
2827
 
 
2828
static int
 
2829
extract_time(PyObject *t, long* sec, long* usec)
 
2830
{
 
2831
        long intval;
 
2832
        if (PyFloat_Check(t)) {
 
2833
                double tval = PyFloat_AsDouble(t);
 
2834
                PyObject *intobj = Py_TYPE(t)->tp_as_number->nb_int(t);
 
2835
                if (!intobj)
 
2836
                        return -1;
 
2837
                intval = PyLong_AsLong(intobj);
 
2838
                Py_DECREF(intobj);
 
2839
                if (intval == -1 && PyErr_Occurred())
 
2840
                        return -1;
 
2841
                *sec = intval;
 
2842
                *usec = (long)((tval - intval) * 1e6); /* can't exceed 1000000 */
 
2843
                if (*usec < 0)
 
2844
                        /* If rounding gave us a negative number,
 
2845
                           truncate.  */
 
2846
                        *usec = 0;
 
2847
                return 0;
 
2848
        }
 
2849
        intval = PyLong_AsLong(t);
 
2850
        if (intval == -1 && PyErr_Occurred())
 
2851
                return -1;
 
2852
        *sec = intval;
 
2853
        *usec = 0;
 
2854
        return 0;
 
2855
}
 
2856
 
 
2857
PyDoc_STRVAR(posix_utime__doc__,
 
2858
"utime(path, (atime, mtime))\n\
 
2859
utime(path, None)\n\n\
 
2860
Set the access and modified time of the file to the given values.  If the\n\
 
2861
second form is used, set the access and modified times to the current time.");
 
2862
 
 
2863
static PyObject *
 
2864
posix_utime(PyObject *self, PyObject *args)
 
2865
{
 
2866
#ifdef Py_WIN_WIDE_FILENAMES
 
2867
        PyObject *arg;
 
2868
        PyUnicodeObject *obwpath;
 
2869
        wchar_t *wpath = NULL;
 
2870
        char *apath = NULL;
 
2871
        HANDLE hFile;
 
2872
        long atimesec, mtimesec, ausec, musec;
 
2873
        FILETIME atime, mtime;
 
2874
        PyObject *result = NULL;
 
2875
 
 
2876
        if (unicode_file_names()) {
 
2877
                if (PyArg_ParseTuple(args, "UO|:utime", &obwpath, &arg)) {
 
2878
                        wpath = PyUnicode_AS_UNICODE(obwpath);
 
2879
                        Py_BEGIN_ALLOW_THREADS
 
2880
                        hFile = CreateFileW(wpath, FILE_WRITE_ATTRIBUTES, 0,
 
2881
                                            NULL, OPEN_EXISTING,
 
2882
                                            FILE_FLAG_BACKUP_SEMANTICS, NULL);
 
2883
                        Py_END_ALLOW_THREADS
 
2884
                        if (hFile == INVALID_HANDLE_VALUE)
 
2885
                                return win32_error_unicode("utime", wpath);
 
2886
                } else
 
2887
                        /* Drop the argument parsing error as narrow strings
 
2888
                           are also valid. */
 
2889
                        PyErr_Clear();
 
2890
        }
 
2891
        if (!wpath) {
 
2892
                if (!PyArg_ParseTuple(args, "etO:utime",
 
2893
                                Py_FileSystemDefaultEncoding, &apath, &arg))
 
2894
                        return NULL;
 
2895
                Py_BEGIN_ALLOW_THREADS
 
2896
                hFile = CreateFileA(apath, FILE_WRITE_ATTRIBUTES, 0,
 
2897
                                    NULL, OPEN_EXISTING,
 
2898
                                    FILE_FLAG_BACKUP_SEMANTICS, NULL);
 
2899
                Py_END_ALLOW_THREADS
 
2900
                if (hFile == INVALID_HANDLE_VALUE) {
 
2901
                        win32_error("utime", apath);
 
2902
                        PyMem_Free(apath);
 
2903
                        return NULL;
 
2904
                }
 
2905
                PyMem_Free(apath);
 
2906
        }
 
2907
        
 
2908
        if (arg == Py_None) {
 
2909
                SYSTEMTIME now;
 
2910
                GetSystemTime(&now);
 
2911
                if (!SystemTimeToFileTime(&now, &mtime) ||
 
2912
                    !SystemTimeToFileTime(&now, &atime)) {
 
2913
                        win32_error("utime", NULL);
 
2914
                        goto done;
 
2915
                    }
 
2916
        }
 
2917
        else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
 
2918
                PyErr_SetString(PyExc_TypeError,
 
2919
                                "utime() arg 2 must be a tuple (atime, mtime)");
 
2920
                goto done;
 
2921
        }
 
2922
        else {
 
2923
                if (extract_time(PyTuple_GET_ITEM(arg, 0),
 
2924
                                 &atimesec, &ausec) == -1)
 
2925
                        goto done;
 
2926
                time_t_to_FILE_TIME(atimesec, 1000*ausec, &atime);
 
2927
                if (extract_time(PyTuple_GET_ITEM(arg, 1),
 
2928
                                 &mtimesec, &musec) == -1)
 
2929
                        goto done;
 
2930
                time_t_to_FILE_TIME(mtimesec, 1000*musec, &mtime);
 
2931
        }
 
2932
        if (!SetFileTime(hFile, NULL, &atime, &mtime)) {
 
2933
                /* Avoid putting the file name into the error here,
 
2934
                   as that may confuse the user into believing that
 
2935
                   something is wrong with the file, when it also
 
2936
                   could be the time stamp that gives a problem. */
 
2937
                win32_error("utime", NULL);
 
2938
        }
 
2939
        Py_INCREF(Py_None);
 
2940
        result = Py_None;
 
2941
done:
 
2942
        CloseHandle(hFile);
 
2943
        return result;
 
2944
#else /* Py_WIN_WIDE_FILENAMES */
 
2945
 
 
2946
        char *path = NULL;
 
2947
        long atime, mtime, ausec, musec;
 
2948
        int res;
 
2949
        PyObject* arg;
 
2950
 
 
2951
#if defined(HAVE_UTIMES)
 
2952
        struct timeval buf[2];
 
2953
#define ATIME buf[0].tv_sec
 
2954
#define MTIME buf[1].tv_sec
 
2955
#elif defined(HAVE_UTIME_H)
 
2956
/* XXX should define struct utimbuf instead, above */
 
2957
        struct utimbuf buf;
 
2958
#define ATIME buf.actime
 
2959
#define MTIME buf.modtime
 
2960
#define UTIME_ARG &buf
 
2961
#else /* HAVE_UTIMES */
 
2962
        time_t buf[2];
 
2963
#define ATIME buf[0]
 
2964
#define MTIME buf[1]
 
2965
#define UTIME_ARG buf
 
2966
#endif /* HAVE_UTIMES */
 
2967
 
 
2968
 
 
2969
        if (!PyArg_ParseTuple(args, "etO:utime",
 
2970
                                  Py_FileSystemDefaultEncoding, &path, &arg))
 
2971
                return NULL;
 
2972
        if (arg == Py_None) {
 
2973
                /* optional time values not given */
 
2974
                Py_BEGIN_ALLOW_THREADS
 
2975
                res = utime(path, NULL);
 
2976
                Py_END_ALLOW_THREADS
 
2977
        }
 
2978
        else if (!PyTuple_Check(arg) || PyTuple_Size(arg) != 2) {
 
2979
                PyErr_SetString(PyExc_TypeError,
 
2980
                                "utime() arg 2 must be a tuple (atime, mtime)");
 
2981
                PyMem_Free(path);
 
2982
                return NULL;
 
2983
        }
 
2984
        else {
 
2985
                if (extract_time(PyTuple_GET_ITEM(arg, 0),
 
2986
                                 &atime, &ausec) == -1) {
 
2987
                        PyMem_Free(path);
 
2988
                        return NULL;
 
2989
                }
 
2990
                if (extract_time(PyTuple_GET_ITEM(arg, 1),
 
2991
                                 &mtime, &musec) == -1) {
 
2992
                        PyMem_Free(path);
 
2993
                        return NULL;
 
2994
                }
 
2995
                ATIME = atime;
 
2996
                MTIME = mtime;
 
2997
#ifdef HAVE_UTIMES
 
2998
                buf[0].tv_usec = ausec;
 
2999
                buf[1].tv_usec = musec;
 
3000
                Py_BEGIN_ALLOW_THREADS
 
3001
                res = utimes(path, buf);
 
3002
                Py_END_ALLOW_THREADS
 
3003
#else
 
3004
                Py_BEGIN_ALLOW_THREADS
 
3005
                res = utime(path, UTIME_ARG);
 
3006
                Py_END_ALLOW_THREADS
 
3007
#endif /* HAVE_UTIMES */
 
3008
        }
 
3009
        if (res < 0) {
 
3010
                return posix_error_with_allocated_filename(path);
 
3011
        }
 
3012
        PyMem_Free(path);
 
3013
        Py_INCREF(Py_None);
 
3014
        return Py_None;
 
3015
#undef UTIME_ARG
 
3016
#undef ATIME
 
3017
#undef MTIME
 
3018
#endif /* Py_WIN_WIDE_FILENAMES */
 
3019
}
 
3020
 
 
3021
 
 
3022
/* Process operations */
 
3023
 
 
3024
PyDoc_STRVAR(posix__exit__doc__,
 
3025
"_exit(status)\n\n\
 
3026
Exit to the system with specified status, without normal exit processing.");
 
3027
 
 
3028
static PyObject *
 
3029
posix__exit(PyObject *self, PyObject *args)
 
3030
{
 
3031
        int sts;
 
3032
        if (!PyArg_ParseTuple(args, "i:_exit", &sts))
 
3033
                return NULL;
 
3034
        _exit(sts);
 
3035
        return NULL; /* Make gcc -Wall happy */
 
3036
}
 
3037
 
 
3038
#if defined(HAVE_EXECV) || defined(HAVE_SPAWNV)
 
3039
static void
 
3040
free_string_array(char **array, Py_ssize_t count)
 
3041
{
 
3042
        Py_ssize_t i;
 
3043
        for (i = 0; i < count; i++)
 
3044
                PyMem_Free(array[i]);
 
3045
        PyMem_DEL(array);
 
3046
}
 
3047
#endif
 
3048
 
 
3049
 
 
3050
#ifdef HAVE_EXECV
 
3051
PyDoc_STRVAR(posix_execv__doc__,
 
3052
"execv(path, args)\n\n\
 
3053
Execute an executable path with arguments, replacing current process.\n\
 
3054
\n\
 
3055
        path: path of executable file\n\
 
3056
        args: tuple or list of strings");
 
3057
 
 
3058
static PyObject *
 
3059
posix_execv(PyObject *self, PyObject *args)
 
3060
{
 
3061
        char *path;
 
3062
        PyObject *argv;
 
3063
        char **argvlist;
 
3064
        Py_ssize_t i, argc;
 
3065
        PyObject *(*getitem)(PyObject *, Py_ssize_t);
 
3066
 
 
3067
        /* execv has two arguments: (path, argv), where
 
3068
           argv is a list or tuple of strings. */
 
3069
 
 
3070
        if (!PyArg_ParseTuple(args, "etO:execv",
 
3071
                              Py_FileSystemDefaultEncoding,
 
3072
                              &path, &argv))
 
3073
                return NULL;
 
3074
        if (PyList_Check(argv)) {
 
3075
                argc = PyList_Size(argv);
 
3076
                getitem = PyList_GetItem;
 
3077
        }
 
3078
        else if (PyTuple_Check(argv)) {
 
3079
                argc = PyTuple_Size(argv);
 
3080
                getitem = PyTuple_GetItem;
 
3081
        }
 
3082
        else {
 
3083
                PyErr_SetString(PyExc_TypeError, "execv() arg 2 must be a tuple or list");
 
3084
                PyMem_Free(path);
 
3085
                return NULL;
 
3086
        }
 
3087
        if (argc < 1) {
 
3088
                PyErr_SetString(PyExc_ValueError, "execv() arg 2 must not be empty");
 
3089
                PyMem_Free(path);
 
3090
                return NULL;
 
3091
        }
 
3092
 
 
3093
        argvlist = PyMem_NEW(char *, argc+1);
 
3094
        if (argvlist == NULL) {
 
3095
                PyMem_Free(path);
 
3096
                return PyErr_NoMemory();
 
3097
        }
 
3098
        for (i = 0; i < argc; i++) {
 
3099
                if (!PyArg_Parse((*getitem)(argv, i), "et",
 
3100
                                 Py_FileSystemDefaultEncoding,
 
3101
                                 &argvlist[i])) {
 
3102
                        free_string_array(argvlist, i);
 
3103
                        PyErr_SetString(PyExc_TypeError,
 
3104
                                        "execv() arg 2 must contain only strings");
 
3105
                        PyMem_Free(path);
 
3106
                        return NULL;
 
3107
 
 
3108
                }
 
3109
        }
 
3110
        argvlist[argc] = NULL;
 
3111
 
 
3112
        execv(path, argvlist);
 
3113
 
 
3114
        /* If we get here it's definitely an error */
 
3115
 
 
3116
        free_string_array(argvlist, argc);
 
3117
        PyMem_Free(path);
 
3118
        return posix_error();
 
3119
}
 
3120
 
 
3121
 
 
3122
PyDoc_STRVAR(posix_execve__doc__,
 
3123
"execve(path, args, env)\n\n\
 
3124
Execute a path with arguments and environment, replacing current process.\n\
 
3125
\n\
 
3126
        path: path of executable file\n\
 
3127
        args: tuple or list of arguments\n\
 
3128
        env: dictionary of strings mapping to strings");
 
3129
 
 
3130
static PyObject *
 
3131
posix_execve(PyObject *self, PyObject *args)
 
3132
{
 
3133
        char *path;
 
3134
        PyObject *argv, *env;
 
3135
        char **argvlist;
 
3136
        char **envlist;
 
3137
        PyObject *key, *val, *keys=NULL, *vals=NULL;
 
3138
        Py_ssize_t i, pos, argc, envc;
 
3139
        PyObject *(*getitem)(PyObject *, Py_ssize_t);
 
3140
        Py_ssize_t lastarg = 0;
 
3141
 
 
3142
        /* execve has three arguments: (path, argv, env), where
 
3143
           argv is a list or tuple of strings and env is a dictionary
 
3144
           like posix.environ. */
 
3145
 
 
3146
        if (!PyArg_ParseTuple(args, "etOO:execve",
 
3147
                              Py_FileSystemDefaultEncoding,
 
3148
                              &path, &argv, &env))
 
3149
                return NULL;
 
3150
        if (PyList_Check(argv)) {
 
3151
                argc = PyList_Size(argv);
 
3152
                getitem = PyList_GetItem;
 
3153
        }
 
3154
        else if (PyTuple_Check(argv)) {
 
3155
                argc = PyTuple_Size(argv);
 
3156
                getitem = PyTuple_GetItem;
 
3157
        }
 
3158
        else {
 
3159
                PyErr_SetString(PyExc_TypeError,
 
3160
                                "execve() arg 2 must be a tuple or list");
 
3161
                goto fail_0;
 
3162
        }
 
3163
        if (!PyMapping_Check(env)) {
 
3164
                PyErr_SetString(PyExc_TypeError,
 
3165
                                "execve() arg 3 must be a mapping object");
 
3166
                goto fail_0;
 
3167
        }
 
3168
 
 
3169
        argvlist = PyMem_NEW(char *, argc+1);
 
3170
        if (argvlist == NULL) {
 
3171
                PyErr_NoMemory();
 
3172
                goto fail_0;
 
3173
        }
 
3174
        for (i = 0; i < argc; i++) {
 
3175
                if (!PyArg_Parse((*getitem)(argv, i),
 
3176
                                 "et;execve() arg 2 must contain only strings",
 
3177
                                 Py_FileSystemDefaultEncoding,
 
3178
                                 &argvlist[i]))
 
3179
                {
 
3180
                        lastarg = i;
 
3181
                        goto fail_1;
 
3182
                }
 
3183
        }
 
3184
        lastarg = argc;
 
3185
        argvlist[argc] = NULL;
 
3186
 
 
3187
        i = PyMapping_Size(env);
 
3188
        if (i < 0)
 
3189
                goto fail_1;
 
3190
        envlist = PyMem_NEW(char *, i + 1);
 
3191
        if (envlist == NULL) {
 
3192
                PyErr_NoMemory();
 
3193
                goto fail_1;
 
3194
        }
 
3195
        envc = 0;
 
3196
        keys = PyMapping_Keys(env);
 
3197
        vals = PyMapping_Values(env);
 
3198
        if (!keys || !vals)
 
3199
                goto fail_2;
 
3200
        if (!PyList_Check(keys) || !PyList_Check(vals)) {
 
3201
                PyErr_SetString(PyExc_TypeError,
 
3202
                        "execve(): env.keys() or env.values() is not a list");
 
3203
                goto fail_2;
 
3204
        }
 
3205
 
 
3206
        for (pos = 0; pos < i; pos++) {
 
3207
                char *p, *k, *v;
 
3208
                size_t len;
 
3209
 
 
3210
                key = PyList_GetItem(keys, pos);
 
3211
                val = PyList_GetItem(vals, pos);
 
3212
                if (!key || !val)
 
3213
                        goto fail_2;
 
3214
 
 
3215
                if (!PyArg_Parse(
 
3216
                            key,
 
3217
                            "s;execve() arg 3 contains a non-string key",
 
3218
                            &k) ||
 
3219
                    !PyArg_Parse(
 
3220
                            val,
 
3221
                            "s;execve() arg 3 contains a non-string value",
 
3222
                            &v))
 
3223
                {
 
3224
                        goto fail_2;
 
3225
                }
 
3226
 
 
3227
#if defined(PYOS_OS2)
 
3228
        /* Omit Pseudo-Env Vars that Would Confuse Programs if Passed On */
 
3229
        if (stricmp(k, "BEGINLIBPATH") != 0 && stricmp(k, "ENDLIBPATH") != 0) {
 
3230
#endif
 
3231
                len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
 
3232
                p = PyMem_NEW(char, len);
 
3233
                if (p == NULL) {
 
3234
                        PyErr_NoMemory();
 
3235
                        goto fail_2;
 
3236
                }
 
3237
                PyOS_snprintf(p, len, "%s=%s", k, v);
 
3238
                envlist[envc++] = p;
 
3239
#if defined(PYOS_OS2)
 
3240
    }
 
3241
#endif
 
3242
        }
 
3243
        envlist[envc] = 0;
 
3244
 
 
3245
        execve(path, argvlist, envlist);
 
3246
 
 
3247
        /* If we get here it's definitely an error */
 
3248
 
 
3249
        (void) posix_error();
 
3250
 
 
3251
  fail_2:
 
3252
        while (--envc >= 0)
 
3253
                PyMem_DEL(envlist[envc]);
 
3254
        PyMem_DEL(envlist);
 
3255
  fail_1:
 
3256
        free_string_array(argvlist, lastarg);
 
3257
        Py_XDECREF(vals);
 
3258
        Py_XDECREF(keys);
 
3259
  fail_0:
 
3260
        PyMem_Free(path);
 
3261
        return NULL;
 
3262
}
 
3263
#endif /* HAVE_EXECV */
 
3264
 
 
3265
 
 
3266
#ifdef HAVE_SPAWNV
 
3267
PyDoc_STRVAR(posix_spawnv__doc__,
 
3268
"spawnv(mode, path, args)\n\n\
 
3269
Execute the program 'path' in a new process.\n\
 
3270
\n\
 
3271
        mode: mode of process creation\n\
 
3272
        path: path of executable file\n\
 
3273
        args: tuple or list of strings");
 
3274
 
 
3275
static PyObject *
 
3276
posix_spawnv(PyObject *self, PyObject *args)
 
3277
{
 
3278
        char *path;
 
3279
        PyObject *argv;
 
3280
        char **argvlist;
 
3281
        int mode, i;
 
3282
        Py_ssize_t argc;
 
3283
        Py_intptr_t spawnval;
 
3284
        PyObject *(*getitem)(PyObject *, Py_ssize_t);
 
3285
 
 
3286
        /* spawnv has three arguments: (mode, path, argv), where
 
3287
           argv is a list or tuple of strings. */
 
3288
 
 
3289
        if (!PyArg_ParseTuple(args, "ietO:spawnv", &mode,
 
3290
                              Py_FileSystemDefaultEncoding,
 
3291
                              &path, &argv))
 
3292
                return NULL;
 
3293
        if (PyList_Check(argv)) {
 
3294
                argc = PyList_Size(argv);
 
3295
                getitem = PyList_GetItem;
 
3296
        }
 
3297
        else if (PyTuple_Check(argv)) {
 
3298
                argc = PyTuple_Size(argv);
 
3299
                getitem = PyTuple_GetItem;
 
3300
        }
 
3301
        else {
 
3302
                PyErr_SetString(PyExc_TypeError,
 
3303
                                "spawnv() arg 2 must be a tuple or list");
 
3304
                PyMem_Free(path);
 
3305
                return NULL;
 
3306
        }
 
3307
 
 
3308
        argvlist = PyMem_NEW(char *, argc+1);
 
3309
        if (argvlist == NULL) {
 
3310
                PyMem_Free(path);
 
3311
                return PyErr_NoMemory();
 
3312
        }
 
3313
        for (i = 0; i < argc; i++) {
 
3314
                if (!PyArg_Parse((*getitem)(argv, i), "et",
 
3315
                                 Py_FileSystemDefaultEncoding,
 
3316
                                 &argvlist[i])) {
 
3317
                        free_string_array(argvlist, i);
 
3318
                        PyErr_SetString(
 
3319
                                PyExc_TypeError,
 
3320
                                "spawnv() arg 2 must contain only strings");
 
3321
                        PyMem_Free(path);
 
3322
                        return NULL;
 
3323
                }
 
3324
        }
 
3325
        argvlist[argc] = NULL;
 
3326
 
 
3327
#if defined(PYOS_OS2) && defined(PYCC_GCC)
 
3328
        Py_BEGIN_ALLOW_THREADS
 
3329
        spawnval = spawnv(mode, path, argvlist);
 
3330
        Py_END_ALLOW_THREADS
 
3331
#else
 
3332
        if (mode == _OLD_P_OVERLAY)
 
3333
                mode = _P_OVERLAY;
 
3334
 
 
3335
        Py_BEGIN_ALLOW_THREADS
 
3336
        spawnval = _spawnv(mode, path, argvlist);
 
3337
        Py_END_ALLOW_THREADS
 
3338
#endif
 
3339
 
 
3340
        free_string_array(argvlist, argc);
 
3341
        PyMem_Free(path);
 
3342
 
 
3343
        if (spawnval == -1)
 
3344
                return posix_error();
 
3345
        else
 
3346
#if SIZEOF_LONG == SIZEOF_VOID_P
 
3347
                return Py_BuildValue("l", (long) spawnval);
 
3348
#else
 
3349
                return Py_BuildValue("L", (PY_LONG_LONG) spawnval);
 
3350
#endif
 
3351
}
 
3352
 
 
3353
 
 
3354
PyDoc_STRVAR(posix_spawnve__doc__,
 
3355
"spawnve(mode, path, args, env)\n\n\
 
3356
Execute the program 'path' in a new process.\n\
 
3357
\n\
 
3358
        mode: mode of process creation\n\
 
3359
        path: path of executable file\n\
 
3360
        args: tuple or list of arguments\n\
 
3361
        env: dictionary of strings mapping to strings");
 
3362
 
 
3363
static PyObject *
 
3364
posix_spawnve(PyObject *self, PyObject *args)
 
3365
{
 
3366
        char *path;
 
3367
        PyObject *argv, *env;
 
3368
        char **argvlist;
 
3369
        char **envlist;
 
3370
        PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
 
3371
        int mode, pos, envc;
 
3372
        Py_ssize_t argc, i;
 
3373
        Py_intptr_t spawnval;
 
3374
        PyObject *(*getitem)(PyObject *, Py_ssize_t);
 
3375
        Py_ssize_t lastarg = 0;
 
3376
 
 
3377
        /* spawnve has four arguments: (mode, path, argv, env), where
 
3378
           argv is a list or tuple of strings and env is a dictionary
 
3379
           like posix.environ. */
 
3380
 
 
3381
        if (!PyArg_ParseTuple(args, "ietOO:spawnve", &mode,
 
3382
                              Py_FileSystemDefaultEncoding,
 
3383
                              &path, &argv, &env))
 
3384
                return NULL;
 
3385
        if (PyList_Check(argv)) {
 
3386
                argc = PyList_Size(argv);
 
3387
                getitem = PyList_GetItem;
 
3388
        }
 
3389
        else if (PyTuple_Check(argv)) {
 
3390
                argc = PyTuple_Size(argv);
 
3391
                getitem = PyTuple_GetItem;
 
3392
        }
 
3393
        else {
 
3394
                PyErr_SetString(PyExc_TypeError,
 
3395
                                "spawnve() arg 2 must be a tuple or list");
 
3396
                goto fail_0;
 
3397
        }
 
3398
        if (!PyMapping_Check(env)) {
 
3399
                PyErr_SetString(PyExc_TypeError,
 
3400
                                "spawnve() arg 3 must be a mapping object");
 
3401
                goto fail_0;
 
3402
        }
 
3403
 
 
3404
        argvlist = PyMem_NEW(char *, argc+1);
 
3405
        if (argvlist == NULL) {
 
3406
                PyErr_NoMemory();
 
3407
                goto fail_0;
 
3408
        }
 
3409
        for (i = 0; i < argc; i++) {
 
3410
                if (!PyArg_Parse((*getitem)(argv, i),
 
3411
                             "et;spawnve() arg 2 must contain only strings",
 
3412
                                 Py_FileSystemDefaultEncoding,
 
3413
                                 &argvlist[i]))
 
3414
                {
 
3415
                        lastarg = i;
 
3416
                        goto fail_1;
 
3417
                }
 
3418
        }
 
3419
        lastarg = argc;
 
3420
        argvlist[argc] = NULL;
 
3421
 
 
3422
        i = PyMapping_Size(env);
 
3423
        if (i < 0)
 
3424
                goto fail_1;
 
3425
        envlist = PyMem_NEW(char *, i + 1);
 
3426
        if (envlist == NULL) {
 
3427
                PyErr_NoMemory();
 
3428
                goto fail_1;
 
3429
        }
 
3430
        envc = 0;
 
3431
        keys = PyMapping_Keys(env);
 
3432
        vals = PyMapping_Values(env);
 
3433
        if (!keys || !vals)
 
3434
                goto fail_2;
 
3435
        if (!PyList_Check(keys) || !PyList_Check(vals)) {
 
3436
                PyErr_SetString(PyExc_TypeError,
 
3437
                        "spawnve(): env.keys() or env.values() is not a list");
 
3438
                goto fail_2;
 
3439
        }
 
3440
 
 
3441
        for (pos = 0; pos < i; pos++) {
 
3442
                char *p, *k, *v;
 
3443
                size_t len;
 
3444
 
 
3445
                key = PyList_GetItem(keys, pos);
 
3446
                val = PyList_GetItem(vals, pos);
 
3447
                if (!key || !val)
 
3448
                        goto fail_2;
 
3449
 
 
3450
                if (!PyArg_Parse(
 
3451
                            key,
 
3452
                            "s;spawnve() arg 3 contains a non-string key",
 
3453
                            &k) ||
 
3454
                    !PyArg_Parse(
 
3455
                            val,
 
3456
                            "s;spawnve() arg 3 contains a non-string value",
 
3457
                            &v))
 
3458
                {
 
3459
                        goto fail_2;
 
3460
                }
 
3461
                len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
 
3462
                p = PyMem_NEW(char, len);
 
3463
                if (p == NULL) {
 
3464
                        PyErr_NoMemory();
 
3465
                        goto fail_2;
 
3466
                }
 
3467
                PyOS_snprintf(p, len, "%s=%s", k, v);
 
3468
                envlist[envc++] = p;
 
3469
        }
 
3470
        envlist[envc] = 0;
 
3471
 
 
3472
#if defined(PYOS_OS2) && defined(PYCC_GCC)
 
3473
        Py_BEGIN_ALLOW_THREADS
 
3474
        spawnval = spawnve(mode, path, argvlist, envlist);
 
3475
        Py_END_ALLOW_THREADS
 
3476
#else
 
3477
        if (mode == _OLD_P_OVERLAY)
 
3478
                mode = _P_OVERLAY;
 
3479
 
 
3480
        Py_BEGIN_ALLOW_THREADS
 
3481
        spawnval = _spawnve(mode, path, argvlist, envlist);
 
3482
        Py_END_ALLOW_THREADS
 
3483
#endif
 
3484
 
 
3485
        if (spawnval == -1)
 
3486
                (void) posix_error();
 
3487
        else
 
3488
#if SIZEOF_LONG == SIZEOF_VOID_P
 
3489
                res = Py_BuildValue("l", (long) spawnval);
 
3490
#else
 
3491
                res = Py_BuildValue("L", (PY_LONG_LONG) spawnval);
 
3492
#endif
 
3493
 
 
3494
  fail_2:
 
3495
        while (--envc >= 0)
 
3496
                PyMem_DEL(envlist[envc]);
 
3497
        PyMem_DEL(envlist);
 
3498
  fail_1:
 
3499
        free_string_array(argvlist, lastarg);
 
3500
        Py_XDECREF(vals);
 
3501
        Py_XDECREF(keys);
 
3502
  fail_0:
 
3503
        PyMem_Free(path);
 
3504
        return res;
 
3505
}
 
3506
 
 
3507
/* OS/2 supports spawnvp & spawnvpe natively */
 
3508
#if defined(PYOS_OS2)
 
3509
PyDoc_STRVAR(posix_spawnvp__doc__,
 
3510
"spawnvp(mode, file, args)\n\n\
 
3511
Execute the program 'file' in a new process, using the environment\n\
 
3512
search path to find the file.\n\
 
3513
\n\
 
3514
        mode: mode of process creation\n\
 
3515
        file: executable file name\n\
 
3516
        args: tuple or list of strings");
 
3517
 
 
3518
static PyObject *
 
3519
posix_spawnvp(PyObject *self, PyObject *args)
 
3520
{
 
3521
        char *path;
 
3522
        PyObject *argv;
 
3523
        char **argvlist;
 
3524
        int mode, i, argc;
 
3525
        Py_intptr_t spawnval;
 
3526
        PyObject *(*getitem)(PyObject *, Py_ssize_t);
 
3527
 
 
3528
        /* spawnvp has three arguments: (mode, path, argv), where
 
3529
           argv is a list or tuple of strings. */
 
3530
 
 
3531
        if (!PyArg_ParseTuple(args, "ietO:spawnvp", &mode,
 
3532
                              Py_FileSystemDefaultEncoding,
 
3533
                              &path, &argv))
 
3534
                return NULL;
 
3535
        if (PyList_Check(argv)) {
 
3536
                argc = PyList_Size(argv);
 
3537
                getitem = PyList_GetItem;
 
3538
        }
 
3539
        else if (PyTuple_Check(argv)) {
 
3540
                argc = PyTuple_Size(argv);
 
3541
                getitem = PyTuple_GetItem;
 
3542
        }
 
3543
        else {
 
3544
                PyErr_SetString(PyExc_TypeError,
 
3545
                                "spawnvp() arg 2 must be a tuple or list");
 
3546
                PyMem_Free(path);
 
3547
                return NULL;
 
3548
        }
 
3549
 
 
3550
        argvlist = PyMem_NEW(char *, argc+1);
 
3551
        if (argvlist == NULL) {
 
3552
                PyMem_Free(path);
 
3553
                return PyErr_NoMemory();
 
3554
        }
 
3555
        for (i = 0; i < argc; i++) {
 
3556
                if (!PyArg_Parse((*getitem)(argv, i), "et",
 
3557
                                 Py_FileSystemDefaultEncoding,
 
3558
                                 &argvlist[i])) {
 
3559
                        free_string_array(argvlist, i);
 
3560
                        PyErr_SetString(
 
3561
                                PyExc_TypeError,
 
3562
                                "spawnvp() arg 2 must contain only strings");
 
3563
                        PyMem_Free(path);
 
3564
                        return NULL;
 
3565
                }
 
3566
        }
 
3567
        argvlist[argc] = NULL;
 
3568
 
 
3569
        Py_BEGIN_ALLOW_THREADS
 
3570
#if defined(PYCC_GCC)
 
3571
        spawnval = spawnvp(mode, path, argvlist);
 
3572
#else
 
3573
        spawnval = _spawnvp(mode, path, argvlist);
 
3574
#endif
 
3575
        Py_END_ALLOW_THREADS
 
3576
 
 
3577
        free_string_array(argvlist, argc);
 
3578
        PyMem_Free(path);
 
3579
 
 
3580
        if (spawnval == -1)
 
3581
                return posix_error();
 
3582
        else
 
3583
                return Py_BuildValue("l", (long) spawnval);
 
3584
}
 
3585
 
 
3586
 
 
3587
PyDoc_STRVAR(posix_spawnvpe__doc__,
 
3588
"spawnvpe(mode, file, args, env)\n\n\
 
3589
Execute the program 'file' in a new process, using the environment\n\
 
3590
search path to find the file.\n\
 
3591
\n\
 
3592
        mode: mode of process creation\n\
 
3593
        file: executable file name\n\
 
3594
        args: tuple or list of arguments\n\
 
3595
        env: dictionary of strings mapping to strings");
 
3596
 
 
3597
static PyObject *
 
3598
posix_spawnvpe(PyObject *self, PyObject *args)
 
3599
{
 
3600
        char *path;
 
3601
        PyObject *argv, *env;
 
3602
        char **argvlist;
 
3603
        char **envlist;
 
3604
        PyObject *key, *val, *keys=NULL, *vals=NULL, *res=NULL;
 
3605
        int mode, i, pos, argc, envc;
 
3606
        Py_intptr_t spawnval;
 
3607
        PyObject *(*getitem)(PyObject *, Py_ssize_t);
 
3608
        int lastarg = 0;
 
3609
 
 
3610
        /* spawnvpe has four arguments: (mode, path, argv, env), where
 
3611
           argv is a list or tuple of strings and env is a dictionary
 
3612
           like posix.environ. */
 
3613
 
 
3614
        if (!PyArg_ParseTuple(args, "ietOO:spawnvpe", &mode,
 
3615
                              Py_FileSystemDefaultEncoding,
 
3616
                              &path, &argv, &env))
 
3617
                return NULL;
 
3618
        if (PyList_Check(argv)) {
 
3619
                argc = PyList_Size(argv);
 
3620
                getitem = PyList_GetItem;
 
3621
        }
 
3622
        else if (PyTuple_Check(argv)) {
 
3623
                argc = PyTuple_Size(argv);
 
3624
                getitem = PyTuple_GetItem;
 
3625
        }
 
3626
        else {
 
3627
                PyErr_SetString(PyExc_TypeError,
 
3628
                                "spawnvpe() arg 2 must be a tuple or list");
 
3629
                goto fail_0;
 
3630
        }
 
3631
        if (!PyMapping_Check(env)) {
 
3632
                PyErr_SetString(PyExc_TypeError,
 
3633
                                "spawnvpe() arg 3 must be a mapping object");
 
3634
                goto fail_0;
 
3635
        }
 
3636
 
 
3637
        argvlist = PyMem_NEW(char *, argc+1);
 
3638
        if (argvlist == NULL) {
 
3639
                PyErr_NoMemory();
 
3640
                goto fail_0;
 
3641
        }
 
3642
        for (i = 0; i < argc; i++) {
 
3643
                if (!PyArg_Parse((*getitem)(argv, i),
 
3644
                             "et;spawnvpe() arg 2 must contain only strings",
 
3645
                                 Py_FileSystemDefaultEncoding,
 
3646
                                 &argvlist[i]))
 
3647
                {
 
3648
                        lastarg = i;
 
3649
                        goto fail_1;
 
3650
                }
 
3651
        }
 
3652
        lastarg = argc;
 
3653
        argvlist[argc] = NULL;
 
3654
 
 
3655
        i = PyMapping_Size(env);
 
3656
        if (i < 0)
 
3657
                goto fail_1;
 
3658
        envlist = PyMem_NEW(char *, i + 1);
 
3659
        if (envlist == NULL) {
 
3660
                PyErr_NoMemory();
 
3661
                goto fail_1;
 
3662
        }
 
3663
        envc = 0;
 
3664
        keys = PyMapping_Keys(env);
 
3665
        vals = PyMapping_Values(env);
 
3666
        if (!keys || !vals)
 
3667
                goto fail_2;
 
3668
        if (!PyList_Check(keys) || !PyList_Check(vals)) {
 
3669
                PyErr_SetString(PyExc_TypeError,
 
3670
                        "spawnvpe(): env.keys() or env.values() is not a list");
 
3671
                goto fail_2;
 
3672
        }
 
3673
 
 
3674
        for (pos = 0; pos < i; pos++) {
 
3675
                char *p, *k, *v;
 
3676
                size_t len;
 
3677
 
 
3678
                key = PyList_GetItem(keys, pos);
 
3679
                val = PyList_GetItem(vals, pos);
 
3680
                if (!key || !val)
 
3681
                        goto fail_2;
 
3682
 
 
3683
                if (!PyArg_Parse(
 
3684
                            key,
 
3685
                            "s;spawnvpe() arg 3 contains a non-string key",
 
3686
                            &k) ||
 
3687
                    !PyArg_Parse(
 
3688
                            val,
 
3689
                            "s;spawnvpe() arg 3 contains a non-string value",
 
3690
                            &v))
 
3691
                {
 
3692
                        goto fail_2;
 
3693
                }
 
3694
                len = PyUnicode_GetSize(key) + PyUnicode_GetSize(val) + 2;
 
3695
                p = PyMem_NEW(char, len);
 
3696
                if (p == NULL) {
 
3697
                        PyErr_NoMemory();
 
3698
                        goto fail_2;
 
3699
                }
 
3700
                PyOS_snprintf(p, len, "%s=%s", k, v);
 
3701
                envlist[envc++] = p;
 
3702
        }
 
3703
        envlist[envc] = 0;
 
3704
 
 
3705
        Py_BEGIN_ALLOW_THREADS
 
3706
#if defined(PYCC_GCC)
 
3707
        spawnval = spawnvpe(mode, path, argvlist, envlist);
 
3708
#else
 
3709
        spawnval = _spawnvpe(mode, path, argvlist, envlist);
 
3710
#endif
 
3711
        Py_END_ALLOW_THREADS
 
3712
 
 
3713
        if (spawnval == -1)
 
3714
                (void) posix_error();
 
3715
        else
 
3716
                res = Py_BuildValue("l", (long) spawnval);
 
3717
 
 
3718
  fail_2:
 
3719
        while (--envc >= 0)
 
3720
                PyMem_DEL(envlist[envc]);
 
3721
        PyMem_DEL(envlist);
 
3722
  fail_1:
 
3723
        free_string_array(argvlist, lastarg);
 
3724
        Py_XDECREF(vals);
 
3725
        Py_XDECREF(keys);
 
3726
  fail_0:
 
3727
        PyMem_Free(path);
 
3728
        return res;
 
3729
}
 
3730
#endif /* PYOS_OS2 */
 
3731
#endif /* HAVE_SPAWNV */
 
3732
 
 
3733
 
 
3734
#ifdef HAVE_FORK1
 
3735
PyDoc_STRVAR(posix_fork1__doc__,
 
3736
"fork1() -> pid\n\n\
 
3737
Fork a child process with a single multiplexed (i.e., not bound) thread.\n\
 
3738
\n\
 
3739
Return 0 to child process and PID of child to parent process.");
 
3740
 
 
3741
static PyObject *
 
3742
posix_fork1(PyObject *self, PyObject *noargs)
 
3743
{
 
3744
        pid_t pid = fork1();
 
3745
        if (pid == -1)
 
3746
                return posix_error();
 
3747
        if (pid == 0)
 
3748
                PyOS_AfterFork();
 
3749
        return PyLong_FromLong(pid);
 
3750
}
 
3751
#endif
 
3752
 
 
3753
 
 
3754
#ifdef HAVE_FORK
 
3755
PyDoc_STRVAR(posix_fork__doc__,
 
3756
"fork() -> pid\n\n\
 
3757
Fork a child process.\n\
 
3758
Return 0 to child process and PID of child to parent process.");
 
3759
 
 
3760
static PyObject *
 
3761
posix_fork(PyObject *self, PyObject *noargs)
 
3762
{
 
3763
        pid_t pid = fork();
 
3764
        if (pid == -1)
 
3765
                return posix_error();
 
3766
        if (pid == 0)
 
3767
                PyOS_AfterFork();
 
3768
        return PyLong_FromLong(pid);
 
3769
}
 
3770
#endif
 
3771
 
 
3772
/* AIX uses /dev/ptc but is otherwise the same as /dev/ptmx */
 
3773
/* IRIX has both /dev/ptc and /dev/ptmx, use ptmx */
 
3774
#if defined(HAVE_DEV_PTC) && !defined(HAVE_DEV_PTMX)
 
3775
#define DEV_PTY_FILE "/dev/ptc"
 
3776
#define HAVE_DEV_PTMX
 
3777
#else
 
3778
#define DEV_PTY_FILE "/dev/ptmx"
 
3779
#endif
 
3780
 
 
3781
#if defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX)
 
3782
#ifdef HAVE_PTY_H
 
3783
#include <pty.h>
 
3784
#else
 
3785
#ifdef HAVE_LIBUTIL_H
 
3786
#include <libutil.h>
 
3787
#endif /* HAVE_LIBUTIL_H */
 
3788
#endif /* HAVE_PTY_H */
 
3789
#ifdef HAVE_STROPTS_H
 
3790
#include <stropts.h>
 
3791
#endif
 
3792
#endif /* defined(HAVE_OPENPTY) || defined(HAVE_FORKPTY) || defined(HAVE_DEV_PTMX */
 
3793
 
 
3794
#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
 
3795
PyDoc_STRVAR(posix_openpty__doc__,
 
3796
"openpty() -> (master_fd, slave_fd)\n\n\
 
3797
Open a pseudo-terminal, returning open fd's for both master and slave end.\n");
 
3798
 
 
3799
static PyObject *
 
3800
posix_openpty(PyObject *self, PyObject *noargs)
 
3801
{
 
3802
        int master_fd, slave_fd;
 
3803
#ifndef HAVE_OPENPTY
 
3804
        char * slave_name;
 
3805
#endif
 
3806
#if defined(HAVE_DEV_PTMX) && !defined(HAVE_OPENPTY) && !defined(HAVE__GETPTY)
 
3807
        PyOS_sighandler_t sig_saved;
 
3808
#ifdef sun
 
3809
        extern char *ptsname(int fildes);
 
3810
#endif
 
3811
#endif
 
3812
 
 
3813
#ifdef HAVE_OPENPTY
 
3814
        if (openpty(&master_fd, &slave_fd, NULL, NULL, NULL) != 0)
 
3815
                return posix_error();
 
3816
#elif defined(HAVE__GETPTY)
 
3817
        slave_name = _getpty(&master_fd, O_RDWR, 0666, 0);
 
3818
        if (slave_name == NULL)
 
3819
                return posix_error();
 
3820
 
 
3821
        slave_fd = open(slave_name, O_RDWR);
 
3822
        if (slave_fd < 0)
 
3823
                return posix_error();
 
3824
#else
 
3825
        master_fd = open(DEV_PTY_FILE, O_RDWR | O_NOCTTY); /* open master */
 
3826
        if (master_fd < 0)
 
3827
                return posix_error();
 
3828
        sig_saved = PyOS_setsig(SIGCHLD, SIG_DFL);
 
3829
        /* change permission of slave */
 
3830
        if (grantpt(master_fd) < 0) {
 
3831
                PyOS_setsig(SIGCHLD, sig_saved);
 
3832
                return posix_error();
 
3833
        }
 
3834
        /* unlock slave */
 
3835
        if (unlockpt(master_fd) < 0) {
 
3836
                PyOS_setsig(SIGCHLD, sig_saved);
 
3837
                return posix_error();
 
3838
        }
 
3839
        PyOS_setsig(SIGCHLD, sig_saved);
 
3840
        slave_name = ptsname(master_fd); /* get name of slave */
 
3841
        if (slave_name == NULL)
 
3842
                return posix_error();
 
3843
        slave_fd = open(slave_name, O_RDWR | O_NOCTTY); /* open slave */
 
3844
        if (slave_fd < 0)
 
3845
                return posix_error();
 
3846
#if !defined(__CYGWIN__) && !defined(HAVE_DEV_PTC)
 
3847
        ioctl(slave_fd, I_PUSH, "ptem"); /* push ptem */
 
3848
        ioctl(slave_fd, I_PUSH, "ldterm"); /* push ldterm */
 
3849
#ifndef __hpux
 
3850
        ioctl(slave_fd, I_PUSH, "ttcompat"); /* push ttcompat */
 
3851
#endif /* __hpux */
 
3852
#endif /* HAVE_CYGWIN */
 
3853
#endif /* HAVE_OPENPTY */
 
3854
 
 
3855
        return Py_BuildValue("(ii)", master_fd, slave_fd);
 
3856
 
 
3857
}
 
3858
#endif /* defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX) */
 
3859
 
 
3860
#ifdef HAVE_FORKPTY
 
3861
PyDoc_STRVAR(posix_forkpty__doc__,
 
3862
"forkpty() -> (pid, master_fd)\n\n\
 
3863
Fork a new process with a new pseudo-terminal as controlling tty.\n\n\
 
3864
Like fork(), return 0 as pid to child process, and PID of child to parent.\n\
 
3865
To both, return fd of newly opened pseudo-terminal.\n");
 
3866
 
 
3867
static PyObject *
 
3868
posix_forkpty(PyObject *self, PyObject *noargs)
 
3869
{
 
3870
        int master_fd = -1;
 
3871
        pid_t pid;
 
3872
 
 
3873
        pid = forkpty(&master_fd, NULL, NULL, NULL);
 
3874
        if (pid == -1)
 
3875
                return posix_error();
 
3876
        if (pid == 0)
 
3877
                PyOS_AfterFork();
 
3878
        return Py_BuildValue("(li)", pid, master_fd);
 
3879
}
 
3880
#endif
 
3881
 
 
3882
#ifdef HAVE_GETEGID
 
3883
PyDoc_STRVAR(posix_getegid__doc__,
 
3884
"getegid() -> egid\n\n\
 
3885
Return the current process's effective group id.");
 
3886
 
 
3887
static PyObject *
 
3888
posix_getegid(PyObject *self, PyObject *noargs)
 
3889
{
 
3890
        return PyLong_FromLong((long)getegid());
 
3891
}
 
3892
#endif
 
3893
 
 
3894
 
 
3895
#ifdef HAVE_GETEUID
 
3896
PyDoc_STRVAR(posix_geteuid__doc__,
 
3897
"geteuid() -> euid\n\n\
 
3898
Return the current process's effective user id.");
 
3899
 
 
3900
static PyObject *
 
3901
posix_geteuid(PyObject *self, PyObject *noargs)
 
3902
{
 
3903
        return PyLong_FromLong((long)geteuid());
 
3904
}
 
3905
#endif
 
3906
 
 
3907
 
 
3908
#ifdef HAVE_GETGID
 
3909
PyDoc_STRVAR(posix_getgid__doc__,
 
3910
"getgid() -> gid\n\n\
 
3911
Return the current process's group id.");
 
3912
 
 
3913
static PyObject *
 
3914
posix_getgid(PyObject *self, PyObject *noargs)
 
3915
{
 
3916
        return PyLong_FromLong((long)getgid());
 
3917
}
 
3918
#endif
 
3919
 
 
3920
 
 
3921
PyDoc_STRVAR(posix_getpid__doc__,
 
3922
"getpid() -> pid\n\n\
 
3923
Return the current process id");
 
3924
 
 
3925
static PyObject *
 
3926
posix_getpid(PyObject *self, PyObject *noargs)
 
3927
{
 
3928
        return PyLong_FromLong((long)getpid());
 
3929
}
 
3930
 
 
3931
 
 
3932
#ifdef HAVE_GETGROUPS
 
3933
PyDoc_STRVAR(posix_getgroups__doc__,
 
3934
"getgroups() -> list of group IDs\n\n\
 
3935
Return list of supplemental group IDs for the process.");
 
3936
 
 
3937
static PyObject *
 
3938
posix_getgroups(PyObject *self, PyObject *noargs)
 
3939
{
 
3940
    PyObject *result = NULL;
 
3941
 
 
3942
#ifdef NGROUPS_MAX
 
3943
#define MAX_GROUPS NGROUPS_MAX
 
3944
#else
 
3945
        /* defined to be 16 on Solaris7, so this should be a small number */
 
3946
#define MAX_GROUPS 64
 
3947
#endif
 
3948
        gid_t grouplist[MAX_GROUPS];
 
3949
        int n;
 
3950
 
 
3951
        n = getgroups(MAX_GROUPS, grouplist);
 
3952
        if (n < 0)
 
3953
            posix_error();
 
3954
        else {
 
3955
            result = PyList_New(n);
 
3956
            if (result != NULL) {
 
3957
                int i;
 
3958
                for (i = 0; i < n; ++i) {
 
3959
                    PyObject *o = PyLong_FromLong((long)grouplist[i]);
 
3960
                    if (o == NULL) {
 
3961
                        Py_DECREF(result);
 
3962
                        result = NULL;
 
3963
                        break;
 
3964
                    }
 
3965
                    PyList_SET_ITEM(result, i, o);
 
3966
                }
 
3967
            }
 
3968
        }
 
3969
 
 
3970
    return result;
 
3971
}
 
3972
#endif
 
3973
 
 
3974
#ifdef HAVE_GETPGID
 
3975
PyDoc_STRVAR(posix_getpgid__doc__,
 
3976
"getpgid(pid) -> pgid\n\n\
 
3977
Call the system call getpgid().");
 
3978
 
 
3979
static PyObject *
 
3980
posix_getpgid(PyObject *self, PyObject *args)
 
3981
{
 
3982
        int pid, pgid;
 
3983
        if (!PyArg_ParseTuple(args, "i:getpgid", &pid))
 
3984
                return NULL;
 
3985
        pgid = getpgid(pid);
 
3986
        if (pgid < 0)
 
3987
                return posix_error();
 
3988
        return PyLong_FromLong((long)pgid);
 
3989
}
 
3990
#endif /* HAVE_GETPGID */
 
3991
 
 
3992
 
 
3993
#ifdef HAVE_GETPGRP
 
3994
PyDoc_STRVAR(posix_getpgrp__doc__,
 
3995
"getpgrp() -> pgrp\n\n\
 
3996
Return the current process group id.");
 
3997
 
 
3998
static PyObject *
 
3999
posix_getpgrp(PyObject *self, PyObject *noargs)
 
4000
{
 
4001
#ifdef GETPGRP_HAVE_ARG
 
4002
        return PyLong_FromLong((long)getpgrp(0));
 
4003
#else /* GETPGRP_HAVE_ARG */
 
4004
        return PyLong_FromLong((long)getpgrp());
 
4005
#endif /* GETPGRP_HAVE_ARG */
 
4006
}
 
4007
#endif /* HAVE_GETPGRP */
 
4008
 
 
4009
 
 
4010
#ifdef HAVE_SETPGRP
 
4011
PyDoc_STRVAR(posix_setpgrp__doc__,
 
4012
"setpgrp()\n\n\
 
4013
Make this process a session leader.");
 
4014
 
 
4015
static PyObject *
 
4016
posix_setpgrp(PyObject *self, PyObject *noargs)
 
4017
{
 
4018
#ifdef SETPGRP_HAVE_ARG
 
4019
        if (setpgrp(0, 0) < 0)
 
4020
#else /* SETPGRP_HAVE_ARG */
 
4021
        if (setpgrp() < 0)
 
4022
#endif /* SETPGRP_HAVE_ARG */
 
4023
                return posix_error();
 
4024
        Py_INCREF(Py_None);
 
4025
        return Py_None;
 
4026
}
 
4027
 
 
4028
#endif /* HAVE_SETPGRP */
 
4029
 
 
4030
#ifdef HAVE_GETPPID
 
4031
PyDoc_STRVAR(posix_getppid__doc__,
 
4032
"getppid() -> ppid\n\n\
 
4033
Return the parent's process id.");
 
4034
 
 
4035
static PyObject *
 
4036
posix_getppid(PyObject *self, PyObject *noargs)
 
4037
{
 
4038
        return PyLong_FromLong((long)getppid());
 
4039
}
 
4040
#endif
 
4041
 
 
4042
 
 
4043
#ifdef HAVE_GETLOGIN
 
4044
PyDoc_STRVAR(posix_getlogin__doc__,
 
4045
"getlogin() -> string\n\n\
 
4046
Return the actual login name.");
 
4047
 
 
4048
static PyObject *
 
4049
posix_getlogin(PyObject *self, PyObject *noargs)
 
4050
{
 
4051
        PyObject *result = NULL;
 
4052
        char *name;
 
4053
        int old_errno = errno;
 
4054
 
 
4055
        errno = 0;
 
4056
        name = getlogin();
 
4057
        if (name == NULL) {
 
4058
            if (errno)
 
4059
                posix_error();
 
4060
            else
 
4061
                PyErr_SetString(PyExc_OSError,
 
4062
                                "unable to determine login name");
 
4063
        }
 
4064
        else
 
4065
            result = PyUnicode_FromString(name);
 
4066
        errno = old_errno;
 
4067
 
 
4068
    return result;
 
4069
}
 
4070
#endif
 
4071
 
 
4072
#ifdef HAVE_GETUID
 
4073
PyDoc_STRVAR(posix_getuid__doc__,
 
4074
"getuid() -> uid\n\n\
 
4075
Return the current process's user id.");
 
4076
 
 
4077
static PyObject *
 
4078
posix_getuid(PyObject *self, PyObject *noargs)
 
4079
{
 
4080
        return PyLong_FromLong((long)getuid());
 
4081
}
 
4082
#endif
 
4083
 
 
4084
 
 
4085
#ifdef HAVE_KILL
 
4086
PyDoc_STRVAR(posix_kill__doc__,
 
4087
"kill(pid, sig)\n\n\
 
4088
Kill a process with a signal.");
 
4089
 
 
4090
static PyObject *
 
4091
posix_kill(PyObject *self, PyObject *args)
 
4092
{
 
4093
        pid_t pid;
 
4094
        int sig;
 
4095
        if (!PyArg_ParseTuple(args, "ii:kill", &pid, &sig))
 
4096
                return NULL;
 
4097
#if defined(PYOS_OS2) && !defined(PYCC_GCC)
 
4098
    if (sig == XCPT_SIGNAL_INTR || sig == XCPT_SIGNAL_BREAK) {
 
4099
        APIRET rc;
 
4100
        if ((rc = DosSendSignalException(pid, sig)) != NO_ERROR)
 
4101
            return os2_error(rc);
 
4102
 
 
4103
    } else if (sig == XCPT_SIGNAL_KILLPROC) {
 
4104
        APIRET rc;
 
4105
        if ((rc = DosKillProcess(DKP_PROCESS, pid)) != NO_ERROR)
 
4106
            return os2_error(rc);
 
4107
 
 
4108
    } else
 
4109
        return NULL; /* Unrecognized Signal Requested */
 
4110
#else
 
4111
        if (kill(pid, sig) == -1)
 
4112
                return posix_error();
 
4113
#endif
 
4114
        Py_INCREF(Py_None);
 
4115
        return Py_None;
 
4116
}
 
4117
#endif
 
4118
 
 
4119
#ifdef HAVE_KILLPG
 
4120
PyDoc_STRVAR(posix_killpg__doc__,
 
4121
"killpg(pgid, sig)\n\n\
 
4122
Kill a process group with a signal.");
 
4123
 
 
4124
static PyObject *
 
4125
posix_killpg(PyObject *self, PyObject *args)
 
4126
{
 
4127
        int pgid, sig;
 
4128
        if (!PyArg_ParseTuple(args, "ii:killpg", &pgid, &sig))
 
4129
                return NULL;
 
4130
        if (killpg(pgid, sig) == -1)
 
4131
                return posix_error();
 
4132
        Py_INCREF(Py_None);
 
4133
        return Py_None;
 
4134
}
 
4135
#endif
 
4136
 
 
4137
#ifdef HAVE_PLOCK
 
4138
 
 
4139
#ifdef HAVE_SYS_LOCK_H
 
4140
#include <sys/lock.h>
 
4141
#endif
 
4142
 
 
4143
PyDoc_STRVAR(posix_plock__doc__,
 
4144
"plock(op)\n\n\
 
4145
Lock program segments into memory.");
 
4146
 
 
4147
static PyObject *
 
4148
posix_plock(PyObject *self, PyObject *args)
 
4149
{
 
4150
        int op;
 
4151
        if (!PyArg_ParseTuple(args, "i:plock", &op))
 
4152
                return NULL;
 
4153
        if (plock(op) == -1)
 
4154
                return posix_error();
 
4155
        Py_INCREF(Py_None);
 
4156
        return Py_None;
 
4157
}
 
4158
#endif
 
4159
 
 
4160
 
 
4161
 
 
4162
 
 
4163
#ifdef HAVE_SETUID
 
4164
PyDoc_STRVAR(posix_setuid__doc__,
 
4165
"setuid(uid)\n\n\
 
4166
Set the current process's user id.");
 
4167
 
 
4168
static PyObject *
 
4169
posix_setuid(PyObject *self, PyObject *args)
 
4170
{
 
4171
        int uid;
 
4172
        if (!PyArg_ParseTuple(args, "i:setuid", &uid))
 
4173
                return NULL;
 
4174
        if (setuid(uid) < 0)
 
4175
                return posix_error();
 
4176
        Py_INCREF(Py_None);
 
4177
        return Py_None;
 
4178
}
 
4179
#endif /* HAVE_SETUID */
 
4180
 
 
4181
 
 
4182
#ifdef HAVE_SETEUID
 
4183
PyDoc_STRVAR(posix_seteuid__doc__,
 
4184
"seteuid(uid)\n\n\
 
4185
Set the current process's effective user id.");
 
4186
 
 
4187
static PyObject *
 
4188
posix_seteuid (PyObject *self, PyObject *args)
 
4189
{
 
4190
        int euid;
 
4191
        if (!PyArg_ParseTuple(args, "i", &euid)) {
 
4192
                return NULL;
 
4193
        } else if (seteuid(euid) < 0) {
 
4194
                return posix_error();
 
4195
        } else {
 
4196
                Py_INCREF(Py_None);
 
4197
                return Py_None;
 
4198
        }
 
4199
}
 
4200
#endif /* HAVE_SETEUID */
 
4201
 
 
4202
#ifdef HAVE_SETEGID
 
4203
PyDoc_STRVAR(posix_setegid__doc__,
 
4204
"setegid(gid)\n\n\
 
4205
Set the current process's effective group id.");
 
4206
 
 
4207
static PyObject *
 
4208
posix_setegid (PyObject *self, PyObject *args)
 
4209
{
 
4210
        int egid;
 
4211
        if (!PyArg_ParseTuple(args, "i", &egid)) {
 
4212
                return NULL;
 
4213
        } else if (setegid(egid) < 0) {
 
4214
                return posix_error();
 
4215
        } else {
 
4216
                Py_INCREF(Py_None);
 
4217
                return Py_None;
 
4218
        }
 
4219
}
 
4220
#endif /* HAVE_SETEGID */
 
4221
 
 
4222
#ifdef HAVE_SETREUID
 
4223
PyDoc_STRVAR(posix_setreuid__doc__,
 
4224
"setreuid(ruid, euid)\n\n\
 
4225
Set the current process's real and effective user ids.");
 
4226
 
 
4227
static PyObject *
 
4228
posix_setreuid (PyObject *self, PyObject *args)
 
4229
{
 
4230
        int ruid, euid;
 
4231
        if (!PyArg_ParseTuple(args, "ii", &ruid, &euid)) {
 
4232
                return NULL;
 
4233
        } else if (setreuid(ruid, euid) < 0) {
 
4234
                return posix_error();
 
4235
        } else {
 
4236
                Py_INCREF(Py_None);
 
4237
                return Py_None;
 
4238
        }
 
4239
}
 
4240
#endif /* HAVE_SETREUID */
 
4241
 
 
4242
#ifdef HAVE_SETREGID
 
4243
PyDoc_STRVAR(posix_setregid__doc__,
 
4244
"setregid(rgid, egid)\n\n\
 
4245
Set the current process's real and effective group ids.");
 
4246
 
 
4247
static PyObject *
 
4248
posix_setregid (PyObject *self, PyObject *args)
 
4249
{
 
4250
        int rgid, egid;
 
4251
        if (!PyArg_ParseTuple(args, "ii", &rgid, &egid)) {
 
4252
                return NULL;
 
4253
        } else if (setregid(rgid, egid) < 0) {
 
4254
                return posix_error();
 
4255
        } else {
 
4256
                Py_INCREF(Py_None);
 
4257
                return Py_None;
 
4258
        }
 
4259
}
 
4260
#endif /* HAVE_SETREGID */
 
4261
 
 
4262
#ifdef HAVE_SETGID
 
4263
PyDoc_STRVAR(posix_setgid__doc__,
 
4264
"setgid(gid)\n\n\
 
4265
Set the current process's group id.");
 
4266
 
 
4267
static PyObject *
 
4268
posix_setgid(PyObject *self, PyObject *args)
 
4269
{
 
4270
        int gid;
 
4271
        if (!PyArg_ParseTuple(args, "i:setgid", &gid))
 
4272
                return NULL;
 
4273
        if (setgid(gid) < 0)
 
4274
                return posix_error();
 
4275
        Py_INCREF(Py_None);
 
4276
        return Py_None;
 
4277
}
 
4278
#endif /* HAVE_SETGID */
 
4279
 
 
4280
#ifdef HAVE_SETGROUPS
 
4281
PyDoc_STRVAR(posix_setgroups__doc__,
 
4282
"setgroups(list)\n\n\
 
4283
Set the groups of the current process to list.");
 
4284
 
 
4285
static PyObject *
 
4286
posix_setgroups(PyObject *self, PyObject *groups)
 
4287
{
 
4288
        int i, len;
 
4289
        gid_t grouplist[MAX_GROUPS];
 
4290
 
 
4291
        if (!PySequence_Check(groups)) {
 
4292
                PyErr_SetString(PyExc_TypeError, "setgroups argument must be a sequence");
 
4293
                return NULL;
 
4294
        }
 
4295
        len = PySequence_Size(groups);
 
4296
        if (len > MAX_GROUPS) {
 
4297
                PyErr_SetString(PyExc_ValueError, "too many groups");
 
4298
                return NULL;
 
4299
        }
 
4300
        for(i = 0; i < len; i++) {
 
4301
                PyObject *elem;
 
4302
                elem = PySequence_GetItem(groups, i);
 
4303
                if (!elem)
 
4304
                        return NULL;
 
4305
                if (!PyLong_Check(elem)) {
 
4306
                        PyErr_SetString(PyExc_TypeError,
 
4307
                                        "groups must be integers");
 
4308
                        Py_DECREF(elem);
 
4309
                        return NULL;
 
4310
                } else {
 
4311
                        unsigned long x = PyLong_AsUnsignedLong(elem);
 
4312
                        if (PyErr_Occurred()) {
 
4313
                                PyErr_SetString(PyExc_TypeError, 
 
4314
                                                "group id too big");
 
4315
                                Py_DECREF(elem);
 
4316
                                return NULL;
 
4317
                        }
 
4318
                        grouplist[i] = x;
 
4319
                        /* read back the value to see if it fitted in gid_t */
 
4320
                        if (grouplist[i] != x) {
 
4321
                                PyErr_SetString(PyExc_TypeError,
 
4322
                                                "group id too big");
 
4323
                                Py_DECREF(elem);
 
4324
                                return NULL;
 
4325
                        }
 
4326
                }
 
4327
                Py_DECREF(elem);
 
4328
        }
 
4329
 
 
4330
        if (setgroups(len, grouplist) < 0)
 
4331
                return posix_error();
 
4332
        Py_INCREF(Py_None);
 
4333
        return Py_None;
 
4334
}
 
4335
#endif /* HAVE_SETGROUPS */
 
4336
 
 
4337
#if defined(HAVE_WAIT3) || defined(HAVE_WAIT4)
 
4338
static PyObject *
 
4339
wait_helper(pid_t pid, int status, struct rusage *ru)
 
4340
{
 
4341
        PyObject *result;
 
4342
        static PyObject *struct_rusage;
 
4343
 
 
4344
        if (pid == -1)
 
4345
                return posix_error();
 
4346
 
 
4347
        if (struct_rusage == NULL) {
 
4348
                PyObject *m = PyImport_ImportModuleNoBlock("resource");
 
4349
                if (m == NULL)
 
4350
                        return NULL;
 
4351
                struct_rusage = PyObject_GetAttrString(m, "struct_rusage");
 
4352
                Py_DECREF(m);
 
4353
                if (struct_rusage == NULL)
 
4354
                        return NULL;
 
4355
        }
 
4356
 
 
4357
        /* XXX(nnorwitz): Copied (w/mods) from resource.c, there should be only one. */
 
4358
        result = PyStructSequence_New((PyTypeObject*) struct_rusage);
 
4359
        if (!result)
 
4360
                return NULL;
 
4361
 
 
4362
#ifndef doubletime
 
4363
#define doubletime(TV) ((double)(TV).tv_sec + (TV).tv_usec * 0.000001)
 
4364
#endif
 
4365
 
 
4366
        PyStructSequence_SET_ITEM(result, 0,
 
4367
                        PyFloat_FromDouble(doubletime(ru->ru_utime)));
 
4368
        PyStructSequence_SET_ITEM(result, 1,
 
4369
                        PyFloat_FromDouble(doubletime(ru->ru_stime)));
 
4370
#define SET_INT(result, index, value)\
 
4371
                PyStructSequence_SET_ITEM(result, index, PyLong_FromLong(value))
 
4372
        SET_INT(result, 2, ru->ru_maxrss);
 
4373
        SET_INT(result, 3, ru->ru_ixrss);
 
4374
        SET_INT(result, 4, ru->ru_idrss);
 
4375
        SET_INT(result, 5, ru->ru_isrss);
 
4376
        SET_INT(result, 6, ru->ru_minflt);
 
4377
        SET_INT(result, 7, ru->ru_majflt);
 
4378
        SET_INT(result, 8, ru->ru_nswap);
 
4379
        SET_INT(result, 9, ru->ru_inblock);
 
4380
        SET_INT(result, 10, ru->ru_oublock);
 
4381
        SET_INT(result, 11, ru->ru_msgsnd);
 
4382
        SET_INT(result, 12, ru->ru_msgrcv);
 
4383
        SET_INT(result, 13, ru->ru_nsignals);
 
4384
        SET_INT(result, 14, ru->ru_nvcsw);
 
4385
        SET_INT(result, 15, ru->ru_nivcsw);
 
4386
#undef SET_INT
 
4387
 
 
4388
        if (PyErr_Occurred()) {
 
4389
                Py_DECREF(result);
 
4390
                return NULL;
 
4391
        }
 
4392
 
 
4393
        return Py_BuildValue("iiN", pid, status, result);
 
4394
}
 
4395
#endif /* HAVE_WAIT3 || HAVE_WAIT4 */
 
4396
 
 
4397
#ifdef HAVE_WAIT3
 
4398
PyDoc_STRVAR(posix_wait3__doc__,
 
4399
"wait3(options) -> (pid, status, rusage)\n\n\
 
4400
Wait for completion of a child process.");
 
4401
 
 
4402
static PyObject *
 
4403
posix_wait3(PyObject *self, PyObject *args)
 
4404
{
 
4405
        pid_t pid;
 
4406
        int options;
 
4407
        struct rusage ru;
 
4408
        WAIT_TYPE status;
 
4409
        WAIT_STATUS_INT(status) = 0;
 
4410
 
 
4411
        if (!PyArg_ParseTuple(args, "i:wait3", &options))
 
4412
                return NULL;
 
4413
 
 
4414
        Py_BEGIN_ALLOW_THREADS
 
4415
        pid = wait3(&status, options, &ru);
 
4416
        Py_END_ALLOW_THREADS
 
4417
 
 
4418
        return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
 
4419
}
 
4420
#endif /* HAVE_WAIT3 */
 
4421
 
 
4422
#ifdef HAVE_WAIT4
 
4423
PyDoc_STRVAR(posix_wait4__doc__,
 
4424
"wait4(pid, options) -> (pid, status, rusage)\n\n\
 
4425
Wait for completion of a given child process.");
 
4426
 
 
4427
static PyObject *
 
4428
posix_wait4(PyObject *self, PyObject *args)
 
4429
{
 
4430
        pid_t pid;
 
4431
        int options;
 
4432
        struct rusage ru;
 
4433
        WAIT_TYPE status;
 
4434
        WAIT_STATUS_INT(status) = 0;
 
4435
 
 
4436
        if (!PyArg_ParseTuple(args, "ii:wait4", &pid, &options))
 
4437
                return NULL;
 
4438
 
 
4439
        Py_BEGIN_ALLOW_THREADS
 
4440
        pid = wait4(pid, &status, options, &ru);
 
4441
        Py_END_ALLOW_THREADS
 
4442
 
 
4443
        return wait_helper(pid, WAIT_STATUS_INT(status), &ru);
 
4444
}
 
4445
#endif /* HAVE_WAIT4 */
 
4446
 
 
4447
#ifdef HAVE_WAITPID
 
4448
PyDoc_STRVAR(posix_waitpid__doc__,
 
4449
"waitpid(pid, options) -> (pid, status)\n\n\
 
4450
Wait for completion of a given child process.");
 
4451
 
 
4452
static PyObject *
 
4453
posix_waitpid(PyObject *self, PyObject *args)
 
4454
{
 
4455
        pid_t pid;
 
4456
        int options;
 
4457
        WAIT_TYPE status;
 
4458
        WAIT_STATUS_INT(status) = 0;
 
4459
 
 
4460
        if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
 
4461
                return NULL;
 
4462
        Py_BEGIN_ALLOW_THREADS
 
4463
        pid = waitpid(pid, &status, options);
 
4464
        Py_END_ALLOW_THREADS
 
4465
        if (pid == -1)
 
4466
                return posix_error();
 
4467
 
 
4468
        return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
 
4469
}
 
4470
 
 
4471
#elif defined(HAVE_CWAIT)
 
4472
 
 
4473
/* MS C has a variant of waitpid() that's usable for most purposes. */
 
4474
PyDoc_STRVAR(posix_waitpid__doc__,
 
4475
"waitpid(pid, options) -> (pid, status << 8)\n\n"
 
4476
"Wait for completion of a given process.  options is ignored on Windows.");
 
4477
 
 
4478
static PyObject *
 
4479
posix_waitpid(PyObject *self, PyObject *args)
 
4480
{
 
4481
        Py_intptr_t pid;
 
4482
        int status, options;
 
4483
 
 
4484
        if (!PyArg_ParseTuple(args, "ii:waitpid", &pid, &options))
 
4485
                return NULL;
 
4486
        Py_BEGIN_ALLOW_THREADS
 
4487
        pid = _cwait(&status, pid, options);
 
4488
        Py_END_ALLOW_THREADS
 
4489
        if (pid == -1)
 
4490
                return posix_error();
 
4491
 
 
4492
        /* shift the status left a byte so this is more like the POSIX waitpid */
 
4493
        return Py_BuildValue("ii", pid, status << 8);
 
4494
}
 
4495
#endif /* HAVE_WAITPID || HAVE_CWAIT */
 
4496
 
 
4497
#ifdef HAVE_WAIT
 
4498
PyDoc_STRVAR(posix_wait__doc__,
 
4499
"wait() -> (pid, status)\n\n\
 
4500
Wait for completion of a child process.");
 
4501
 
 
4502
static PyObject *
 
4503
posix_wait(PyObject *self, PyObject *noargs)
 
4504
{
 
4505
        pid_t pid;
 
4506
        WAIT_TYPE status;
 
4507
        WAIT_STATUS_INT(status) = 0;
 
4508
 
 
4509
        Py_BEGIN_ALLOW_THREADS
 
4510
        pid = wait(&status);
 
4511
        Py_END_ALLOW_THREADS
 
4512
        if (pid == -1)
 
4513
                return posix_error();
 
4514
 
 
4515
        return Py_BuildValue("ii", pid, WAIT_STATUS_INT(status));
 
4516
}
 
4517
#endif
 
4518
 
 
4519
 
 
4520
PyDoc_STRVAR(posix_lstat__doc__,
 
4521
"lstat(path) -> stat result\n\n\
 
4522
Like stat(path), but do not follow symbolic links.");
 
4523
 
 
4524
static PyObject *
 
4525
posix_lstat(PyObject *self, PyObject *args)
 
4526
{
 
4527
#ifdef HAVE_LSTAT
 
4528
        return posix_do_stat(self, args, "et:lstat", lstat, NULL, NULL);
 
4529
#else /* !HAVE_LSTAT */
 
4530
#ifdef MS_WINDOWS
 
4531
        return posix_do_stat(self, args, "et:lstat", STAT, "U:lstat", win32_wstat);
 
4532
#else
 
4533
        return posix_do_stat(self, args, "et:lstat", STAT, NULL, NULL);
 
4534
#endif
 
4535
#endif /* !HAVE_LSTAT */
 
4536
}
 
4537
 
 
4538
 
 
4539
#ifdef HAVE_READLINK
 
4540
PyDoc_STRVAR(posix_readlink__doc__,
 
4541
"readlink(path) -> path\n\n\
 
4542
Return a string representing the path to which the symbolic link points.");
 
4543
 
 
4544
static PyObject *
 
4545
posix_readlink(PyObject *self, PyObject *args)
 
4546
{
 
4547
        PyObject* v;
 
4548
        char buf[MAXPATHLEN];
 
4549
        char *path;
 
4550
        int n;
 
4551
        int arg_is_unicode = 0;
 
4552
 
 
4553
        if (!PyArg_ParseTuple(args, "et:readlink", 
 
4554
                                Py_FileSystemDefaultEncoding, &path))
 
4555
                return NULL;
 
4556
        v = PySequence_GetItem(args, 0);
 
4557
        if (v == NULL) {
 
4558
                PyMem_Free(path);
 
4559
                return NULL;
 
4560
        }
 
4561
 
 
4562
        if (PyUnicode_Check(v)) {
 
4563
                arg_is_unicode = 1;
 
4564
        }
 
4565
        Py_DECREF(v);
 
4566
 
 
4567
        Py_BEGIN_ALLOW_THREADS
 
4568
        n = readlink(path, buf, (int) sizeof buf);
 
4569
        Py_END_ALLOW_THREADS
 
4570
        if (n < 0)
 
4571
                return posix_error_with_allocated_filename(path);
 
4572
 
 
4573
        PyMem_Free(path);
 
4574
        v = PyBytes_FromStringAndSize(buf, n);
 
4575
        if (arg_is_unicode) {
 
4576
                PyObject *w;
 
4577
 
 
4578
                w = PyUnicode_FromEncodedObject(v,
 
4579
                                Py_FileSystemDefaultEncoding,
 
4580
                                "strict");
 
4581
                if (w != NULL) {
 
4582
                        Py_DECREF(v);
 
4583
                        v = w;
 
4584
                }
 
4585
                else {
 
4586
                        v = NULL;
 
4587
                }
 
4588
        }
 
4589
        return v;
 
4590
}
 
4591
#endif /* HAVE_READLINK */
 
4592
 
 
4593
 
 
4594
#ifdef HAVE_SYMLINK
 
4595
PyDoc_STRVAR(posix_symlink__doc__,
 
4596
"symlink(src, dst)\n\n\
 
4597
Create a symbolic link pointing to src named dst.");
 
4598
 
 
4599
static PyObject *
 
4600
posix_symlink(PyObject *self, PyObject *args)
 
4601
{
 
4602
        return posix_2str(args, "etet:symlink", symlink);
 
4603
}
 
4604
#endif /* HAVE_SYMLINK */
 
4605
 
 
4606
 
 
4607
#ifdef HAVE_TIMES
 
4608
#if defined(PYCC_VACPP) && defined(PYOS_OS2)
 
4609
static long
 
4610
system_uptime(void)
 
4611
{
 
4612
    ULONG     value = 0;
 
4613
 
 
4614
    Py_BEGIN_ALLOW_THREADS
 
4615
    DosQuerySysInfo(QSV_MS_COUNT, QSV_MS_COUNT, &value, sizeof(value));
 
4616
    Py_END_ALLOW_THREADS
 
4617
 
 
4618
    return value;
 
4619
}
 
4620
 
 
4621
static PyObject *
 
4622
posix_times(PyObject *self, PyObject *noargs)
 
4623
{
 
4624
    /* Currently Only Uptime is Provided -- Others Later */
 
4625
        return Py_BuildValue("ddddd",
 
4626
                             (double)0 /* t.tms_utime / HZ */,
 
4627
                             (double)0 /* t.tms_stime / HZ */,
 
4628
                             (double)0 /* t.tms_cutime / HZ */,
 
4629
                             (double)0 /* t.tms_cstime / HZ */,
 
4630
                             (double)system_uptime() / 1000);
 
4631
}
 
4632
#else /* not OS2 */
 
4633
#define NEED_TICKS_PER_SECOND
 
4634
static long ticks_per_second = -1;
 
4635
static PyObject *
 
4636
posix_times(PyObject *self, PyObject *noargs)
 
4637
{
 
4638
        struct tms t;
 
4639
        clock_t c;
 
4640
        errno = 0;
 
4641
        c = times(&t);
 
4642
        if (c == (clock_t) -1)
 
4643
                return posix_error();
 
4644
        return Py_BuildValue("ddddd",
 
4645
                             (double)t.tms_utime / ticks_per_second,
 
4646
                             (double)t.tms_stime / ticks_per_second,
 
4647
                             (double)t.tms_cutime / ticks_per_second,
 
4648
                             (double)t.tms_cstime / ticks_per_second,
 
4649
                             (double)c / ticks_per_second);
 
4650
}
 
4651
#endif /* not OS2 */
 
4652
#endif /* HAVE_TIMES */
 
4653
 
 
4654
 
 
4655
#ifdef MS_WINDOWS
 
4656
#define HAVE_TIMES      /* so the method table will pick it up */
 
4657
static PyObject *
 
4658
posix_times(PyObject *self, PyObject *noargs)
 
4659
{
 
4660
        FILETIME create, exit, kernel, user;
 
4661
        HANDLE hProc;
 
4662
        hProc = GetCurrentProcess();
 
4663
        GetProcessTimes(hProc, &create, &exit, &kernel, &user);
 
4664
        /* The fields of a FILETIME structure are the hi and lo part
 
4665
           of a 64-bit value expressed in 100 nanosecond units.
 
4666
           1e7 is one second in such units; 1e-7 the inverse.
 
4667
           429.4967296 is 2**32 / 1e7 or 2**32 * 1e-7.
 
4668
        */
 
4669
        return Py_BuildValue(
 
4670
                "ddddd",
 
4671
                (double)(user.dwHighDateTime*429.4967296 +
 
4672
                         user.dwLowDateTime*1e-7),
 
4673
                (double)(kernel.dwHighDateTime*429.4967296 +
 
4674
                         kernel.dwLowDateTime*1e-7),
 
4675
                (double)0,
 
4676
                (double)0,
 
4677
                (double)0);
 
4678
}
 
4679
#endif /* MS_WINDOWS */
 
4680
 
 
4681
#ifdef HAVE_TIMES
 
4682
PyDoc_STRVAR(posix_times__doc__,
 
4683
"times() -> (utime, stime, cutime, cstime, elapsed_time)\n\n\
 
4684
Return a tuple of floating point numbers indicating process times.");
 
4685
#endif
 
4686
 
 
4687
 
 
4688
#ifdef HAVE_GETSID
 
4689
PyDoc_STRVAR(posix_getsid__doc__,
 
4690
"getsid(pid) -> sid\n\n\
 
4691
Call the system call getsid().");
 
4692
 
 
4693
static PyObject *
 
4694
posix_getsid(PyObject *self, PyObject *args)
 
4695
{
 
4696
        pid_t pid;
 
4697
        int sid;
 
4698
        if (!PyArg_ParseTuple(args, "i:getsid", &pid))
 
4699
                return NULL;
 
4700
        sid = getsid(pid);
 
4701
        if (sid < 0)
 
4702
                return posix_error();
 
4703
        return PyLong_FromLong((long)sid);
 
4704
}
 
4705
#endif /* HAVE_GETSID */
 
4706
 
 
4707
 
 
4708
#ifdef HAVE_SETSID
 
4709
PyDoc_STRVAR(posix_setsid__doc__,
 
4710
"setsid()\n\n\
 
4711
Call the system call setsid().");
 
4712
 
 
4713
static PyObject *
 
4714
posix_setsid(PyObject *self, PyObject *noargs)
 
4715
{
 
4716
        if (setsid() < 0)
 
4717
                return posix_error();
 
4718
        Py_INCREF(Py_None);
 
4719
        return Py_None;
 
4720
}
 
4721
#endif /* HAVE_SETSID */
 
4722
 
 
4723
#ifdef HAVE_SETPGID
 
4724
PyDoc_STRVAR(posix_setpgid__doc__,
 
4725
"setpgid(pid, pgrp)\n\n\
 
4726
Call the system call setpgid().");
 
4727
 
 
4728
static PyObject *
 
4729
posix_setpgid(PyObject *self, PyObject *args)
 
4730
{
 
4731
        pid_t pid;
 
4732
        int pgrp;
 
4733
        if (!PyArg_ParseTuple(args, "ii:setpgid", &pid, &pgrp))
 
4734
                return NULL;
 
4735
        if (setpgid(pid, pgrp) < 0)
 
4736
                return posix_error();
 
4737
        Py_INCREF(Py_None);
 
4738
        return Py_None;
 
4739
}
 
4740
#endif /* HAVE_SETPGID */
 
4741
 
 
4742
 
 
4743
#ifdef HAVE_TCGETPGRP
 
4744
PyDoc_STRVAR(posix_tcgetpgrp__doc__,
 
4745
"tcgetpgrp(fd) -> pgid\n\n\
 
4746
Return the process group associated with the terminal given by a fd.");
 
4747
 
 
4748
static PyObject *
 
4749
posix_tcgetpgrp(PyObject *self, PyObject *args)
 
4750
{
 
4751
        int fd;
 
4752
        pid_t pgid;
 
4753
        if (!PyArg_ParseTuple(args, "i:tcgetpgrp", &fd))
 
4754
                return NULL;
 
4755
        pgid = tcgetpgrp(fd);
 
4756
        if (pgid < 0)
 
4757
                return posix_error();
 
4758
        return PyLong_FromLong((long)pgid);
 
4759
}
 
4760
#endif /* HAVE_TCGETPGRP */
 
4761
 
 
4762
 
 
4763
#ifdef HAVE_TCSETPGRP
 
4764
PyDoc_STRVAR(posix_tcsetpgrp__doc__,
 
4765
"tcsetpgrp(fd, pgid)\n\n\
 
4766
Set the process group associated with the terminal given by a fd.");
 
4767
 
 
4768
static PyObject *
 
4769
posix_tcsetpgrp(PyObject *self, PyObject *args)
 
4770
{
 
4771
        int fd, pgid;
 
4772
        if (!PyArg_ParseTuple(args, "ii:tcsetpgrp", &fd, &pgid))
 
4773
                return NULL;
 
4774
        if (tcsetpgrp(fd, pgid) < 0)
 
4775
                return posix_error();
 
4776
        Py_INCREF(Py_None);
 
4777
        return Py_None;
 
4778
}
 
4779
#endif /* HAVE_TCSETPGRP */
 
4780
 
 
4781
/* Functions acting on file descriptors */
 
4782
 
 
4783
PyDoc_STRVAR(posix_open__doc__,
 
4784
"open(filename, flag [, mode=0777]) -> fd\n\n\
 
4785
Open a file (for low level IO).");
 
4786
 
 
4787
static PyObject *
 
4788
posix_open(PyObject *self, PyObject *args)
 
4789
{
 
4790
        char *file = NULL;
 
4791
        int flag;
 
4792
        int mode = 0777;
 
4793
        int fd;
 
4794
 
 
4795
#ifdef MS_WINDOWS
 
4796
        if (unicode_file_names()) {
 
4797
                PyUnicodeObject *po;
 
4798
                if (PyArg_ParseTuple(args, "Ui|i:mkdir", &po, &flag, &mode)) {
 
4799
                        Py_BEGIN_ALLOW_THREADS
 
4800
                        /* PyUnicode_AS_UNICODE OK without thread
 
4801
                           lock as it is a simple dereference. */
 
4802
                        fd = _wopen(PyUnicode_AS_UNICODE(po), flag, mode);
 
4803
                        Py_END_ALLOW_THREADS
 
4804
                        if (fd < 0)
 
4805
                                return posix_error();
 
4806
                        return PyLong_FromLong((long)fd);
 
4807
                }
 
4808
                /* Drop the argument parsing error as narrow strings
 
4809
                   are also valid. */
 
4810
                PyErr_Clear();
 
4811
        }
 
4812
#endif
 
4813
 
 
4814
        if (!PyArg_ParseTuple(args, "eti|i",
 
4815
                              Py_FileSystemDefaultEncoding, &file,
 
4816
                              &flag, &mode))
 
4817
                return NULL;
 
4818
 
 
4819
        Py_BEGIN_ALLOW_THREADS
 
4820
        fd = open(file, flag, mode);
 
4821
        Py_END_ALLOW_THREADS
 
4822
        if (fd < 0)
 
4823
                return posix_error_with_allocated_filename(file);
 
4824
        PyMem_Free(file);
 
4825
        return PyLong_FromLong((long)fd);
 
4826
}
 
4827
 
 
4828
 
 
4829
PyDoc_STRVAR(posix_close__doc__,
 
4830
"close(fd)\n\n\
 
4831
Close a file descriptor (for low level IO).");
 
4832
 
 
4833
static PyObject *
 
4834
posix_close(PyObject *self, PyObject *args)
 
4835
{
 
4836
        int fd, res;
 
4837
        if (!PyArg_ParseTuple(args, "i:close", &fd))
 
4838
                return NULL;
 
4839
        if (!_PyVerify_fd(fd))
 
4840
                return posix_error();
 
4841
        Py_BEGIN_ALLOW_THREADS
 
4842
        res = close(fd);
 
4843
        Py_END_ALLOW_THREADS
 
4844
        if (res < 0)
 
4845
                return posix_error();
 
4846
        Py_INCREF(Py_None);
 
4847
        return Py_None;
 
4848
}
 
4849
 
 
4850
 
 
4851
PyDoc_STRVAR(posix_closerange__doc__, 
 
4852
"closerange(fd_low, fd_high)\n\n\
 
4853
Closes all file descriptors in [fd_low, fd_high), ignoring errors.");
 
4854
 
 
4855
static PyObject *
 
4856
posix_closerange(PyObject *self, PyObject *args)
 
4857
{
 
4858
        int fd_from, fd_to, i;
 
4859
        if (!PyArg_ParseTuple(args, "ii:closerange", &fd_from, &fd_to))
 
4860
                return NULL;
 
4861
        Py_BEGIN_ALLOW_THREADS
 
4862
        for (i = fd_from; i < fd_to; i++)
 
4863
                if (_PyVerify_fd(i))
 
4864
                        close(i);
 
4865
        Py_END_ALLOW_THREADS
 
4866
        Py_RETURN_NONE;
 
4867
}
 
4868
 
 
4869
 
 
4870
PyDoc_STRVAR(posix_dup__doc__,
 
4871
"dup(fd) -> fd2\n\n\
 
4872
Return a duplicate of a file descriptor.");
 
4873
 
 
4874
static PyObject *
 
4875
posix_dup(PyObject *self, PyObject *args)
 
4876
{
 
4877
        int fd;
 
4878
        if (!PyArg_ParseTuple(args, "i:dup", &fd))
 
4879
                return NULL;
 
4880
        if (!_PyVerify_fd(fd))
 
4881
                return posix_error();
 
4882
        Py_BEGIN_ALLOW_THREADS
 
4883
        fd = dup(fd);
 
4884
        Py_END_ALLOW_THREADS
 
4885
        if (fd < 0)
 
4886
                return posix_error();
 
4887
        return PyLong_FromLong((long)fd);
 
4888
}
 
4889
 
 
4890
 
 
4891
PyDoc_STRVAR(posix_dup2__doc__,
 
4892
"dup2(old_fd, new_fd)\n\n\
 
4893
Duplicate file descriptor.");
 
4894
 
 
4895
static PyObject *
 
4896
posix_dup2(PyObject *self, PyObject *args)
 
4897
{
 
4898
        int fd, fd2, res;
 
4899
        if (!PyArg_ParseTuple(args, "ii:dup2", &fd, &fd2))
 
4900
                return NULL;
 
4901
        if (!_PyVerify_fd_dup2(fd, fd2))
 
4902
                return posix_error();
 
4903
        Py_BEGIN_ALLOW_THREADS
 
4904
        res = dup2(fd, fd2);
 
4905
        Py_END_ALLOW_THREADS
 
4906
        if (res < 0)
 
4907
                return posix_error();
 
4908
        Py_INCREF(Py_None);
 
4909
        return Py_None;
 
4910
}
 
4911
 
 
4912
 
 
4913
PyDoc_STRVAR(posix_lseek__doc__,
 
4914
"lseek(fd, pos, how) -> newpos\n\n\
 
4915
Set the current position of a file descriptor.");
 
4916
 
 
4917
static PyObject *
 
4918
posix_lseek(PyObject *self, PyObject *args)
 
4919
{
 
4920
        int fd, how;
 
4921
#if defined(MS_WIN64) || defined(MS_WINDOWS)
 
4922
        PY_LONG_LONG pos, res;
 
4923
#else
 
4924
        off_t pos, res;
 
4925
#endif
 
4926
        PyObject *posobj;
 
4927
        if (!PyArg_ParseTuple(args, "iOi:lseek", &fd, &posobj, &how))
 
4928
                return NULL;
 
4929
#ifdef SEEK_SET
 
4930
        /* Turn 0, 1, 2 into SEEK_{SET,CUR,END} */
 
4931
        switch (how) {
 
4932
        case 0: how = SEEK_SET; break;
 
4933
        case 1: how = SEEK_CUR; break;
 
4934
        case 2: how = SEEK_END; break;
 
4935
        }
 
4936
#endif /* SEEK_END */
 
4937
 
 
4938
#if !defined(HAVE_LARGEFILE_SUPPORT)
 
4939
        pos = PyLong_AsLong(posobj);
 
4940
#else
 
4941
        pos = PyLong_Check(posobj) ?
 
4942
                PyLong_AsLongLong(posobj) : PyLong_AsLong(posobj);
 
4943
#endif
 
4944
        if (PyErr_Occurred())
 
4945
                return NULL;
 
4946
 
 
4947
        if (!_PyVerify_fd(fd))
 
4948
                return posix_error();
 
4949
        Py_BEGIN_ALLOW_THREADS
 
4950
#if defined(MS_WIN64) || defined(MS_WINDOWS)
 
4951
        res = _lseeki64(fd, pos, how);
 
4952
#else
 
4953
        res = lseek(fd, pos, how);
 
4954
#endif
 
4955
        Py_END_ALLOW_THREADS
 
4956
        if (res < 0)
 
4957
                return posix_error();
 
4958
 
 
4959
#if !defined(HAVE_LARGEFILE_SUPPORT)
 
4960
        return PyLong_FromLong(res);
 
4961
#else
 
4962
        return PyLong_FromLongLong(res);
 
4963
#endif
 
4964
}
 
4965
 
 
4966
 
 
4967
PyDoc_STRVAR(posix_read__doc__,
 
4968
"read(fd, buffersize) -> string\n\n\
 
4969
Read a file descriptor.");
 
4970
 
 
4971
static PyObject *
 
4972
posix_read(PyObject *self, PyObject *args)
 
4973
{
 
4974
        int fd, size;
 
4975
        Py_ssize_t n;
 
4976
        PyObject *buffer;
 
4977
        if (!PyArg_ParseTuple(args, "ii:read", &fd, &size))
 
4978
                return NULL;
 
4979
        if (size < 0) {
 
4980
                errno = EINVAL;
 
4981
                return posix_error();
 
4982
        }
 
4983
        buffer = PyBytes_FromStringAndSize((char *)NULL, size);
 
4984
        if (buffer == NULL)
 
4985
                return NULL;
 
4986
        if (!_PyVerify_fd(fd))
 
4987
                return posix_error();
 
4988
        Py_BEGIN_ALLOW_THREADS
 
4989
        n = read(fd, PyBytes_AS_STRING(buffer), size);
 
4990
        Py_END_ALLOW_THREADS
 
4991
        if (n < 0) {
 
4992
                Py_DECREF(buffer);
 
4993
                return posix_error();
 
4994
        }
 
4995
        if (n != size)
 
4996
                _PyBytes_Resize(&buffer, n);
 
4997
        return buffer;
 
4998
}
 
4999
 
 
5000
 
 
5001
PyDoc_STRVAR(posix_write__doc__,
 
5002
"write(fd, string) -> byteswritten\n\n\
 
5003
Write a string to a file descriptor.");
 
5004
 
 
5005
static PyObject *
 
5006
posix_write(PyObject *self, PyObject *args)
 
5007
{
 
5008
        Py_buffer pbuf;
 
5009
        int fd;
 
5010
        Py_ssize_t size;
 
5011
 
 
5012
        if (!PyArg_ParseTuple(args, "iy*:write", &fd, &pbuf))
 
5013
                return NULL;
 
5014
        if (!_PyVerify_fd(fd))
 
5015
                return posix_error();
 
5016
        Py_BEGIN_ALLOW_THREADS
 
5017
        size = write(fd, pbuf.buf, (size_t)pbuf.len);
 
5018
        Py_END_ALLOW_THREADS
 
5019
                PyBuffer_Release(&pbuf);
 
5020
        if (size < 0)
 
5021
                return posix_error();
 
5022
        return PyLong_FromSsize_t(size);
 
5023
}
 
5024
 
 
5025
 
 
5026
PyDoc_STRVAR(posix_fstat__doc__,
 
5027
"fstat(fd) -> stat result\n\n\
 
5028
Like stat(), but for an open file descriptor.");
 
5029
 
 
5030
static PyObject *
 
5031
posix_fstat(PyObject *self, PyObject *args)
 
5032
{
 
5033
        int fd;
 
5034
        STRUCT_STAT st;
 
5035
        int res;
 
5036
        if (!PyArg_ParseTuple(args, "i:fstat", &fd))
 
5037
                return NULL;
 
5038
#ifdef __VMS
 
5039
        /* on OpenVMS we must ensure that all bytes are written to the file */
 
5040
        fsync(fd);
 
5041
#endif
 
5042
        if (!_PyVerify_fd(fd))
 
5043
                return posix_error();
 
5044
        Py_BEGIN_ALLOW_THREADS
 
5045
        res = FSTAT(fd, &st);
 
5046
        Py_END_ALLOW_THREADS
 
5047
        if (res != 0) {
 
5048
#ifdef MS_WINDOWS
 
5049
                return win32_error("fstat", NULL);
 
5050
#else
 
5051
                return posix_error();
 
5052
#endif
 
5053
        }
 
5054
 
 
5055
        return _pystat_fromstructstat(&st);
 
5056
}
 
5057
 
 
5058
PyDoc_STRVAR(posix_isatty__doc__,
 
5059
"isatty(fd) -> bool\n\n\
 
5060
Return True if the file descriptor 'fd' is an open file descriptor\n\
 
5061
connected to the slave end of a terminal.");
 
5062
 
 
5063
static PyObject *
 
5064
posix_isatty(PyObject *self, PyObject *args)
 
5065
{
 
5066
        int fd;
 
5067
        if (!PyArg_ParseTuple(args, "i:isatty", &fd))
 
5068
                return NULL;
 
5069
        if (!_PyVerify_fd(fd))
 
5070
                return PyBool_FromLong(0);
 
5071
        return PyBool_FromLong(isatty(fd));
 
5072
}
 
5073
 
 
5074
#ifdef HAVE_PIPE
 
5075
PyDoc_STRVAR(posix_pipe__doc__,
 
5076
"pipe() -> (read_end, write_end)\n\n\
 
5077
Create a pipe.");
 
5078
 
 
5079
static PyObject *
 
5080
posix_pipe(PyObject *self, PyObject *noargs)
 
5081
{
 
5082
#if defined(PYOS_OS2)
 
5083
    HFILE read, write;
 
5084
    APIRET rc;
 
5085
 
 
5086
        Py_BEGIN_ALLOW_THREADS
 
5087
    rc = DosCreatePipe( &read, &write, 4096);
 
5088
        Py_END_ALLOW_THREADS
 
5089
    if (rc != NO_ERROR)
 
5090
        return os2_error(rc);
 
5091
 
 
5092
    return Py_BuildValue("(ii)", read, write);
 
5093
#else
 
5094
#if !defined(MS_WINDOWS)
 
5095
        int fds[2];
 
5096
        int res;
 
5097
        Py_BEGIN_ALLOW_THREADS
 
5098
        res = pipe(fds);
 
5099
        Py_END_ALLOW_THREADS
 
5100
        if (res != 0)
 
5101
                return posix_error();
 
5102
        return Py_BuildValue("(ii)", fds[0], fds[1]);
 
5103
#else /* MS_WINDOWS */
 
5104
        HANDLE read, write;
 
5105
        int read_fd, write_fd;
 
5106
        BOOL ok;
 
5107
        Py_BEGIN_ALLOW_THREADS
 
5108
        ok = CreatePipe(&read, &write, NULL, 0);
 
5109
        Py_END_ALLOW_THREADS
 
5110
        if (!ok)
 
5111
                return win32_error("CreatePipe", NULL);
 
5112
        read_fd = _open_osfhandle((Py_intptr_t)read, 0);
 
5113
        write_fd = _open_osfhandle((Py_intptr_t)write, 1);
 
5114
        return Py_BuildValue("(ii)", read_fd, write_fd);
 
5115
#endif /* MS_WINDOWS */
 
5116
#endif
 
5117
}
 
5118
#endif  /* HAVE_PIPE */
 
5119
 
 
5120
 
 
5121
#ifdef HAVE_MKFIFO
 
5122
PyDoc_STRVAR(posix_mkfifo__doc__,
 
5123
"mkfifo(filename [, mode=0666])\n\n\
 
5124
Create a FIFO (a POSIX named pipe).");
 
5125
 
 
5126
static PyObject *
 
5127
posix_mkfifo(PyObject *self, PyObject *args)
 
5128
{
 
5129
        char *filename;
 
5130
        int mode = 0666;
 
5131
        int res;
 
5132
        if (!PyArg_ParseTuple(args, "s|i:mkfifo", &filename, &mode))
 
5133
                return NULL;
 
5134
        Py_BEGIN_ALLOW_THREADS
 
5135
        res = mkfifo(filename, mode);
 
5136
        Py_END_ALLOW_THREADS
 
5137
        if (res < 0)
 
5138
                return posix_error();
 
5139
        Py_INCREF(Py_None);
 
5140
        return Py_None;
 
5141
}
 
5142
#endif
 
5143
 
 
5144
 
 
5145
#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
 
5146
PyDoc_STRVAR(posix_mknod__doc__,
 
5147
"mknod(filename [, mode=0600, device])\n\n\
 
5148
Create a filesystem node (file, device special file or named pipe)\n\
 
5149
named filename. mode specifies both the permissions to use and the\n\
 
5150
type of node to be created, being combined (bitwise OR) with one of\n\
 
5151
S_IFREG, S_IFCHR, S_IFBLK, and S_IFIFO. For S_IFCHR and S_IFBLK,\n\
 
5152
device defines the newly created device special file (probably using\n\
 
5153
os.makedev()), otherwise it is ignored.");
 
5154
 
 
5155
 
 
5156
static PyObject *
 
5157
posix_mknod(PyObject *self, PyObject *args)
 
5158
{
 
5159
        char *filename;
 
5160
        int mode = 0600;
 
5161
        int device = 0;
 
5162
        int res;
 
5163
        if (!PyArg_ParseTuple(args, "s|ii:mknod", &filename, &mode, &device))
 
5164
                return NULL;
 
5165
        Py_BEGIN_ALLOW_THREADS
 
5166
        res = mknod(filename, mode, device);
 
5167
        Py_END_ALLOW_THREADS
 
5168
        if (res < 0)
 
5169
                return posix_error();
 
5170
        Py_INCREF(Py_None);
 
5171
        return Py_None;
 
5172
}
 
5173
#endif
 
5174
 
 
5175
#ifdef HAVE_DEVICE_MACROS
 
5176
PyDoc_STRVAR(posix_major__doc__,
 
5177
"major(device) -> major number\n\
 
5178
Extracts a device major number from a raw device number.");
 
5179
 
 
5180
static PyObject *
 
5181
posix_major(PyObject *self, PyObject *args)
 
5182
{
 
5183
        int device;
 
5184
        if (!PyArg_ParseTuple(args, "i:major", &device))
 
5185
                return NULL;
 
5186
        return PyLong_FromLong((long)major(device));
 
5187
}
 
5188
 
 
5189
PyDoc_STRVAR(posix_minor__doc__,
 
5190
"minor(device) -> minor number\n\
 
5191
Extracts a device minor number from a raw device number.");
 
5192
 
 
5193
static PyObject *
 
5194
posix_minor(PyObject *self, PyObject *args)
 
5195
{
 
5196
        int device;
 
5197
        if (!PyArg_ParseTuple(args, "i:minor", &device))
 
5198
                return NULL;
 
5199
        return PyLong_FromLong((long)minor(device));
 
5200
}
 
5201
 
 
5202
PyDoc_STRVAR(posix_makedev__doc__,
 
5203
"makedev(major, minor) -> device number\n\
 
5204
Composes a raw device number from the major and minor device numbers.");
 
5205
 
 
5206
static PyObject *
 
5207
posix_makedev(PyObject *self, PyObject *args)
 
5208
{
 
5209
        int major, minor;
 
5210
        if (!PyArg_ParseTuple(args, "ii:makedev", &major, &minor))
 
5211
                return NULL;
 
5212
        return PyLong_FromLong((long)makedev(major, minor));
 
5213
}
 
5214
#endif /* device macros */
 
5215
 
 
5216
 
 
5217
#ifdef HAVE_FTRUNCATE
 
5218
PyDoc_STRVAR(posix_ftruncate__doc__,
 
5219
"ftruncate(fd, length)\n\n\
 
5220
Truncate a file to a specified length.");
 
5221
 
 
5222
static PyObject *
 
5223
posix_ftruncate(PyObject *self, PyObject *args)
 
5224
{
 
5225
        int fd;
 
5226
        off_t length;
 
5227
        int res;
 
5228
        PyObject *lenobj;
 
5229
 
 
5230
        if (!PyArg_ParseTuple(args, "iO:ftruncate", &fd, &lenobj))
 
5231
                return NULL;
 
5232
 
 
5233
#if !defined(HAVE_LARGEFILE_SUPPORT)
 
5234
        length = PyLong_AsLong(lenobj);
 
5235
#else
 
5236
        length = PyLong_Check(lenobj) ?
 
5237
                PyLong_AsLongLong(lenobj) : PyLong_AsLong(lenobj);
 
5238
#endif
 
5239
        if (PyErr_Occurred())
 
5240
                return NULL;
 
5241
 
 
5242
        Py_BEGIN_ALLOW_THREADS
 
5243
        res = ftruncate(fd, length);
 
5244
        Py_END_ALLOW_THREADS
 
5245
        if (res < 0)
 
5246
                return posix_error();
 
5247
        Py_INCREF(Py_None);
 
5248
        return Py_None;
 
5249
}
 
5250
#endif
 
5251
 
 
5252
#ifdef HAVE_PUTENV
 
5253
PyDoc_STRVAR(posix_putenv__doc__,
 
5254
"putenv(key, value)\n\n\
 
5255
Change or add an environment variable.");
 
5256
 
 
5257
/* Save putenv() parameters as values here, so we can collect them when they
 
5258
 * get re-set with another call for the same key. */
 
5259
static PyObject *posix_putenv_garbage;
 
5260
 
 
5261
static PyObject *
 
5262
posix_putenv(PyObject *self, PyObject *args)
 
5263
{
 
5264
#ifdef MS_WINDOWS
 
5265
        wchar_t *s1, *s2;
 
5266
        wchar_t *newenv;
 
5267
#else
 
5268
        char *s1, *s2;
 
5269
        char *newenv;
 
5270
#endif
 
5271
        PyObject *newstr;
 
5272
        size_t len;
 
5273
 
 
5274
        if (!PyArg_ParseTuple(args,
 
5275
#ifdef MS_WINDOWS
 
5276
                              "uu:putenv",
 
5277
#else
 
5278
                              "ss:putenv",
 
5279
#endif
 
5280
                              &s1, &s2))
 
5281
                return NULL;
 
5282
 
 
5283
#if defined(PYOS_OS2)
 
5284
    if (stricmp(s1, "BEGINLIBPATH") == 0) {
 
5285
        APIRET rc;
 
5286
 
 
5287
        rc = DosSetExtLIBPATH(s2, BEGIN_LIBPATH);
 
5288
        if (rc != NO_ERROR)
 
5289
            return os2_error(rc);
 
5290
 
 
5291
    } else if (stricmp(s1, "ENDLIBPATH") == 0) {
 
5292
        APIRET rc;
 
5293
 
 
5294
        rc = DosSetExtLIBPATH(s2, END_LIBPATH);
 
5295
        if (rc != NO_ERROR)
 
5296
            return os2_error(rc);
 
5297
    } else {
 
5298
#endif
 
5299
        /* XXX This can leak memory -- not easy to fix :-( */
 
5300
        /* len includes space for a trailing \0; the size arg to
 
5301
           PyBytes_FromStringAndSize does not count that */
 
5302
#ifdef MS_WINDOWS
 
5303
        len = wcslen(s1) + wcslen(s2) + 2;
 
5304
        newstr = PyUnicode_FromUnicode(NULL, (int)len - 1);
 
5305
#else
 
5306
        len = strlen(s1) + strlen(s2) + 2;
 
5307
        newstr = PyBytes_FromStringAndSize(NULL, (int)len - 1);
 
5308
#endif
 
5309
        if (newstr == NULL)
 
5310
                return PyErr_NoMemory();
 
5311
#ifdef MS_WINDOWS
 
5312
        newenv = PyUnicode_AsUnicode(newstr);
 
5313
        _snwprintf(newenv, len, L"%s=%s", s1, s2);
 
5314
        if (_wputenv(newenv)) {
 
5315
                Py_DECREF(newstr);
 
5316
                posix_error();
 
5317
                return NULL;
 
5318
        }
 
5319
#else
 
5320
        newenv = PyBytes_AS_STRING(newstr);
 
5321
        PyOS_snprintf(newenv, len, "%s=%s", s1, s2);
 
5322
        if (putenv(newenv)) {
 
5323
                Py_DECREF(newstr);
 
5324
                posix_error();
 
5325
                return NULL;
 
5326
        }
 
5327
#endif
 
5328
        /* Install the first arg and newstr in posix_putenv_garbage;
 
5329
         * this will cause previous value to be collected.  This has to
 
5330
         * happen after the real putenv() call because the old value
 
5331
         * was still accessible until then. */
 
5332
        if (PyDict_SetItem(posix_putenv_garbage,
 
5333
                           PyTuple_GET_ITEM(args, 0), newstr)) {
 
5334
                /* really not much we can do; just leak */
 
5335
                PyErr_Clear();
 
5336
        }
 
5337
        else {
 
5338
                Py_DECREF(newstr);
 
5339
        }
 
5340
 
 
5341
#if defined(PYOS_OS2)
 
5342
    }
 
5343
#endif
 
5344
        Py_INCREF(Py_None);
 
5345
        return Py_None;
 
5346
}
 
5347
#endif /* putenv */
 
5348
 
 
5349
#ifdef HAVE_UNSETENV
 
5350
PyDoc_STRVAR(posix_unsetenv__doc__,
 
5351
"unsetenv(key)\n\n\
 
5352
Delete an environment variable.");
 
5353
 
 
5354
static PyObject *
 
5355
posix_unsetenv(PyObject *self, PyObject *args)
 
5356
{
 
5357
        char *s1;
 
5358
 
 
5359
        if (!PyArg_ParseTuple(args, "s:unsetenv", &s1))
 
5360
                return NULL;
 
5361
 
 
5362
        unsetenv(s1);
 
5363
 
 
5364
        /* Remove the key from posix_putenv_garbage;
 
5365
         * this will cause it to be collected.  This has to
 
5366
         * happen after the real unsetenv() call because the
 
5367
         * old value was still accessible until then.
 
5368
         */
 
5369
        if (PyDict_DelItem(posix_putenv_garbage,
 
5370
                PyTuple_GET_ITEM(args, 0))) {
 
5371
                /* really not much we can do; just leak */
 
5372
                PyErr_Clear();
 
5373
        }
 
5374
 
 
5375
        Py_INCREF(Py_None);
 
5376
        return Py_None;
 
5377
}
 
5378
#endif /* unsetenv */
 
5379
 
 
5380
PyDoc_STRVAR(posix_strerror__doc__,
 
5381
"strerror(code) -> string\n\n\
 
5382
Translate an error code to a message string.");
 
5383
 
 
5384
static PyObject *
 
5385
posix_strerror(PyObject *self, PyObject *args)
 
5386
{
 
5387
        int code;
 
5388
        char *message;
 
5389
        if (!PyArg_ParseTuple(args, "i:strerror", &code))
 
5390
                return NULL;
 
5391
        message = strerror(code);
 
5392
        if (message == NULL) {
 
5393
                PyErr_SetString(PyExc_ValueError,
 
5394
                                "strerror() argument out of range");
 
5395
                return NULL;
 
5396
        }
 
5397
        return PyUnicode_FromString(message);
 
5398
}
 
5399
 
 
5400
 
 
5401
#ifdef HAVE_SYS_WAIT_H
 
5402
 
 
5403
#ifdef WCOREDUMP
 
5404
PyDoc_STRVAR(posix_WCOREDUMP__doc__,
 
5405
"WCOREDUMP(status) -> bool\n\n\
 
5406
Return True if the process returning 'status' was dumped to a core file.");
 
5407
 
 
5408
static PyObject *
 
5409
posix_WCOREDUMP(PyObject *self, PyObject *args)
 
5410
{
 
5411
        WAIT_TYPE status;
 
5412
        WAIT_STATUS_INT(status) = 0;
 
5413
 
 
5414
        if (!PyArg_ParseTuple(args, "i:WCOREDUMP", &WAIT_STATUS_INT(status)))
 
5415
                return NULL;
 
5416
 
 
5417
        return PyBool_FromLong(WCOREDUMP(status));
 
5418
}
 
5419
#endif /* WCOREDUMP */
 
5420
 
 
5421
#ifdef WIFCONTINUED
 
5422
PyDoc_STRVAR(posix_WIFCONTINUED__doc__,
 
5423
"WIFCONTINUED(status) -> bool\n\n\
 
5424
Return True if the process returning 'status' was continued from a\n\
 
5425
job control stop.");
 
5426
 
 
5427
static PyObject *
 
5428
posix_WIFCONTINUED(PyObject *self, PyObject *args)
 
5429
{
 
5430
        WAIT_TYPE status;
 
5431
        WAIT_STATUS_INT(status) = 0;
 
5432
 
 
5433
        if (!PyArg_ParseTuple(args, "i:WCONTINUED", &WAIT_STATUS_INT(status)))
 
5434
                return NULL;
 
5435
 
 
5436
        return PyBool_FromLong(WIFCONTINUED(status));
 
5437
}
 
5438
#endif /* WIFCONTINUED */
 
5439
 
 
5440
#ifdef WIFSTOPPED
 
5441
PyDoc_STRVAR(posix_WIFSTOPPED__doc__,
 
5442
"WIFSTOPPED(status) -> bool\n\n\
 
5443
Return True if the process returning 'status' was stopped.");
 
5444
 
 
5445
static PyObject *
 
5446
posix_WIFSTOPPED(PyObject *self, PyObject *args)
 
5447
{
 
5448
        WAIT_TYPE status;
 
5449
        WAIT_STATUS_INT(status) = 0;
 
5450
 
 
5451
        if (!PyArg_ParseTuple(args, "i:WIFSTOPPED", &WAIT_STATUS_INT(status)))
 
5452
                return NULL;
 
5453
 
 
5454
        return PyBool_FromLong(WIFSTOPPED(status));
 
5455
}
 
5456
#endif /* WIFSTOPPED */
 
5457
 
 
5458
#ifdef WIFSIGNALED
 
5459
PyDoc_STRVAR(posix_WIFSIGNALED__doc__,
 
5460
"WIFSIGNALED(status) -> bool\n\n\
 
5461
Return True if the process returning 'status' was terminated by a signal.");
 
5462
 
 
5463
static PyObject *
 
5464
posix_WIFSIGNALED(PyObject *self, PyObject *args)
 
5465
{
 
5466
        WAIT_TYPE status;
 
5467
        WAIT_STATUS_INT(status) = 0;
 
5468
 
 
5469
        if (!PyArg_ParseTuple(args, "i:WIFSIGNALED", &WAIT_STATUS_INT(status)))
 
5470
                return NULL;
 
5471
 
 
5472
        return PyBool_FromLong(WIFSIGNALED(status));
 
5473
}
 
5474
#endif /* WIFSIGNALED */
 
5475
 
 
5476
#ifdef WIFEXITED
 
5477
PyDoc_STRVAR(posix_WIFEXITED__doc__,
 
5478
"WIFEXITED(status) -> bool\n\n\
 
5479
Return true if the process returning 'status' exited using the exit()\n\
 
5480
system call.");
 
5481
 
 
5482
static PyObject *
 
5483
posix_WIFEXITED(PyObject *self, PyObject *args)
 
5484
{
 
5485
        WAIT_TYPE status;
 
5486
        WAIT_STATUS_INT(status) = 0;
 
5487
 
 
5488
        if (!PyArg_ParseTuple(args, "i:WIFEXITED", &WAIT_STATUS_INT(status)))
 
5489
                return NULL;
 
5490
 
 
5491
        return PyBool_FromLong(WIFEXITED(status));
 
5492
}
 
5493
#endif /* WIFEXITED */
 
5494
 
 
5495
#ifdef WEXITSTATUS
 
5496
PyDoc_STRVAR(posix_WEXITSTATUS__doc__,
 
5497
"WEXITSTATUS(status) -> integer\n\n\
 
5498
Return the process return code from 'status'.");
 
5499
 
 
5500
static PyObject *
 
5501
posix_WEXITSTATUS(PyObject *self, PyObject *args)
 
5502
{
 
5503
        WAIT_TYPE status;
 
5504
        WAIT_STATUS_INT(status) = 0;
 
5505
 
 
5506
        if (!PyArg_ParseTuple(args, "i:WEXITSTATUS", &WAIT_STATUS_INT(status)))
 
5507
                return NULL;
 
5508
 
 
5509
        return Py_BuildValue("i", WEXITSTATUS(status));
 
5510
}
 
5511
#endif /* WEXITSTATUS */
 
5512
 
 
5513
#ifdef WTERMSIG
 
5514
PyDoc_STRVAR(posix_WTERMSIG__doc__,
 
5515
"WTERMSIG(status) -> integer\n\n\
 
5516
Return the signal that terminated the process that provided the 'status'\n\
 
5517
value.");
 
5518
 
 
5519
static PyObject *
 
5520
posix_WTERMSIG(PyObject *self, PyObject *args)
 
5521
{
 
5522
        WAIT_TYPE status;
 
5523
        WAIT_STATUS_INT(status) = 0;
 
5524
 
 
5525
        if (!PyArg_ParseTuple(args, "i:WTERMSIG", &WAIT_STATUS_INT(status)))
 
5526
                return NULL;
 
5527
 
 
5528
        return Py_BuildValue("i", WTERMSIG(status));
 
5529
}
 
5530
#endif /* WTERMSIG */
 
5531
 
 
5532
#ifdef WSTOPSIG
 
5533
PyDoc_STRVAR(posix_WSTOPSIG__doc__,
 
5534
"WSTOPSIG(status) -> integer\n\n\
 
5535
Return the signal that stopped the process that provided\n\
 
5536
the 'status' value.");
 
5537
 
 
5538
static PyObject *
 
5539
posix_WSTOPSIG(PyObject *self, PyObject *args)
 
5540
{
 
5541
        WAIT_TYPE status;
 
5542
        WAIT_STATUS_INT(status) = 0;
 
5543
 
 
5544
        if (!PyArg_ParseTuple(args, "i:WSTOPSIG", &WAIT_STATUS_INT(status)))
 
5545
                return NULL;
 
5546
 
 
5547
        return Py_BuildValue("i", WSTOPSIG(status));
 
5548
}
 
5549
#endif /* WSTOPSIG */
 
5550
 
 
5551
#endif /* HAVE_SYS_WAIT_H */
 
5552
 
 
5553
 
 
5554
#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
 
5555
#ifdef _SCO_DS
 
5556
/* SCO OpenServer 5.0 and later requires _SVID3 before it reveals the
 
5557
   needed definitions in sys/statvfs.h */
 
5558
#define _SVID3
 
5559
#endif
 
5560
#include <sys/statvfs.h>
 
5561
 
 
5562
static PyObject*
 
5563
_pystatvfs_fromstructstatvfs(struct statvfs st) {
 
5564
        PyObject *v = PyStructSequence_New(&StatVFSResultType);
 
5565
        if (v == NULL)
 
5566
                return NULL;
 
5567
 
 
5568
#if !defined(HAVE_LARGEFILE_SUPPORT)
 
5569
        PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
 
5570
        PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
 
5571
        PyStructSequence_SET_ITEM(v, 2, PyLong_FromLong((long) st.f_blocks));
 
5572
        PyStructSequence_SET_ITEM(v, 3, PyLong_FromLong((long) st.f_bfree));
 
5573
        PyStructSequence_SET_ITEM(v, 4, PyLong_FromLong((long) st.f_bavail));
 
5574
        PyStructSequence_SET_ITEM(v, 5, PyLong_FromLong((long) st.f_files));
 
5575
        PyStructSequence_SET_ITEM(v, 6, PyLong_FromLong((long) st.f_ffree));
 
5576
        PyStructSequence_SET_ITEM(v, 7, PyLong_FromLong((long) st.f_favail));
 
5577
        PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
 
5578
        PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
 
5579
#else
 
5580
        PyStructSequence_SET_ITEM(v, 0, PyLong_FromLong((long) st.f_bsize));
 
5581
        PyStructSequence_SET_ITEM(v, 1, PyLong_FromLong((long) st.f_frsize));
 
5582
        PyStructSequence_SET_ITEM(v, 2,
 
5583
                               PyLong_FromLongLong((PY_LONG_LONG) st.f_blocks));
 
5584
        PyStructSequence_SET_ITEM(v, 3,
 
5585
                               PyLong_FromLongLong((PY_LONG_LONG) st.f_bfree));
 
5586
        PyStructSequence_SET_ITEM(v, 4,
 
5587
                               PyLong_FromLongLong((PY_LONG_LONG) st.f_bavail));
 
5588
        PyStructSequence_SET_ITEM(v, 5,
 
5589
                               PyLong_FromLongLong((PY_LONG_LONG) st.f_files));
 
5590
        PyStructSequence_SET_ITEM(v, 6,
 
5591
                               PyLong_FromLongLong((PY_LONG_LONG) st.f_ffree));
 
5592
        PyStructSequence_SET_ITEM(v, 7,
 
5593
                               PyLong_FromLongLong((PY_LONG_LONG) st.f_favail));
 
5594
        PyStructSequence_SET_ITEM(v, 8, PyLong_FromLong((long) st.f_flag));
 
5595
        PyStructSequence_SET_ITEM(v, 9, PyLong_FromLong((long) st.f_namemax));
 
5596
#endif
 
5597
 
 
5598
        return v;
 
5599
}
 
5600
 
 
5601
PyDoc_STRVAR(posix_fstatvfs__doc__,
 
5602
"fstatvfs(fd) -> statvfs result\n\n\
 
5603
Perform an fstatvfs system call on the given fd.");
 
5604
 
 
5605
static PyObject *
 
5606
posix_fstatvfs(PyObject *self, PyObject *args)
 
5607
{
 
5608
        int fd, res;
 
5609
        struct statvfs st;
 
5610
 
 
5611
        if (!PyArg_ParseTuple(args, "i:fstatvfs", &fd))
 
5612
                return NULL;
 
5613
        Py_BEGIN_ALLOW_THREADS
 
5614
        res = fstatvfs(fd, &st);
 
5615
        Py_END_ALLOW_THREADS
 
5616
        if (res != 0)
 
5617
                return posix_error();
 
5618
 
 
5619
        return _pystatvfs_fromstructstatvfs(st);
 
5620
}
 
5621
#endif /* HAVE_FSTATVFS && HAVE_SYS_STATVFS_H */
 
5622
 
 
5623
 
 
5624
#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
 
5625
#include <sys/statvfs.h>
 
5626
 
 
5627
PyDoc_STRVAR(posix_statvfs__doc__,
 
5628
"statvfs(path) -> statvfs result\n\n\
 
5629
Perform a statvfs system call on the given path.");
 
5630
 
 
5631
static PyObject *
 
5632
posix_statvfs(PyObject *self, PyObject *args)
 
5633
{
 
5634
        char *path;
 
5635
        int res;
 
5636
        struct statvfs st;
 
5637
        if (!PyArg_ParseTuple(args, "s:statvfs", &path))
 
5638
                return NULL;
 
5639
        Py_BEGIN_ALLOW_THREADS
 
5640
        res = statvfs(path, &st);
 
5641
        Py_END_ALLOW_THREADS
 
5642
        if (res != 0)
 
5643
                return posix_error_with_filename(path);
 
5644
 
 
5645
        return _pystatvfs_fromstructstatvfs(st);
 
5646
}
 
5647
#endif /* HAVE_STATVFS */
 
5648
 
 
5649
/* This is used for fpathconf(), pathconf(), confstr() and sysconf().
 
5650
 * It maps strings representing configuration variable names to
 
5651
 * integer values, allowing those functions to be called with the
 
5652
 * magic names instead of polluting the module's namespace with tons of
 
5653
 * rarely-used constants.  There are three separate tables that use
 
5654
 * these definitions.
 
5655
 *
 
5656
 * This code is always included, even if none of the interfaces that
 
5657
 * need it are included.  The #if hackery needed to avoid it would be
 
5658
 * sufficiently pervasive that it's not worth the loss of readability.
 
5659
 */
 
5660
struct constdef {
 
5661
    char *name;
 
5662
    long value;
 
5663
};
 
5664
 
 
5665
static int
 
5666
conv_confname(PyObject *arg, int *valuep, struct constdef *table,
 
5667
              size_t tablesize)
 
5668
{
 
5669
    if (PyLong_Check(arg)) {
 
5670
        *valuep = PyLong_AS_LONG(arg);
 
5671
        return 1;
 
5672
    }
 
5673
    else {
 
5674
        /* look up the value in the table using a binary search */
 
5675
        size_t lo = 0;
 
5676
        size_t mid;
 
5677
        size_t hi = tablesize;
 
5678
        int cmp;
 
5679
        const char *confname;
 
5680
        if (!PyUnicode_Check(arg)) {
 
5681
            PyErr_SetString(PyExc_TypeError,
 
5682
                            "configuration names must be strings or integers");
 
5683
            return 0;
 
5684
        }
 
5685
        confname = _PyUnicode_AsString(arg);
 
5686
        if (confname == NULL)
 
5687
            return 0;
 
5688
        while (lo < hi) {
 
5689
            mid = (lo + hi) / 2;
 
5690
            cmp = strcmp(confname, table[mid].name);
 
5691
            if (cmp < 0)
 
5692
                hi = mid;
 
5693
            else if (cmp > 0)
 
5694
                lo = mid + 1;
 
5695
            else {
 
5696
                *valuep = table[mid].value;
 
5697
                return 1;
 
5698
            }
 
5699
        }
 
5700
        PyErr_SetString(PyExc_ValueError, "unrecognized configuration name");
 
5701
        return 0;
 
5702
    }
 
5703
}
 
5704
 
 
5705
 
 
5706
#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
 
5707
static struct constdef  posix_constants_pathconf[] = {
 
5708
#ifdef _PC_ABI_AIO_XFER_MAX
 
5709
    {"PC_ABI_AIO_XFER_MAX",     _PC_ABI_AIO_XFER_MAX},
 
5710
#endif
 
5711
#ifdef _PC_ABI_ASYNC_IO
 
5712
    {"PC_ABI_ASYNC_IO", _PC_ABI_ASYNC_IO},
 
5713
#endif
 
5714
#ifdef _PC_ASYNC_IO
 
5715
    {"PC_ASYNC_IO",     _PC_ASYNC_IO},
 
5716
#endif
 
5717
#ifdef _PC_CHOWN_RESTRICTED
 
5718
    {"PC_CHOWN_RESTRICTED",     _PC_CHOWN_RESTRICTED},
 
5719
#endif
 
5720
#ifdef _PC_FILESIZEBITS
 
5721
    {"PC_FILESIZEBITS", _PC_FILESIZEBITS},
 
5722
#endif
 
5723
#ifdef _PC_LAST
 
5724
    {"PC_LAST", _PC_LAST},
 
5725
#endif
 
5726
#ifdef _PC_LINK_MAX
 
5727
    {"PC_LINK_MAX",     _PC_LINK_MAX},
 
5728
#endif
 
5729
#ifdef _PC_MAX_CANON
 
5730
    {"PC_MAX_CANON",    _PC_MAX_CANON},
 
5731
#endif
 
5732
#ifdef _PC_MAX_INPUT
 
5733
    {"PC_MAX_INPUT",    _PC_MAX_INPUT},
 
5734
#endif
 
5735
#ifdef _PC_NAME_MAX
 
5736
    {"PC_NAME_MAX",     _PC_NAME_MAX},
 
5737
#endif
 
5738
#ifdef _PC_NO_TRUNC
 
5739
    {"PC_NO_TRUNC",     _PC_NO_TRUNC},
 
5740
#endif
 
5741
#ifdef _PC_PATH_MAX
 
5742
    {"PC_PATH_MAX",     _PC_PATH_MAX},
 
5743
#endif
 
5744
#ifdef _PC_PIPE_BUF
 
5745
    {"PC_PIPE_BUF",     _PC_PIPE_BUF},
 
5746
#endif
 
5747
#ifdef _PC_PRIO_IO
 
5748
    {"PC_PRIO_IO",      _PC_PRIO_IO},
 
5749
#endif
 
5750
#ifdef _PC_SOCK_MAXBUF
 
5751
    {"PC_SOCK_MAXBUF",  _PC_SOCK_MAXBUF},
 
5752
#endif
 
5753
#ifdef _PC_SYNC_IO
 
5754
    {"PC_SYNC_IO",      _PC_SYNC_IO},
 
5755
#endif
 
5756
#ifdef _PC_VDISABLE
 
5757
    {"PC_VDISABLE",     _PC_VDISABLE},
 
5758
#endif
 
5759
};
 
5760
 
 
5761
static int
 
5762
conv_path_confname(PyObject *arg, int *valuep)
 
5763
{
 
5764
    return conv_confname(arg, valuep, posix_constants_pathconf,
 
5765
                         sizeof(posix_constants_pathconf)
 
5766
                           / sizeof(struct constdef));
 
5767
}
 
5768
#endif
 
5769
 
 
5770
#ifdef HAVE_FPATHCONF
 
5771
PyDoc_STRVAR(posix_fpathconf__doc__,
 
5772
"fpathconf(fd, name) -> integer\n\n\
 
5773
Return the configuration limit name for the file descriptor fd.\n\
 
5774
If there is no limit, return -1.");
 
5775
 
 
5776
static PyObject *
 
5777
posix_fpathconf(PyObject *self, PyObject *args)
 
5778
{
 
5779
    PyObject *result = NULL;
 
5780
    int name, fd;
 
5781
 
 
5782
    if (PyArg_ParseTuple(args, "iO&:fpathconf", &fd,
 
5783
                         conv_path_confname, &name)) {
 
5784
        long limit;
 
5785
 
 
5786
        errno = 0;
 
5787
        limit = fpathconf(fd, name);
 
5788
        if (limit == -1 && errno != 0)
 
5789
            posix_error();
 
5790
        else
 
5791
            result = PyLong_FromLong(limit);
 
5792
    }
 
5793
    return result;
 
5794
}
 
5795
#endif
 
5796
 
 
5797
 
 
5798
#ifdef HAVE_PATHCONF
 
5799
PyDoc_STRVAR(posix_pathconf__doc__,
 
5800
"pathconf(path, name) -> integer\n\n\
 
5801
Return the configuration limit name for the file or directory path.\n\
 
5802
If there is no limit, return -1.");
 
5803
 
 
5804
static PyObject *
 
5805
posix_pathconf(PyObject *self, PyObject *args)
 
5806
{
 
5807
    PyObject *result = NULL;
 
5808
    int name;
 
5809
    char *path;
 
5810
 
 
5811
    if (PyArg_ParseTuple(args, "sO&:pathconf", &path,
 
5812
                         conv_path_confname, &name)) {
 
5813
        long limit;
 
5814
 
 
5815
        errno = 0;
 
5816
        limit = pathconf(path, name);
 
5817
        if (limit == -1 && errno != 0) {
 
5818
            if (errno == EINVAL)
 
5819
                /* could be a path or name problem */
 
5820
                posix_error();
 
5821
            else
 
5822
                posix_error_with_filename(path);
 
5823
        }
 
5824
        else
 
5825
            result = PyLong_FromLong(limit);
 
5826
    }
 
5827
    return result;
 
5828
}
 
5829
#endif
 
5830
 
 
5831
#ifdef HAVE_CONFSTR
 
5832
static struct constdef posix_constants_confstr[] = {
 
5833
#ifdef _CS_ARCHITECTURE
 
5834
    {"CS_ARCHITECTURE", _CS_ARCHITECTURE},
 
5835
#endif
 
5836
#ifdef _CS_HOSTNAME
 
5837
    {"CS_HOSTNAME",     _CS_HOSTNAME},
 
5838
#endif
 
5839
#ifdef _CS_HW_PROVIDER
 
5840
    {"CS_HW_PROVIDER",  _CS_HW_PROVIDER},
 
5841
#endif
 
5842
#ifdef _CS_HW_SERIAL
 
5843
    {"CS_HW_SERIAL",    _CS_HW_SERIAL},
 
5844
#endif
 
5845
#ifdef _CS_INITTAB_NAME
 
5846
    {"CS_INITTAB_NAME", _CS_INITTAB_NAME},
 
5847
#endif
 
5848
#ifdef _CS_LFS64_CFLAGS
 
5849
    {"CS_LFS64_CFLAGS", _CS_LFS64_CFLAGS},
 
5850
#endif
 
5851
#ifdef _CS_LFS64_LDFLAGS
 
5852
    {"CS_LFS64_LDFLAGS",        _CS_LFS64_LDFLAGS},
 
5853
#endif
 
5854
#ifdef _CS_LFS64_LIBS
 
5855
    {"CS_LFS64_LIBS",   _CS_LFS64_LIBS},
 
5856
#endif
 
5857
#ifdef _CS_LFS64_LINTFLAGS
 
5858
    {"CS_LFS64_LINTFLAGS",      _CS_LFS64_LINTFLAGS},
 
5859
#endif
 
5860
#ifdef _CS_LFS_CFLAGS
 
5861
    {"CS_LFS_CFLAGS",   _CS_LFS_CFLAGS},
 
5862
#endif
 
5863
#ifdef _CS_LFS_LDFLAGS
 
5864
    {"CS_LFS_LDFLAGS",  _CS_LFS_LDFLAGS},
 
5865
#endif
 
5866
#ifdef _CS_LFS_LIBS
 
5867
    {"CS_LFS_LIBS",     _CS_LFS_LIBS},
 
5868
#endif
 
5869
#ifdef _CS_LFS_LINTFLAGS
 
5870
    {"CS_LFS_LINTFLAGS",        _CS_LFS_LINTFLAGS},
 
5871
#endif
 
5872
#ifdef _CS_MACHINE
 
5873
    {"CS_MACHINE",      _CS_MACHINE},
 
5874
#endif
 
5875
#ifdef _CS_PATH
 
5876
    {"CS_PATH", _CS_PATH},
 
5877
#endif
 
5878
#ifdef _CS_RELEASE
 
5879
    {"CS_RELEASE",      _CS_RELEASE},
 
5880
#endif
 
5881
#ifdef _CS_SRPC_DOMAIN
 
5882
    {"CS_SRPC_DOMAIN",  _CS_SRPC_DOMAIN},
 
5883
#endif
 
5884
#ifdef _CS_SYSNAME
 
5885
    {"CS_SYSNAME",      _CS_SYSNAME},
 
5886
#endif
 
5887
#ifdef _CS_VERSION
 
5888
    {"CS_VERSION",      _CS_VERSION},
 
5889
#endif
 
5890
#ifdef _CS_XBS5_ILP32_OFF32_CFLAGS
 
5891
    {"CS_XBS5_ILP32_OFF32_CFLAGS",      _CS_XBS5_ILP32_OFF32_CFLAGS},
 
5892
#endif
 
5893
#ifdef _CS_XBS5_ILP32_OFF32_LDFLAGS
 
5894
    {"CS_XBS5_ILP32_OFF32_LDFLAGS",     _CS_XBS5_ILP32_OFF32_LDFLAGS},
 
5895
#endif
 
5896
#ifdef _CS_XBS5_ILP32_OFF32_LIBS
 
5897
    {"CS_XBS5_ILP32_OFF32_LIBS",        _CS_XBS5_ILP32_OFF32_LIBS},
 
5898
#endif
 
5899
#ifdef _CS_XBS5_ILP32_OFF32_LINTFLAGS
 
5900
    {"CS_XBS5_ILP32_OFF32_LINTFLAGS",   _CS_XBS5_ILP32_OFF32_LINTFLAGS},
 
5901
#endif
 
5902
#ifdef _CS_XBS5_ILP32_OFFBIG_CFLAGS
 
5903
    {"CS_XBS5_ILP32_OFFBIG_CFLAGS",     _CS_XBS5_ILP32_OFFBIG_CFLAGS},
 
5904
#endif
 
5905
#ifdef _CS_XBS5_ILP32_OFFBIG_LDFLAGS
 
5906
    {"CS_XBS5_ILP32_OFFBIG_LDFLAGS",    _CS_XBS5_ILP32_OFFBIG_LDFLAGS},
 
5907
#endif
 
5908
#ifdef _CS_XBS5_ILP32_OFFBIG_LIBS
 
5909
    {"CS_XBS5_ILP32_OFFBIG_LIBS",       _CS_XBS5_ILP32_OFFBIG_LIBS},
 
5910
#endif
 
5911
#ifdef _CS_XBS5_ILP32_OFFBIG_LINTFLAGS
 
5912
    {"CS_XBS5_ILP32_OFFBIG_LINTFLAGS",  _CS_XBS5_ILP32_OFFBIG_LINTFLAGS},
 
5913
#endif
 
5914
#ifdef _CS_XBS5_LP64_OFF64_CFLAGS
 
5915
    {"CS_XBS5_LP64_OFF64_CFLAGS",       _CS_XBS5_LP64_OFF64_CFLAGS},
 
5916
#endif
 
5917
#ifdef _CS_XBS5_LP64_OFF64_LDFLAGS
 
5918
    {"CS_XBS5_LP64_OFF64_LDFLAGS",      _CS_XBS5_LP64_OFF64_LDFLAGS},
 
5919
#endif
 
5920
#ifdef _CS_XBS5_LP64_OFF64_LIBS
 
5921
    {"CS_XBS5_LP64_OFF64_LIBS", _CS_XBS5_LP64_OFF64_LIBS},
 
5922
#endif
 
5923
#ifdef _CS_XBS5_LP64_OFF64_LINTFLAGS
 
5924
    {"CS_XBS5_LP64_OFF64_LINTFLAGS",    _CS_XBS5_LP64_OFF64_LINTFLAGS},
 
5925
#endif
 
5926
#ifdef _CS_XBS5_LPBIG_OFFBIG_CFLAGS
 
5927
    {"CS_XBS5_LPBIG_OFFBIG_CFLAGS",     _CS_XBS5_LPBIG_OFFBIG_CFLAGS},
 
5928
#endif
 
5929
#ifdef _CS_XBS5_LPBIG_OFFBIG_LDFLAGS
 
5930
    {"CS_XBS5_LPBIG_OFFBIG_LDFLAGS",    _CS_XBS5_LPBIG_OFFBIG_LDFLAGS},
 
5931
#endif
 
5932
#ifdef _CS_XBS5_LPBIG_OFFBIG_LIBS
 
5933
    {"CS_XBS5_LPBIG_OFFBIG_LIBS",       _CS_XBS5_LPBIG_OFFBIG_LIBS},
 
5934
#endif
 
5935
#ifdef _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS
 
5936
    {"CS_XBS5_LPBIG_OFFBIG_LINTFLAGS",  _CS_XBS5_LPBIG_OFFBIG_LINTFLAGS},
 
5937
#endif
 
5938
#ifdef _MIPS_CS_AVAIL_PROCESSORS
 
5939
    {"MIPS_CS_AVAIL_PROCESSORS",        _MIPS_CS_AVAIL_PROCESSORS},
 
5940
#endif
 
5941
#ifdef _MIPS_CS_BASE
 
5942
    {"MIPS_CS_BASE",    _MIPS_CS_BASE},
 
5943
#endif
 
5944
#ifdef _MIPS_CS_HOSTID
 
5945
    {"MIPS_CS_HOSTID",  _MIPS_CS_HOSTID},
 
5946
#endif
 
5947
#ifdef _MIPS_CS_HW_NAME
 
5948
    {"MIPS_CS_HW_NAME", _MIPS_CS_HW_NAME},
 
5949
#endif
 
5950
#ifdef _MIPS_CS_NUM_PROCESSORS
 
5951
    {"MIPS_CS_NUM_PROCESSORS",  _MIPS_CS_NUM_PROCESSORS},
 
5952
#endif
 
5953
#ifdef _MIPS_CS_OSREL_MAJ
 
5954
    {"MIPS_CS_OSREL_MAJ",       _MIPS_CS_OSREL_MAJ},
 
5955
#endif
 
5956
#ifdef _MIPS_CS_OSREL_MIN
 
5957
    {"MIPS_CS_OSREL_MIN",       _MIPS_CS_OSREL_MIN},
 
5958
#endif
 
5959
#ifdef _MIPS_CS_OSREL_PATCH
 
5960
    {"MIPS_CS_OSREL_PATCH",     _MIPS_CS_OSREL_PATCH},
 
5961
#endif
 
5962
#ifdef _MIPS_CS_OS_NAME
 
5963
    {"MIPS_CS_OS_NAME", _MIPS_CS_OS_NAME},
 
5964
#endif
 
5965
#ifdef _MIPS_CS_OS_PROVIDER
 
5966
    {"MIPS_CS_OS_PROVIDER",     _MIPS_CS_OS_PROVIDER},
 
5967
#endif
 
5968
#ifdef _MIPS_CS_PROCESSORS
 
5969
    {"MIPS_CS_PROCESSORS",      _MIPS_CS_PROCESSORS},
 
5970
#endif
 
5971
#ifdef _MIPS_CS_SERIAL
 
5972
    {"MIPS_CS_SERIAL",  _MIPS_CS_SERIAL},
 
5973
#endif
 
5974
#ifdef _MIPS_CS_VENDOR
 
5975
    {"MIPS_CS_VENDOR",  _MIPS_CS_VENDOR},
 
5976
#endif
 
5977
};
 
5978
 
 
5979
static int
 
5980
conv_confstr_confname(PyObject *arg, int *valuep)
 
5981
{
 
5982
    return conv_confname(arg, valuep, posix_constants_confstr,
 
5983
                         sizeof(posix_constants_confstr)
 
5984
                           / sizeof(struct constdef));
 
5985
}
 
5986
 
 
5987
PyDoc_STRVAR(posix_confstr__doc__,
 
5988
"confstr(name) -> string\n\n\
 
5989
Return a string-valued system configuration variable.");
 
5990
 
 
5991
static PyObject *
 
5992
posix_confstr(PyObject *self, PyObject *args)
 
5993
{
 
5994
    PyObject *result = NULL;
 
5995
    int name;
 
5996
    char buffer[256];
 
5997
 
 
5998
    if (PyArg_ParseTuple(args, "O&:confstr", conv_confstr_confname, &name)) {
 
5999
        int len;
 
6000
 
 
6001
        errno = 0;
 
6002
        len = confstr(name, buffer, sizeof(buffer));
 
6003
        if (len == 0) {
 
6004
            if (errno) {
 
6005
                posix_error();
 
6006
            }
 
6007
            else {
 
6008
                result = Py_None;
 
6009
                Py_INCREF(Py_None);
 
6010
            }
 
6011
        }
 
6012
        else {
 
6013
            if ((unsigned int)len >= sizeof(buffer)) {
 
6014
                result = PyUnicode_FromStringAndSize(NULL, len-1);
 
6015
                if (result != NULL)
 
6016
                    confstr(name, _PyUnicode_AsString(result), len);
 
6017
            }
 
6018
            else
 
6019
                result = PyUnicode_FromStringAndSize(buffer, len-1);
 
6020
        }
 
6021
    }
 
6022
    return result;
 
6023
}
 
6024
#endif
 
6025
 
 
6026
 
 
6027
#ifdef HAVE_SYSCONF
 
6028
static struct constdef posix_constants_sysconf[] = {
 
6029
#ifdef _SC_2_CHAR_TERM
 
6030
    {"SC_2_CHAR_TERM",  _SC_2_CHAR_TERM},
 
6031
#endif
 
6032
#ifdef _SC_2_C_BIND
 
6033
    {"SC_2_C_BIND",     _SC_2_C_BIND},
 
6034
#endif
 
6035
#ifdef _SC_2_C_DEV
 
6036
    {"SC_2_C_DEV",      _SC_2_C_DEV},
 
6037
#endif
 
6038
#ifdef _SC_2_C_VERSION
 
6039
    {"SC_2_C_VERSION",  _SC_2_C_VERSION},
 
6040
#endif
 
6041
#ifdef _SC_2_FORT_DEV
 
6042
    {"SC_2_FORT_DEV",   _SC_2_FORT_DEV},
 
6043
#endif
 
6044
#ifdef _SC_2_FORT_RUN
 
6045
    {"SC_2_FORT_RUN",   _SC_2_FORT_RUN},
 
6046
#endif
 
6047
#ifdef _SC_2_LOCALEDEF
 
6048
    {"SC_2_LOCALEDEF",  _SC_2_LOCALEDEF},
 
6049
#endif
 
6050
#ifdef _SC_2_SW_DEV
 
6051
    {"SC_2_SW_DEV",     _SC_2_SW_DEV},
 
6052
#endif
 
6053
#ifdef _SC_2_UPE
 
6054
    {"SC_2_UPE",        _SC_2_UPE},
 
6055
#endif
 
6056
#ifdef _SC_2_VERSION
 
6057
    {"SC_2_VERSION",    _SC_2_VERSION},
 
6058
#endif
 
6059
#ifdef _SC_ABI_ASYNCHRONOUS_IO
 
6060
    {"SC_ABI_ASYNCHRONOUS_IO",  _SC_ABI_ASYNCHRONOUS_IO},
 
6061
#endif
 
6062
#ifdef _SC_ACL
 
6063
    {"SC_ACL",  _SC_ACL},
 
6064
#endif
 
6065
#ifdef _SC_AIO_LISTIO_MAX
 
6066
    {"SC_AIO_LISTIO_MAX",       _SC_AIO_LISTIO_MAX},
 
6067
#endif
 
6068
#ifdef _SC_AIO_MAX
 
6069
    {"SC_AIO_MAX",      _SC_AIO_MAX},
 
6070
#endif
 
6071
#ifdef _SC_AIO_PRIO_DELTA_MAX
 
6072
    {"SC_AIO_PRIO_DELTA_MAX",   _SC_AIO_PRIO_DELTA_MAX},
 
6073
#endif
 
6074
#ifdef _SC_ARG_MAX
 
6075
    {"SC_ARG_MAX",      _SC_ARG_MAX},
 
6076
#endif
 
6077
#ifdef _SC_ASYNCHRONOUS_IO
 
6078
    {"SC_ASYNCHRONOUS_IO",      _SC_ASYNCHRONOUS_IO},
 
6079
#endif
 
6080
#ifdef _SC_ATEXIT_MAX
 
6081
    {"SC_ATEXIT_MAX",   _SC_ATEXIT_MAX},
 
6082
#endif
 
6083
#ifdef _SC_AUDIT
 
6084
    {"SC_AUDIT",        _SC_AUDIT},
 
6085
#endif
 
6086
#ifdef _SC_AVPHYS_PAGES
 
6087
    {"SC_AVPHYS_PAGES", _SC_AVPHYS_PAGES},
 
6088
#endif
 
6089
#ifdef _SC_BC_BASE_MAX
 
6090
    {"SC_BC_BASE_MAX",  _SC_BC_BASE_MAX},
 
6091
#endif
 
6092
#ifdef _SC_BC_DIM_MAX
 
6093
    {"SC_BC_DIM_MAX",   _SC_BC_DIM_MAX},
 
6094
#endif
 
6095
#ifdef _SC_BC_SCALE_MAX
 
6096
    {"SC_BC_SCALE_MAX", _SC_BC_SCALE_MAX},
 
6097
#endif
 
6098
#ifdef _SC_BC_STRING_MAX
 
6099
    {"SC_BC_STRING_MAX",        _SC_BC_STRING_MAX},
 
6100
#endif
 
6101
#ifdef _SC_CAP
 
6102
    {"SC_CAP",  _SC_CAP},
 
6103
#endif
 
6104
#ifdef _SC_CHARCLASS_NAME_MAX
 
6105
    {"SC_CHARCLASS_NAME_MAX",   _SC_CHARCLASS_NAME_MAX},
 
6106
#endif
 
6107
#ifdef _SC_CHAR_BIT
 
6108
    {"SC_CHAR_BIT",     _SC_CHAR_BIT},
 
6109
#endif
 
6110
#ifdef _SC_CHAR_MAX
 
6111
    {"SC_CHAR_MAX",     _SC_CHAR_MAX},
 
6112
#endif
 
6113
#ifdef _SC_CHAR_MIN
 
6114
    {"SC_CHAR_MIN",     _SC_CHAR_MIN},
 
6115
#endif
 
6116
#ifdef _SC_CHILD_MAX
 
6117
    {"SC_CHILD_MAX",    _SC_CHILD_MAX},
 
6118
#endif
 
6119
#ifdef _SC_CLK_TCK
 
6120
    {"SC_CLK_TCK",      _SC_CLK_TCK},
 
6121
#endif
 
6122
#ifdef _SC_COHER_BLKSZ
 
6123
    {"SC_COHER_BLKSZ",  _SC_COHER_BLKSZ},
 
6124
#endif
 
6125
#ifdef _SC_COLL_WEIGHTS_MAX
 
6126
    {"SC_COLL_WEIGHTS_MAX",     _SC_COLL_WEIGHTS_MAX},
 
6127
#endif
 
6128
#ifdef _SC_DCACHE_ASSOC
 
6129
    {"SC_DCACHE_ASSOC", _SC_DCACHE_ASSOC},
 
6130
#endif
 
6131
#ifdef _SC_DCACHE_BLKSZ
 
6132
    {"SC_DCACHE_BLKSZ", _SC_DCACHE_BLKSZ},
 
6133
#endif
 
6134
#ifdef _SC_DCACHE_LINESZ
 
6135
    {"SC_DCACHE_LINESZ",        _SC_DCACHE_LINESZ},
 
6136
#endif
 
6137
#ifdef _SC_DCACHE_SZ
 
6138
    {"SC_DCACHE_SZ",    _SC_DCACHE_SZ},
 
6139
#endif
 
6140
#ifdef _SC_DCACHE_TBLKSZ
 
6141
    {"SC_DCACHE_TBLKSZ",        _SC_DCACHE_TBLKSZ},
 
6142
#endif
 
6143
#ifdef _SC_DELAYTIMER_MAX
 
6144
    {"SC_DELAYTIMER_MAX",       _SC_DELAYTIMER_MAX},
 
6145
#endif
 
6146
#ifdef _SC_EQUIV_CLASS_MAX
 
6147
    {"SC_EQUIV_CLASS_MAX",      _SC_EQUIV_CLASS_MAX},
 
6148
#endif
 
6149
#ifdef _SC_EXPR_NEST_MAX
 
6150
    {"SC_EXPR_NEST_MAX",        _SC_EXPR_NEST_MAX},
 
6151
#endif
 
6152
#ifdef _SC_FSYNC
 
6153
    {"SC_FSYNC",        _SC_FSYNC},
 
6154
#endif
 
6155
#ifdef _SC_GETGR_R_SIZE_MAX
 
6156
    {"SC_GETGR_R_SIZE_MAX",     _SC_GETGR_R_SIZE_MAX},
 
6157
#endif
 
6158
#ifdef _SC_GETPW_R_SIZE_MAX
 
6159
    {"SC_GETPW_R_SIZE_MAX",     _SC_GETPW_R_SIZE_MAX},
 
6160
#endif
 
6161
#ifdef _SC_ICACHE_ASSOC
 
6162
    {"SC_ICACHE_ASSOC", _SC_ICACHE_ASSOC},
 
6163
#endif
 
6164
#ifdef _SC_ICACHE_BLKSZ
 
6165
    {"SC_ICACHE_BLKSZ", _SC_ICACHE_BLKSZ},
 
6166
#endif
 
6167
#ifdef _SC_ICACHE_LINESZ
 
6168
    {"SC_ICACHE_LINESZ",        _SC_ICACHE_LINESZ},
 
6169
#endif
 
6170
#ifdef _SC_ICACHE_SZ
 
6171
    {"SC_ICACHE_SZ",    _SC_ICACHE_SZ},
 
6172
#endif
 
6173
#ifdef _SC_INF
 
6174
    {"SC_INF",  _SC_INF},
 
6175
#endif
 
6176
#ifdef _SC_INT_MAX
 
6177
    {"SC_INT_MAX",      _SC_INT_MAX},
 
6178
#endif
 
6179
#ifdef _SC_INT_MIN
 
6180
    {"SC_INT_MIN",      _SC_INT_MIN},
 
6181
#endif
 
6182
#ifdef _SC_IOV_MAX
 
6183
    {"SC_IOV_MAX",      _SC_IOV_MAX},
 
6184
#endif
 
6185
#ifdef _SC_IP_SECOPTS
 
6186
    {"SC_IP_SECOPTS",   _SC_IP_SECOPTS},
 
6187
#endif
 
6188
#ifdef _SC_JOB_CONTROL
 
6189
    {"SC_JOB_CONTROL",  _SC_JOB_CONTROL},
 
6190
#endif
 
6191
#ifdef _SC_KERN_POINTERS
 
6192
    {"SC_KERN_POINTERS",        _SC_KERN_POINTERS},
 
6193
#endif
 
6194
#ifdef _SC_KERN_SIM
 
6195
    {"SC_KERN_SIM",     _SC_KERN_SIM},
 
6196
#endif
 
6197
#ifdef _SC_LINE_MAX
 
6198
    {"SC_LINE_MAX",     _SC_LINE_MAX},
 
6199
#endif
 
6200
#ifdef _SC_LOGIN_NAME_MAX
 
6201
    {"SC_LOGIN_NAME_MAX",       _SC_LOGIN_NAME_MAX},
 
6202
#endif
 
6203
#ifdef _SC_LOGNAME_MAX
 
6204
    {"SC_LOGNAME_MAX",  _SC_LOGNAME_MAX},
 
6205
#endif
 
6206
#ifdef _SC_LONG_BIT
 
6207
    {"SC_LONG_BIT",     _SC_LONG_BIT},
 
6208
#endif
 
6209
#ifdef _SC_MAC
 
6210
    {"SC_MAC",  _SC_MAC},
 
6211
#endif
 
6212
#ifdef _SC_MAPPED_FILES
 
6213
    {"SC_MAPPED_FILES", _SC_MAPPED_FILES},
 
6214
#endif
 
6215
#ifdef _SC_MAXPID
 
6216
    {"SC_MAXPID",       _SC_MAXPID},
 
6217
#endif
 
6218
#ifdef _SC_MB_LEN_MAX
 
6219
    {"SC_MB_LEN_MAX",   _SC_MB_LEN_MAX},
 
6220
#endif
 
6221
#ifdef _SC_MEMLOCK
 
6222
    {"SC_MEMLOCK",      _SC_MEMLOCK},
 
6223
#endif
 
6224
#ifdef _SC_MEMLOCK_RANGE
 
6225
    {"SC_MEMLOCK_RANGE",        _SC_MEMLOCK_RANGE},
 
6226
#endif
 
6227
#ifdef _SC_MEMORY_PROTECTION
 
6228
    {"SC_MEMORY_PROTECTION",    _SC_MEMORY_PROTECTION},
 
6229
#endif
 
6230
#ifdef _SC_MESSAGE_PASSING
 
6231
    {"SC_MESSAGE_PASSING",      _SC_MESSAGE_PASSING},
 
6232
#endif
 
6233
#ifdef _SC_MMAP_FIXED_ALIGNMENT
 
6234
    {"SC_MMAP_FIXED_ALIGNMENT", _SC_MMAP_FIXED_ALIGNMENT},
 
6235
#endif
 
6236
#ifdef _SC_MQ_OPEN_MAX
 
6237
    {"SC_MQ_OPEN_MAX",  _SC_MQ_OPEN_MAX},
 
6238
#endif
 
6239
#ifdef _SC_MQ_PRIO_MAX
 
6240
    {"SC_MQ_PRIO_MAX",  _SC_MQ_PRIO_MAX},
 
6241
#endif
 
6242
#ifdef _SC_NACLS_MAX
 
6243
    {"SC_NACLS_MAX",    _SC_NACLS_MAX},
 
6244
#endif
 
6245
#ifdef _SC_NGROUPS_MAX
 
6246
    {"SC_NGROUPS_MAX",  _SC_NGROUPS_MAX},
 
6247
#endif
 
6248
#ifdef _SC_NL_ARGMAX
 
6249
    {"SC_NL_ARGMAX",    _SC_NL_ARGMAX},
 
6250
#endif
 
6251
#ifdef _SC_NL_LANGMAX
 
6252
    {"SC_NL_LANGMAX",   _SC_NL_LANGMAX},
 
6253
#endif
 
6254
#ifdef _SC_NL_MSGMAX
 
6255
    {"SC_NL_MSGMAX",    _SC_NL_MSGMAX},
 
6256
#endif
 
6257
#ifdef _SC_NL_NMAX
 
6258
    {"SC_NL_NMAX",      _SC_NL_NMAX},
 
6259
#endif
 
6260
#ifdef _SC_NL_SETMAX
 
6261
    {"SC_NL_SETMAX",    _SC_NL_SETMAX},
 
6262
#endif
 
6263
#ifdef _SC_NL_TEXTMAX
 
6264
    {"SC_NL_TEXTMAX",   _SC_NL_TEXTMAX},
 
6265
#endif
 
6266
#ifdef _SC_NPROCESSORS_CONF
 
6267
    {"SC_NPROCESSORS_CONF",     _SC_NPROCESSORS_CONF},
 
6268
#endif
 
6269
#ifdef _SC_NPROCESSORS_ONLN
 
6270
    {"SC_NPROCESSORS_ONLN",     _SC_NPROCESSORS_ONLN},
 
6271
#endif
 
6272
#ifdef _SC_NPROC_CONF
 
6273
    {"SC_NPROC_CONF",   _SC_NPROC_CONF},
 
6274
#endif
 
6275
#ifdef _SC_NPROC_ONLN
 
6276
    {"SC_NPROC_ONLN",   _SC_NPROC_ONLN},
 
6277
#endif
 
6278
#ifdef _SC_NZERO
 
6279
    {"SC_NZERO",        _SC_NZERO},
 
6280
#endif
 
6281
#ifdef _SC_OPEN_MAX
 
6282
    {"SC_OPEN_MAX",     _SC_OPEN_MAX},
 
6283
#endif
 
6284
#ifdef _SC_PAGESIZE
 
6285
    {"SC_PAGESIZE",     _SC_PAGESIZE},
 
6286
#endif
 
6287
#ifdef _SC_PAGE_SIZE
 
6288
    {"SC_PAGE_SIZE",    _SC_PAGE_SIZE},
 
6289
#endif
 
6290
#ifdef _SC_PASS_MAX
 
6291
    {"SC_PASS_MAX",     _SC_PASS_MAX},
 
6292
#endif
 
6293
#ifdef _SC_PHYS_PAGES
 
6294
    {"SC_PHYS_PAGES",   _SC_PHYS_PAGES},
 
6295
#endif
 
6296
#ifdef _SC_PII
 
6297
    {"SC_PII",  _SC_PII},
 
6298
#endif
 
6299
#ifdef _SC_PII_INTERNET
 
6300
    {"SC_PII_INTERNET", _SC_PII_INTERNET},
 
6301
#endif
 
6302
#ifdef _SC_PII_INTERNET_DGRAM
 
6303
    {"SC_PII_INTERNET_DGRAM",   _SC_PII_INTERNET_DGRAM},
 
6304
#endif
 
6305
#ifdef _SC_PII_INTERNET_STREAM
 
6306
    {"SC_PII_INTERNET_STREAM",  _SC_PII_INTERNET_STREAM},
 
6307
#endif
 
6308
#ifdef _SC_PII_OSI
 
6309
    {"SC_PII_OSI",      _SC_PII_OSI},
 
6310
#endif
 
6311
#ifdef _SC_PII_OSI_CLTS
 
6312
    {"SC_PII_OSI_CLTS", _SC_PII_OSI_CLTS},
 
6313
#endif
 
6314
#ifdef _SC_PII_OSI_COTS
 
6315
    {"SC_PII_OSI_COTS", _SC_PII_OSI_COTS},
 
6316
#endif
 
6317
#ifdef _SC_PII_OSI_M
 
6318
    {"SC_PII_OSI_M",    _SC_PII_OSI_M},
 
6319
#endif
 
6320
#ifdef _SC_PII_SOCKET
 
6321
    {"SC_PII_SOCKET",   _SC_PII_SOCKET},
 
6322
#endif
 
6323
#ifdef _SC_PII_XTI
 
6324
    {"SC_PII_XTI",      _SC_PII_XTI},
 
6325
#endif
 
6326
#ifdef _SC_POLL
 
6327
    {"SC_POLL", _SC_POLL},
 
6328
#endif
 
6329
#ifdef _SC_PRIORITIZED_IO
 
6330
    {"SC_PRIORITIZED_IO",       _SC_PRIORITIZED_IO},
 
6331
#endif
 
6332
#ifdef _SC_PRIORITY_SCHEDULING
 
6333
    {"SC_PRIORITY_SCHEDULING",  _SC_PRIORITY_SCHEDULING},
 
6334
#endif
 
6335
#ifdef _SC_REALTIME_SIGNALS
 
6336
    {"SC_REALTIME_SIGNALS",     _SC_REALTIME_SIGNALS},
 
6337
#endif
 
6338
#ifdef _SC_RE_DUP_MAX
 
6339
    {"SC_RE_DUP_MAX",   _SC_RE_DUP_MAX},
 
6340
#endif
 
6341
#ifdef _SC_RTSIG_MAX
 
6342
    {"SC_RTSIG_MAX",    _SC_RTSIG_MAX},
 
6343
#endif
 
6344
#ifdef _SC_SAVED_IDS
 
6345
    {"SC_SAVED_IDS",    _SC_SAVED_IDS},
 
6346
#endif
 
6347
#ifdef _SC_SCHAR_MAX
 
6348
    {"SC_SCHAR_MAX",    _SC_SCHAR_MAX},
 
6349
#endif
 
6350
#ifdef _SC_SCHAR_MIN
 
6351
    {"SC_SCHAR_MIN",    _SC_SCHAR_MIN},
 
6352
#endif
 
6353
#ifdef _SC_SELECT
 
6354
    {"SC_SELECT",       _SC_SELECT},
 
6355
#endif
 
6356
#ifdef _SC_SEMAPHORES
 
6357
    {"SC_SEMAPHORES",   _SC_SEMAPHORES},
 
6358
#endif
 
6359
#ifdef _SC_SEM_NSEMS_MAX
 
6360
    {"SC_SEM_NSEMS_MAX",        _SC_SEM_NSEMS_MAX},
 
6361
#endif
 
6362
#ifdef _SC_SEM_VALUE_MAX
 
6363
    {"SC_SEM_VALUE_MAX",        _SC_SEM_VALUE_MAX},
 
6364
#endif
 
6365
#ifdef _SC_SHARED_MEMORY_OBJECTS
 
6366
    {"SC_SHARED_MEMORY_OBJECTS",        _SC_SHARED_MEMORY_OBJECTS},
 
6367
#endif
 
6368
#ifdef _SC_SHRT_MAX
 
6369
    {"SC_SHRT_MAX",     _SC_SHRT_MAX},
 
6370
#endif
 
6371
#ifdef _SC_SHRT_MIN
 
6372
    {"SC_SHRT_MIN",     _SC_SHRT_MIN},
 
6373
#endif
 
6374
#ifdef _SC_SIGQUEUE_MAX
 
6375
    {"SC_SIGQUEUE_MAX", _SC_SIGQUEUE_MAX},
 
6376
#endif
 
6377
#ifdef _SC_SIGRT_MAX
 
6378
    {"SC_SIGRT_MAX",    _SC_SIGRT_MAX},
 
6379
#endif
 
6380
#ifdef _SC_SIGRT_MIN
 
6381
    {"SC_SIGRT_MIN",    _SC_SIGRT_MIN},
 
6382
#endif
 
6383
#ifdef _SC_SOFTPOWER
 
6384
    {"SC_SOFTPOWER",    _SC_SOFTPOWER},
 
6385
#endif
 
6386
#ifdef _SC_SPLIT_CACHE
 
6387
    {"SC_SPLIT_CACHE",  _SC_SPLIT_CACHE},
 
6388
#endif
 
6389
#ifdef _SC_SSIZE_MAX
 
6390
    {"SC_SSIZE_MAX",    _SC_SSIZE_MAX},
 
6391
#endif
 
6392
#ifdef _SC_STACK_PROT
 
6393
    {"SC_STACK_PROT",   _SC_STACK_PROT},
 
6394
#endif
 
6395
#ifdef _SC_STREAM_MAX
 
6396
    {"SC_STREAM_MAX",   _SC_STREAM_MAX},
 
6397
#endif
 
6398
#ifdef _SC_SYNCHRONIZED_IO
 
6399
    {"SC_SYNCHRONIZED_IO",      _SC_SYNCHRONIZED_IO},
 
6400
#endif
 
6401
#ifdef _SC_THREADS
 
6402
    {"SC_THREADS",      _SC_THREADS},
 
6403
#endif
 
6404
#ifdef _SC_THREAD_ATTR_STACKADDR
 
6405
    {"SC_THREAD_ATTR_STACKADDR",        _SC_THREAD_ATTR_STACKADDR},
 
6406
#endif
 
6407
#ifdef _SC_THREAD_ATTR_STACKSIZE
 
6408
    {"SC_THREAD_ATTR_STACKSIZE",        _SC_THREAD_ATTR_STACKSIZE},
 
6409
#endif
 
6410
#ifdef _SC_THREAD_DESTRUCTOR_ITERATIONS
 
6411
    {"SC_THREAD_DESTRUCTOR_ITERATIONS", _SC_THREAD_DESTRUCTOR_ITERATIONS},
 
6412
#endif
 
6413
#ifdef _SC_THREAD_KEYS_MAX
 
6414
    {"SC_THREAD_KEYS_MAX",      _SC_THREAD_KEYS_MAX},
 
6415
#endif
 
6416
#ifdef _SC_THREAD_PRIORITY_SCHEDULING
 
6417
    {"SC_THREAD_PRIORITY_SCHEDULING",   _SC_THREAD_PRIORITY_SCHEDULING},
 
6418
#endif
 
6419
#ifdef _SC_THREAD_PRIO_INHERIT
 
6420
    {"SC_THREAD_PRIO_INHERIT",  _SC_THREAD_PRIO_INHERIT},
 
6421
#endif
 
6422
#ifdef _SC_THREAD_PRIO_PROTECT
 
6423
    {"SC_THREAD_PRIO_PROTECT",  _SC_THREAD_PRIO_PROTECT},
 
6424
#endif
 
6425
#ifdef _SC_THREAD_PROCESS_SHARED
 
6426
    {"SC_THREAD_PROCESS_SHARED",        _SC_THREAD_PROCESS_SHARED},
 
6427
#endif
 
6428
#ifdef _SC_THREAD_SAFE_FUNCTIONS
 
6429
    {"SC_THREAD_SAFE_FUNCTIONS",        _SC_THREAD_SAFE_FUNCTIONS},
 
6430
#endif
 
6431
#ifdef _SC_THREAD_STACK_MIN
 
6432
    {"SC_THREAD_STACK_MIN",     _SC_THREAD_STACK_MIN},
 
6433
#endif
 
6434
#ifdef _SC_THREAD_THREADS_MAX
 
6435
    {"SC_THREAD_THREADS_MAX",   _SC_THREAD_THREADS_MAX},
 
6436
#endif
 
6437
#ifdef _SC_TIMERS
 
6438
    {"SC_TIMERS",       _SC_TIMERS},
 
6439
#endif
 
6440
#ifdef _SC_TIMER_MAX
 
6441
    {"SC_TIMER_MAX",    _SC_TIMER_MAX},
 
6442
#endif
 
6443
#ifdef _SC_TTY_NAME_MAX
 
6444
    {"SC_TTY_NAME_MAX", _SC_TTY_NAME_MAX},
 
6445
#endif
 
6446
#ifdef _SC_TZNAME_MAX
 
6447
    {"SC_TZNAME_MAX",   _SC_TZNAME_MAX},
 
6448
#endif
 
6449
#ifdef _SC_T_IOV_MAX
 
6450
    {"SC_T_IOV_MAX",    _SC_T_IOV_MAX},
 
6451
#endif
 
6452
#ifdef _SC_UCHAR_MAX
 
6453
    {"SC_UCHAR_MAX",    _SC_UCHAR_MAX},
 
6454
#endif
 
6455
#ifdef _SC_UINT_MAX
 
6456
    {"SC_UINT_MAX",     _SC_UINT_MAX},
 
6457
#endif
 
6458
#ifdef _SC_UIO_MAXIOV
 
6459
    {"SC_UIO_MAXIOV",   _SC_UIO_MAXIOV},
 
6460
#endif
 
6461
#ifdef _SC_ULONG_MAX
 
6462
    {"SC_ULONG_MAX",    _SC_ULONG_MAX},
 
6463
#endif
 
6464
#ifdef _SC_USHRT_MAX
 
6465
    {"SC_USHRT_MAX",    _SC_USHRT_MAX},
 
6466
#endif
 
6467
#ifdef _SC_VERSION
 
6468
    {"SC_VERSION",      _SC_VERSION},
 
6469
#endif
 
6470
#ifdef _SC_WORD_BIT
 
6471
    {"SC_WORD_BIT",     _SC_WORD_BIT},
 
6472
#endif
 
6473
#ifdef _SC_XBS5_ILP32_OFF32
 
6474
    {"SC_XBS5_ILP32_OFF32",     _SC_XBS5_ILP32_OFF32},
 
6475
#endif
 
6476
#ifdef _SC_XBS5_ILP32_OFFBIG
 
6477
    {"SC_XBS5_ILP32_OFFBIG",    _SC_XBS5_ILP32_OFFBIG},
 
6478
#endif
 
6479
#ifdef _SC_XBS5_LP64_OFF64
 
6480
    {"SC_XBS5_LP64_OFF64",      _SC_XBS5_LP64_OFF64},
 
6481
#endif
 
6482
#ifdef _SC_XBS5_LPBIG_OFFBIG
 
6483
    {"SC_XBS5_LPBIG_OFFBIG",    _SC_XBS5_LPBIG_OFFBIG},
 
6484
#endif
 
6485
#ifdef _SC_XOPEN_CRYPT
 
6486
    {"SC_XOPEN_CRYPT",  _SC_XOPEN_CRYPT},
 
6487
#endif
 
6488
#ifdef _SC_XOPEN_ENH_I18N
 
6489
    {"SC_XOPEN_ENH_I18N",       _SC_XOPEN_ENH_I18N},
 
6490
#endif
 
6491
#ifdef _SC_XOPEN_LEGACY
 
6492
    {"SC_XOPEN_LEGACY", _SC_XOPEN_LEGACY},
 
6493
#endif
 
6494
#ifdef _SC_XOPEN_REALTIME
 
6495
    {"SC_XOPEN_REALTIME",       _SC_XOPEN_REALTIME},
 
6496
#endif
 
6497
#ifdef _SC_XOPEN_REALTIME_THREADS
 
6498
    {"SC_XOPEN_REALTIME_THREADS",       _SC_XOPEN_REALTIME_THREADS},
 
6499
#endif
 
6500
#ifdef _SC_XOPEN_SHM
 
6501
    {"SC_XOPEN_SHM",    _SC_XOPEN_SHM},
 
6502
#endif
 
6503
#ifdef _SC_XOPEN_UNIX
 
6504
    {"SC_XOPEN_UNIX",   _SC_XOPEN_UNIX},
 
6505
#endif
 
6506
#ifdef _SC_XOPEN_VERSION
 
6507
    {"SC_XOPEN_VERSION",        _SC_XOPEN_VERSION},
 
6508
#endif
 
6509
#ifdef _SC_XOPEN_XCU_VERSION
 
6510
    {"SC_XOPEN_XCU_VERSION",    _SC_XOPEN_XCU_VERSION},
 
6511
#endif
 
6512
#ifdef _SC_XOPEN_XPG2
 
6513
    {"SC_XOPEN_XPG2",   _SC_XOPEN_XPG2},
 
6514
#endif
 
6515
#ifdef _SC_XOPEN_XPG3
 
6516
    {"SC_XOPEN_XPG3",   _SC_XOPEN_XPG3},
 
6517
#endif
 
6518
#ifdef _SC_XOPEN_XPG4
 
6519
    {"SC_XOPEN_XPG4",   _SC_XOPEN_XPG4},
 
6520
#endif
 
6521
};
 
6522
 
 
6523
static int
 
6524
conv_sysconf_confname(PyObject *arg, int *valuep)
 
6525
{
 
6526
    return conv_confname(arg, valuep, posix_constants_sysconf,
 
6527
                         sizeof(posix_constants_sysconf)
 
6528
                           / sizeof(struct constdef));
 
6529
}
 
6530
 
 
6531
PyDoc_STRVAR(posix_sysconf__doc__,
 
6532
"sysconf(name) -> integer\n\n\
 
6533
Return an integer-valued system configuration variable.");
 
6534
 
 
6535
static PyObject *
 
6536
posix_sysconf(PyObject *self, PyObject *args)
 
6537
{
 
6538
    PyObject *result = NULL;
 
6539
    int name;
 
6540
 
 
6541
    if (PyArg_ParseTuple(args, "O&:sysconf", conv_sysconf_confname, &name)) {
 
6542
        int value;
 
6543
 
 
6544
        errno = 0;
 
6545
        value = sysconf(name);
 
6546
        if (value == -1 && errno != 0)
 
6547
            posix_error();
 
6548
        else
 
6549
            result = PyLong_FromLong(value);
 
6550
    }
 
6551
    return result;
 
6552
}
 
6553
#endif
 
6554
 
 
6555
 
 
6556
/* This code is used to ensure that the tables of configuration value names
 
6557
 * are in sorted order as required by conv_confname(), and also to build the
 
6558
 * the exported dictionaries that are used to publish information about the
 
6559
 * names available on the host platform.
 
6560
 *
 
6561
 * Sorting the table at runtime ensures that the table is properly ordered
 
6562
 * when used, even for platforms we're not able to test on.  It also makes
 
6563
 * it easier to add additional entries to the tables.
 
6564
 */
 
6565
 
 
6566
static int
 
6567
cmp_constdefs(const void *v1,  const void *v2)
 
6568
{
 
6569
    const struct constdef *c1 =
 
6570
        (const struct constdef *) v1;
 
6571
    const struct constdef *c2 =
 
6572
        (const struct constdef *) v2;
 
6573
 
 
6574
    return strcmp(c1->name, c2->name);
 
6575
}
 
6576
 
 
6577
static int
 
6578
setup_confname_table(struct constdef *table, size_t tablesize,
 
6579
                     char *tablename, PyObject *module)
 
6580
{
 
6581
    PyObject *d = NULL;
 
6582
    size_t i;
 
6583
 
 
6584
    qsort(table, tablesize, sizeof(struct constdef), cmp_constdefs);
 
6585
    d = PyDict_New();
 
6586
    if (d == NULL)
 
6587
            return -1;
 
6588
 
 
6589
    for (i=0; i < tablesize; ++i) {
 
6590
            PyObject *o = PyLong_FromLong(table[i].value);
 
6591
            if (o == NULL || PyDict_SetItemString(d, table[i].name, o) == -1) {
 
6592
                    Py_XDECREF(o);
 
6593
                    Py_DECREF(d);
 
6594
                    return -1;
 
6595
            }
 
6596
            Py_DECREF(o);
 
6597
    }
 
6598
    return PyModule_AddObject(module, tablename, d);
 
6599
}
 
6600
 
 
6601
/* Return -1 on failure, 0 on success. */
 
6602
static int
 
6603
setup_confname_tables(PyObject *module)
 
6604
{
 
6605
#if defined(HAVE_FPATHCONF) || defined(HAVE_PATHCONF)
 
6606
    if (setup_confname_table(posix_constants_pathconf,
 
6607
                             sizeof(posix_constants_pathconf)
 
6608
                               / sizeof(struct constdef),
 
6609
                             "pathconf_names", module))
 
6610
        return -1;
 
6611
#endif
 
6612
#ifdef HAVE_CONFSTR
 
6613
    if (setup_confname_table(posix_constants_confstr,
 
6614
                             sizeof(posix_constants_confstr)
 
6615
                               / sizeof(struct constdef),
 
6616
                             "confstr_names", module))
 
6617
        return -1;
 
6618
#endif
 
6619
#ifdef HAVE_SYSCONF
 
6620
    if (setup_confname_table(posix_constants_sysconf,
 
6621
                             sizeof(posix_constants_sysconf)
 
6622
                               / sizeof(struct constdef),
 
6623
                             "sysconf_names", module))
 
6624
        return -1;
 
6625
#endif
 
6626
    return 0;
 
6627
}
 
6628
 
 
6629
 
 
6630
PyDoc_STRVAR(posix_abort__doc__,
 
6631
"abort() -> does not return!\n\n\
 
6632
Abort the interpreter immediately.  This 'dumps core' or otherwise fails\n\
 
6633
in the hardest way possible on the hosting operating system.");
 
6634
 
 
6635
static PyObject *
 
6636
posix_abort(PyObject *self, PyObject *noargs)
 
6637
{
 
6638
    abort();
 
6639
    /*NOTREACHED*/
 
6640
    Py_FatalError("abort() called from Python code didn't abort!");
 
6641
    return NULL;
 
6642
}
 
6643
 
 
6644
#ifdef MS_WINDOWS
 
6645
PyDoc_STRVAR(win32_startfile__doc__,
 
6646
"startfile(filepath [, operation]) - Start a file with its associated\n\
 
6647
application.\n\
 
6648
\n\
 
6649
When \"operation\" is not specified or \"open\", this acts like\n\
 
6650
double-clicking the file in Explorer, or giving the file name as an\n\
 
6651
argument to the DOS \"start\" command: the file is opened with whatever\n\
 
6652
application (if any) its extension is associated.\n\
 
6653
When another \"operation\" is given, it specifies what should be done with\n\
 
6654
the file.  A typical operation is \"print\".\n\
 
6655
\n\
 
6656
startfile returns as soon as the associated application is launched.\n\
 
6657
There is no option to wait for the application to close, and no way\n\
 
6658
to retrieve the application's exit status.\n\
 
6659
\n\
 
6660
The filepath is relative to the current directory.  If you want to use\n\
 
6661
an absolute path, make sure the first character is not a slash (\"/\");\n\
 
6662
the underlying Win32 ShellExecute function doesn't work if it is.");
 
6663
 
 
6664
static PyObject *
 
6665
win32_startfile(PyObject *self, PyObject *args)
 
6666
{
 
6667
        char *filepath;
 
6668
        char *operation = NULL;
 
6669
        HINSTANCE rc;
 
6670
#ifdef Py_WIN_WIDE_FILENAMES
 
6671
        if (unicode_file_names()) {
 
6672
                PyObject *unipath, *woperation = NULL;
 
6673
                if (!PyArg_ParseTuple(args, "U|s:startfile",
 
6674
                                      &unipath, &operation)) {
 
6675
                        PyErr_Clear();
 
6676
                        goto normal;
 
6677
                }
 
6678
                
 
6679
 
 
6680
                if (operation) {
 
6681
                    woperation = PyUnicode_DecodeASCII(operation, 
 
6682
                                                       strlen(operation), NULL);
 
6683
                    if (!woperation) {
 
6684
                            PyErr_Clear();
 
6685
                            operation = NULL;
 
6686
                            goto normal;
 
6687
                    }
 
6688
                }
 
6689
                        
 
6690
                Py_BEGIN_ALLOW_THREADS
 
6691
                rc = ShellExecuteW((HWND)0, woperation ? PyUnicode_AS_UNICODE(woperation) : 0,
 
6692
                        PyUnicode_AS_UNICODE(unipath),
 
6693
                        NULL, NULL, SW_SHOWNORMAL);
 
6694
                Py_END_ALLOW_THREADS
 
6695
 
 
6696
                Py_XDECREF(woperation);
 
6697
                if (rc <= (HINSTANCE)32) {
 
6698
                        PyObject *errval = win32_error_unicode("startfile",
 
6699
                                                PyUnicode_AS_UNICODE(unipath));
 
6700
                        return errval;
 
6701
                }
 
6702
                Py_INCREF(Py_None);
 
6703
                return Py_None;
 
6704
        }
 
6705
#endif
 
6706
 
 
6707
normal:
 
6708
        if (!PyArg_ParseTuple(args, "et|s:startfile", 
 
6709
                              Py_FileSystemDefaultEncoding, &filepath, 
 
6710
                              &operation))
 
6711
                return NULL;
 
6712
        Py_BEGIN_ALLOW_THREADS
 
6713
        rc = ShellExecute((HWND)0, operation, filepath, 
 
6714
                          NULL, NULL, SW_SHOWNORMAL);
 
6715
        Py_END_ALLOW_THREADS
 
6716
        if (rc <= (HINSTANCE)32) {
 
6717
                PyObject *errval = win32_error("startfile", filepath);
 
6718
                PyMem_Free(filepath);
 
6719
                return errval;
 
6720
        }
 
6721
        PyMem_Free(filepath);
 
6722
        Py_INCREF(Py_None);
 
6723
        return Py_None;
 
6724
}
 
6725
#endif
 
6726
 
 
6727
#ifdef HAVE_GETLOADAVG
 
6728
PyDoc_STRVAR(posix_getloadavg__doc__,
 
6729
"getloadavg() -> (float, float, float)\n\n\
 
6730
Return the number of processes in the system run queue averaged over\n\
 
6731
the last 1, 5, and 15 minutes or raises OSError if the load average\n\
 
6732
was unobtainable");
 
6733
 
 
6734
static PyObject *
 
6735
posix_getloadavg(PyObject *self, PyObject *noargs)
 
6736
{
 
6737
    double loadavg[3];
 
6738
    if (getloadavg(loadavg, 3)!=3) {
 
6739
        PyErr_SetString(PyExc_OSError, "Load averages are unobtainable");
 
6740
        return NULL;
 
6741
    } else
 
6742
        return Py_BuildValue("ddd", loadavg[0], loadavg[1], loadavg[2]);
 
6743
}
 
6744
#endif
 
6745
 
 
6746
#ifdef MS_WINDOWS
 
6747
 
 
6748
PyDoc_STRVAR(win32_urandom__doc__,
 
6749
"urandom(n) -> str\n\n\
 
6750
Return n random bytes suitable for cryptographic use.");
 
6751
 
 
6752
typedef BOOL (WINAPI *CRYPTACQUIRECONTEXTA)(HCRYPTPROV *phProv,\
 
6753
              LPCSTR pszContainer, LPCSTR pszProvider, DWORD dwProvType,\
 
6754
              DWORD dwFlags );
 
6755
typedef BOOL (WINAPI *CRYPTGENRANDOM)(HCRYPTPROV hProv, DWORD dwLen,\
 
6756
              BYTE *pbBuffer );
 
6757
 
 
6758
static CRYPTGENRANDOM pCryptGenRandom = NULL;
 
6759
/* This handle is never explicitly released. Instead, the operating
 
6760
   system will release it when the process terminates. */
 
6761
static HCRYPTPROV hCryptProv = 0;
 
6762
 
 
6763
static PyObject*
 
6764
win32_urandom(PyObject *self, PyObject *args)
 
6765
{
 
6766
        int howMany;
 
6767
        PyObject* result;
 
6768
 
 
6769
        /* Read arguments */
 
6770
        if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
 
6771
                return NULL;
 
6772
        if (howMany < 0)
 
6773
                return PyErr_Format(PyExc_ValueError,
 
6774
                                    "negative argument not allowed");
 
6775
 
 
6776
        if (hCryptProv == 0) {
 
6777
                HINSTANCE hAdvAPI32 = NULL;
 
6778
                CRYPTACQUIRECONTEXTA pCryptAcquireContext = NULL;
 
6779
 
 
6780
                /* Obtain handle to the DLL containing CryptoAPI
 
6781
                   This should not fail */
 
6782
                hAdvAPI32 = GetModuleHandle("advapi32.dll");
 
6783
                if(hAdvAPI32 == NULL)
 
6784
                        return win32_error("GetModuleHandle", NULL);
 
6785
 
 
6786
                /* Obtain pointers to the CryptoAPI functions
 
6787
                   This will fail on some early versions of Win95 */
 
6788
                pCryptAcquireContext = (CRYPTACQUIRECONTEXTA)GetProcAddress(
 
6789
                                                hAdvAPI32,
 
6790
                                                "CryptAcquireContextA");
 
6791
                if (pCryptAcquireContext == NULL)
 
6792
                        return PyErr_Format(PyExc_NotImplementedError,
 
6793
                                            "CryptAcquireContextA not found");
 
6794
 
 
6795
                pCryptGenRandom = (CRYPTGENRANDOM)GetProcAddress(
 
6796
                                                hAdvAPI32, "CryptGenRandom");
 
6797
                if (pCryptGenRandom == NULL)
 
6798
                        return PyErr_Format(PyExc_NotImplementedError,
 
6799
                                            "CryptGenRandom not found");
 
6800
 
 
6801
                /* Acquire context */
 
6802
                if (! pCryptAcquireContext(&hCryptProv, NULL, NULL,
 
6803
                                           PROV_RSA_FULL, CRYPT_VERIFYCONTEXT))
 
6804
                        return win32_error("CryptAcquireContext", NULL);
 
6805
        }
 
6806
 
 
6807
        /* Allocate bytes */
 
6808
        result = PyBytes_FromStringAndSize(NULL, howMany);
 
6809
        if (result != NULL) {
 
6810
                /* Get random data */
 
6811
                memset(PyBytes_AS_STRING(result), 0, howMany); /* zero seed */
 
6812
                if (! pCryptGenRandom(hCryptProv, howMany, (unsigned char*)
 
6813
                                      PyBytes_AS_STRING(result))) {
 
6814
                        Py_DECREF(result);
 
6815
                        return win32_error("CryptGenRandom", NULL);
 
6816
                }
 
6817
        }
 
6818
        return result;
 
6819
}
 
6820
#endif
 
6821
 
 
6822
PyDoc_STRVAR(device_encoding__doc__,
 
6823
"device_encoding(fd) -> str\n\n\
 
6824
Return a string describing the encoding of the device\n\
 
6825
if the output is a terminal; else return None.");
 
6826
 
 
6827
static PyObject *
 
6828
device_encoding(PyObject *self, PyObject *args)
 
6829
{
 
6830
        int fd;
 
6831
        if (!PyArg_ParseTuple(args, "i:device_encoding", &fd))
 
6832
                return NULL;
 
6833
        if (!_PyVerify_fd(fd))
 
6834
                return posix_error();
 
6835
        if (!isatty(fd)) {
 
6836
                Py_INCREF(Py_None);
 
6837
                return Py_None;
 
6838
        }
 
6839
#if defined(MS_WINDOWS) || defined(MS_WIN64)
 
6840
        if (fd == 0) {
 
6841
                char buf[100];
 
6842
                sprintf(buf, "cp%d", GetConsoleCP());
 
6843
                return PyUnicode_FromString(buf);
 
6844
        }
 
6845
        if (fd == 1 || fd == 2) {
 
6846
                char buf[100];
 
6847
                sprintf(buf, "cp%d", GetConsoleOutputCP());
 
6848
                return PyUnicode_FromString(buf);
 
6849
        }
 
6850
#elif defined(CODESET)
 
6851
        {
 
6852
                char *codeset = nl_langinfo(CODESET);
 
6853
                if (codeset != NULL && codeset[0] != 0)
 
6854
                        return PyUnicode_FromString(codeset);
 
6855
        }
 
6856
#endif
 
6857
        Py_INCREF(Py_None);
 
6858
        return Py_None;
 
6859
}
 
6860
 
 
6861
#ifdef __VMS
 
6862
/* Use openssl random routine */
 
6863
#include <openssl/rand.h>
 
6864
PyDoc_STRVAR(vms_urandom__doc__,
 
6865
"urandom(n) -> str\n\n\
 
6866
Return n random bytes suitable for cryptographic use.");
 
6867
 
 
6868
static PyObject*
 
6869
vms_urandom(PyObject *self, PyObject *args)
 
6870
{
 
6871
        int howMany;
 
6872
        PyObject* result;
 
6873
 
 
6874
        /* Read arguments */
 
6875
        if (! PyArg_ParseTuple(args, "i:urandom", &howMany))
 
6876
                return NULL;
 
6877
        if (howMany < 0)
 
6878
                return PyErr_Format(PyExc_ValueError,
 
6879
                                    "negative argument not allowed");
 
6880
 
 
6881
        /* Allocate bytes */
 
6882
        result = PyBytes_FromStringAndSize(NULL, howMany);
 
6883
        if (result != NULL) {
 
6884
                /* Get random data */
 
6885
                if (RAND_pseudo_bytes((unsigned char*)
 
6886
                                      PyBytes_AS_STRING(result),
 
6887
                                      howMany) < 0) {
 
6888
                        Py_DECREF(result);
 
6889
                        return PyErr_Format(PyExc_ValueError,
 
6890
                                            "RAND_pseudo_bytes");
 
6891
                }
 
6892
        }
 
6893
        return result;
 
6894
}
 
6895
#endif
 
6896
 
 
6897
static PyMethodDef posix_methods[] = {
 
6898
        {"access",      posix_access, METH_VARARGS, posix_access__doc__},
 
6899
#ifdef HAVE_TTYNAME
 
6900
        {"ttyname",     posix_ttyname, METH_VARARGS, posix_ttyname__doc__},
 
6901
#endif
 
6902
        {"chdir",       posix_chdir, METH_VARARGS, posix_chdir__doc__},
 
6903
#ifdef HAVE_CHFLAGS
 
6904
        {"chflags",     posix_chflags, METH_VARARGS, posix_chflags__doc__},
 
6905
#endif /* HAVE_CHFLAGS */
 
6906
        {"chmod",       posix_chmod, METH_VARARGS, posix_chmod__doc__},
 
6907
#ifdef HAVE_FCHMOD
 
6908
        {"fchmod",      posix_fchmod, METH_VARARGS, posix_fchmod__doc__},
 
6909
#endif /* HAVE_FCHMOD */
 
6910
#ifdef HAVE_CHOWN
 
6911
        {"chown",       posix_chown, METH_VARARGS, posix_chown__doc__},
 
6912
#endif /* HAVE_CHOWN */
 
6913
#ifdef HAVE_LCHMOD
 
6914
        {"lchmod",      posix_lchmod, METH_VARARGS, posix_lchmod__doc__},
 
6915
#endif /* HAVE_LCHMOD */
 
6916
#ifdef HAVE_FCHOWN
 
6917
        {"fchown",      posix_fchown, METH_VARARGS, posix_fchown__doc__},
 
6918
#endif /* HAVE_FCHOWN */
 
6919
#ifdef HAVE_LCHFLAGS
 
6920
        {"lchflags",    posix_lchflags, METH_VARARGS, posix_lchflags__doc__},
 
6921
#endif /* HAVE_LCHFLAGS */
 
6922
#ifdef HAVE_LCHOWN
 
6923
        {"lchown",      posix_lchown, METH_VARARGS, posix_lchown__doc__},
 
6924
#endif /* HAVE_LCHOWN */
 
6925
#ifdef HAVE_CHROOT
 
6926
        {"chroot",      posix_chroot, METH_VARARGS, posix_chroot__doc__},
 
6927
#endif
 
6928
#ifdef HAVE_CTERMID
 
6929
        {"ctermid",     posix_ctermid, METH_NOARGS, posix_ctermid__doc__},
 
6930
#endif
 
6931
#ifdef HAVE_GETCWD
 
6932
        {"getcwd",      (PyCFunction)posix_getcwd_unicode,
 
6933
        METH_NOARGS, posix_getcwd__doc__},
 
6934
        {"getcwdb",     (PyCFunction)posix_getcwd_bytes,
 
6935
        METH_NOARGS, posix_getcwdb__doc__},
 
6936
#endif
 
6937
#ifdef HAVE_LINK
 
6938
        {"link",        posix_link, METH_VARARGS, posix_link__doc__},
 
6939
#endif /* HAVE_LINK */
 
6940
        {"listdir",     posix_listdir, METH_VARARGS, posix_listdir__doc__},
 
6941
        {"lstat",       posix_lstat, METH_VARARGS, posix_lstat__doc__},
 
6942
        {"mkdir",       posix_mkdir, METH_VARARGS, posix_mkdir__doc__},
 
6943
#ifdef HAVE_NICE
 
6944
        {"nice",        posix_nice, METH_VARARGS, posix_nice__doc__},
 
6945
#endif /* HAVE_NICE */
 
6946
#ifdef HAVE_READLINK
 
6947
        {"readlink",    posix_readlink, METH_VARARGS, posix_readlink__doc__},
 
6948
#endif /* HAVE_READLINK */
 
6949
        {"rename",      posix_rename, METH_VARARGS, posix_rename__doc__},
 
6950
        {"rmdir",       posix_rmdir, METH_VARARGS, posix_rmdir__doc__},
 
6951
        {"stat",        posix_stat, METH_VARARGS, posix_stat__doc__},
 
6952
        {"stat_float_times", stat_float_times, METH_VARARGS, stat_float_times__doc__},
 
6953
#ifdef HAVE_SYMLINK
 
6954
        {"symlink",     posix_symlink, METH_VARARGS, posix_symlink__doc__},
 
6955
#endif /* HAVE_SYMLINK */
 
6956
#ifdef HAVE_SYSTEM
 
6957
        {"system",      posix_system, METH_VARARGS, posix_system__doc__},
 
6958
#endif
 
6959
        {"umask",       posix_umask, METH_VARARGS, posix_umask__doc__},
 
6960
#ifdef HAVE_UNAME
 
6961
        {"uname",       posix_uname, METH_NOARGS, posix_uname__doc__},
 
6962
#endif /* HAVE_UNAME */
 
6963
        {"unlink",      posix_unlink, METH_VARARGS, posix_unlink__doc__},
 
6964
        {"remove",      posix_unlink, METH_VARARGS, posix_remove__doc__},
 
6965
        {"utime",       posix_utime, METH_VARARGS, posix_utime__doc__},
 
6966
#ifdef HAVE_TIMES
 
6967
        {"times",       posix_times, METH_NOARGS, posix_times__doc__},
 
6968
#endif /* HAVE_TIMES */
 
6969
        {"_exit",       posix__exit, METH_VARARGS, posix__exit__doc__},
 
6970
#ifdef HAVE_EXECV
 
6971
        {"execv",       posix_execv, METH_VARARGS, posix_execv__doc__},
 
6972
        {"execve",      posix_execve, METH_VARARGS, posix_execve__doc__},
 
6973
#endif /* HAVE_EXECV */
 
6974
#ifdef HAVE_SPAWNV
 
6975
        {"spawnv",      posix_spawnv, METH_VARARGS, posix_spawnv__doc__},
 
6976
        {"spawnve",     posix_spawnve, METH_VARARGS, posix_spawnve__doc__},
 
6977
#if defined(PYOS_OS2)
 
6978
        {"spawnvp",     posix_spawnvp, METH_VARARGS, posix_spawnvp__doc__},
 
6979
        {"spawnvpe",    posix_spawnvpe, METH_VARARGS, posix_spawnvpe__doc__},
 
6980
#endif /* PYOS_OS2 */
 
6981
#endif /* HAVE_SPAWNV */
 
6982
#ifdef HAVE_FORK1
 
6983
        {"fork1",       posix_fork1, METH_NOARGS, posix_fork1__doc__},
 
6984
#endif /* HAVE_FORK1 */
 
6985
#ifdef HAVE_FORK
 
6986
        {"fork",        posix_fork, METH_NOARGS, posix_fork__doc__},
 
6987
#endif /* HAVE_FORK */
 
6988
#if defined(HAVE_OPENPTY) || defined(HAVE__GETPTY) || defined(HAVE_DEV_PTMX)
 
6989
        {"openpty",     posix_openpty, METH_NOARGS, posix_openpty__doc__},
 
6990
#endif /* HAVE_OPENPTY || HAVE__GETPTY || HAVE_DEV_PTMX */
 
6991
#ifdef HAVE_FORKPTY
 
6992
        {"forkpty",     posix_forkpty, METH_NOARGS, posix_forkpty__doc__},
 
6993
#endif /* HAVE_FORKPTY */
 
6994
#ifdef HAVE_GETEGID
 
6995
        {"getegid",     posix_getegid, METH_NOARGS, posix_getegid__doc__},
 
6996
#endif /* HAVE_GETEGID */
 
6997
#ifdef HAVE_GETEUID
 
6998
        {"geteuid",     posix_geteuid, METH_NOARGS, posix_geteuid__doc__},
 
6999
#endif /* HAVE_GETEUID */
 
7000
#ifdef HAVE_GETGID
 
7001
        {"getgid",      posix_getgid, METH_NOARGS, posix_getgid__doc__},
 
7002
#endif /* HAVE_GETGID */
 
7003
#ifdef HAVE_GETGROUPS
 
7004
        {"getgroups",   posix_getgroups, METH_NOARGS, posix_getgroups__doc__},
 
7005
#endif
 
7006
        {"getpid",      posix_getpid, METH_NOARGS, posix_getpid__doc__},
 
7007
#ifdef HAVE_GETPGRP
 
7008
        {"getpgrp",     posix_getpgrp, METH_NOARGS, posix_getpgrp__doc__},
 
7009
#endif /* HAVE_GETPGRP */
 
7010
#ifdef HAVE_GETPPID
 
7011
        {"getppid",     posix_getppid, METH_NOARGS, posix_getppid__doc__},
 
7012
#endif /* HAVE_GETPPID */
 
7013
#ifdef HAVE_GETUID
 
7014
        {"getuid",      posix_getuid, METH_NOARGS, posix_getuid__doc__},
 
7015
#endif /* HAVE_GETUID */
 
7016
#ifdef HAVE_GETLOGIN
 
7017
        {"getlogin",    posix_getlogin, METH_NOARGS, posix_getlogin__doc__},
 
7018
#endif
 
7019
#ifdef HAVE_KILL
 
7020
        {"kill",        posix_kill, METH_VARARGS, posix_kill__doc__},
 
7021
#endif /* HAVE_KILL */
 
7022
#ifdef HAVE_KILLPG
 
7023
        {"killpg",      posix_killpg, METH_VARARGS, posix_killpg__doc__},
 
7024
#endif /* HAVE_KILLPG */
 
7025
#ifdef HAVE_PLOCK
 
7026
        {"plock",       posix_plock, METH_VARARGS, posix_plock__doc__},
 
7027
#endif /* HAVE_PLOCK */
 
7028
#ifdef MS_WINDOWS
 
7029
        {"startfile",   win32_startfile, METH_VARARGS, win32_startfile__doc__},
 
7030
#endif
 
7031
#ifdef HAVE_SETUID
 
7032
        {"setuid",      posix_setuid, METH_VARARGS, posix_setuid__doc__},
 
7033
#endif /* HAVE_SETUID */
 
7034
#ifdef HAVE_SETEUID
 
7035
        {"seteuid",     posix_seteuid, METH_VARARGS, posix_seteuid__doc__},
 
7036
#endif /* HAVE_SETEUID */
 
7037
#ifdef HAVE_SETEGID
 
7038
        {"setegid",     posix_setegid, METH_VARARGS, posix_setegid__doc__},
 
7039
#endif /* HAVE_SETEGID */
 
7040
#ifdef HAVE_SETREUID
 
7041
        {"setreuid",    posix_setreuid, METH_VARARGS, posix_setreuid__doc__},
 
7042
#endif /* HAVE_SETREUID */
 
7043
#ifdef HAVE_SETREGID
 
7044
        {"setregid",    posix_setregid, METH_VARARGS, posix_setregid__doc__},
 
7045
#endif /* HAVE_SETREGID */
 
7046
#ifdef HAVE_SETGID
 
7047
        {"setgid",      posix_setgid, METH_VARARGS, posix_setgid__doc__},
 
7048
#endif /* HAVE_SETGID */
 
7049
#ifdef HAVE_SETGROUPS
 
7050
        {"setgroups",   posix_setgroups, METH_O, posix_setgroups__doc__},
 
7051
#endif /* HAVE_SETGROUPS */
 
7052
#ifdef HAVE_GETPGID
 
7053
        {"getpgid",     posix_getpgid, METH_VARARGS, posix_getpgid__doc__},
 
7054
#endif /* HAVE_GETPGID */
 
7055
#ifdef HAVE_SETPGRP
 
7056
        {"setpgrp",     posix_setpgrp, METH_NOARGS, posix_setpgrp__doc__},
 
7057
#endif /* HAVE_SETPGRP */
 
7058
#ifdef HAVE_WAIT
 
7059
        {"wait",        posix_wait, METH_NOARGS, posix_wait__doc__},
 
7060
#endif /* HAVE_WAIT */
 
7061
#ifdef HAVE_WAIT3
 
7062
        {"wait3",       posix_wait3, METH_VARARGS, posix_wait3__doc__},
 
7063
#endif /* HAVE_WAIT3 */
 
7064
#ifdef HAVE_WAIT4
 
7065
        {"wait4",       posix_wait4, METH_VARARGS, posix_wait4__doc__},
 
7066
#endif /* HAVE_WAIT4 */
 
7067
#if defined(HAVE_WAITPID) || defined(HAVE_CWAIT)
 
7068
        {"waitpid",     posix_waitpid, METH_VARARGS, posix_waitpid__doc__},
 
7069
#endif /* HAVE_WAITPID */
 
7070
#ifdef HAVE_GETSID
 
7071
        {"getsid",      posix_getsid, METH_VARARGS, posix_getsid__doc__},
 
7072
#endif /* HAVE_GETSID */
 
7073
#ifdef HAVE_SETSID
 
7074
        {"setsid",      posix_setsid, METH_NOARGS, posix_setsid__doc__},
 
7075
#endif /* HAVE_SETSID */
 
7076
#ifdef HAVE_SETPGID
 
7077
        {"setpgid",     posix_setpgid, METH_VARARGS, posix_setpgid__doc__},
 
7078
#endif /* HAVE_SETPGID */
 
7079
#ifdef HAVE_TCGETPGRP
 
7080
        {"tcgetpgrp",   posix_tcgetpgrp, METH_VARARGS, posix_tcgetpgrp__doc__},
 
7081
#endif /* HAVE_TCGETPGRP */
 
7082
#ifdef HAVE_TCSETPGRP
 
7083
        {"tcsetpgrp",   posix_tcsetpgrp, METH_VARARGS, posix_tcsetpgrp__doc__},
 
7084
#endif /* HAVE_TCSETPGRP */
 
7085
        {"open",        posix_open, METH_VARARGS, posix_open__doc__},
 
7086
        {"close",       posix_close, METH_VARARGS, posix_close__doc__},
 
7087
        {"closerange",  posix_closerange, METH_VARARGS, posix_closerange__doc__},
 
7088
        {"device_encoding", device_encoding, METH_VARARGS, device_encoding__doc__},
 
7089
        {"dup",         posix_dup, METH_VARARGS, posix_dup__doc__},
 
7090
        {"dup2",        posix_dup2, METH_VARARGS, posix_dup2__doc__},
 
7091
        {"lseek",       posix_lseek, METH_VARARGS, posix_lseek__doc__},
 
7092
        {"read",        posix_read, METH_VARARGS, posix_read__doc__},
 
7093
        {"write",       posix_write, METH_VARARGS, posix_write__doc__},
 
7094
        {"fstat",       posix_fstat, METH_VARARGS, posix_fstat__doc__},
 
7095
        {"isatty",      posix_isatty, METH_VARARGS, posix_isatty__doc__},
 
7096
#ifdef HAVE_PIPE
 
7097
        {"pipe",        posix_pipe, METH_NOARGS, posix_pipe__doc__},
 
7098
#endif
 
7099
#ifdef HAVE_MKFIFO
 
7100
        {"mkfifo",      posix_mkfifo, METH_VARARGS, posix_mkfifo__doc__},
 
7101
#endif
 
7102
#if defined(HAVE_MKNOD) && defined(HAVE_MAKEDEV)
 
7103
        {"mknod",       posix_mknod, METH_VARARGS, posix_mknod__doc__},
 
7104
#endif
 
7105
#ifdef HAVE_DEVICE_MACROS
 
7106
        {"major",       posix_major, METH_VARARGS, posix_major__doc__},
 
7107
        {"minor",       posix_minor, METH_VARARGS, posix_minor__doc__},
 
7108
        {"makedev",     posix_makedev, METH_VARARGS, posix_makedev__doc__},
 
7109
#endif
 
7110
#ifdef HAVE_FTRUNCATE
 
7111
        {"ftruncate",   posix_ftruncate, METH_VARARGS, posix_ftruncate__doc__},
 
7112
#endif
 
7113
#ifdef HAVE_PUTENV
 
7114
        {"putenv",      posix_putenv, METH_VARARGS, posix_putenv__doc__},
 
7115
#endif
 
7116
#ifdef HAVE_UNSETENV
 
7117
        {"unsetenv",    posix_unsetenv, METH_VARARGS, posix_unsetenv__doc__},
 
7118
#endif
 
7119
        {"strerror",    posix_strerror, METH_VARARGS, posix_strerror__doc__},
 
7120
#ifdef HAVE_FCHDIR
 
7121
        {"fchdir",      posix_fchdir, METH_O, posix_fchdir__doc__},
 
7122
#endif
 
7123
#ifdef HAVE_FSYNC
 
7124
        {"fsync",       posix_fsync, METH_O, posix_fsync__doc__},
 
7125
#endif
 
7126
#ifdef HAVE_FDATASYNC
 
7127
        {"fdatasync",   posix_fdatasync,  METH_O, posix_fdatasync__doc__},
 
7128
#endif
 
7129
#ifdef HAVE_SYS_WAIT_H
 
7130
#ifdef WCOREDUMP
 
7131
        {"WCOREDUMP",   posix_WCOREDUMP, METH_VARARGS, posix_WCOREDUMP__doc__},
 
7132
#endif /* WCOREDUMP */
 
7133
#ifdef WIFCONTINUED
 
7134
        {"WIFCONTINUED",posix_WIFCONTINUED, METH_VARARGS, posix_WIFCONTINUED__doc__},
 
7135
#endif /* WIFCONTINUED */
 
7136
#ifdef WIFSTOPPED
 
7137
        {"WIFSTOPPED",  posix_WIFSTOPPED, METH_VARARGS, posix_WIFSTOPPED__doc__},
 
7138
#endif /* WIFSTOPPED */
 
7139
#ifdef WIFSIGNALED
 
7140
        {"WIFSIGNALED", posix_WIFSIGNALED, METH_VARARGS, posix_WIFSIGNALED__doc__},
 
7141
#endif /* WIFSIGNALED */
 
7142
#ifdef WIFEXITED
 
7143
        {"WIFEXITED",   posix_WIFEXITED, METH_VARARGS, posix_WIFEXITED__doc__},
 
7144
#endif /* WIFEXITED */
 
7145
#ifdef WEXITSTATUS
 
7146
        {"WEXITSTATUS", posix_WEXITSTATUS, METH_VARARGS, posix_WEXITSTATUS__doc__},
 
7147
#endif /* WEXITSTATUS */
 
7148
#ifdef WTERMSIG
 
7149
        {"WTERMSIG",    posix_WTERMSIG, METH_VARARGS, posix_WTERMSIG__doc__},
 
7150
#endif /* WTERMSIG */
 
7151
#ifdef WSTOPSIG
 
7152
        {"WSTOPSIG",    posix_WSTOPSIG, METH_VARARGS, posix_WSTOPSIG__doc__},
 
7153
#endif /* WSTOPSIG */
 
7154
#endif /* HAVE_SYS_WAIT_H */
 
7155
#if defined(HAVE_FSTATVFS) && defined(HAVE_SYS_STATVFS_H)
 
7156
        {"fstatvfs",    posix_fstatvfs, METH_VARARGS, posix_fstatvfs__doc__},
 
7157
#endif
 
7158
#if defined(HAVE_STATVFS) && defined(HAVE_SYS_STATVFS_H)
 
7159
        {"statvfs",     posix_statvfs, METH_VARARGS, posix_statvfs__doc__},
 
7160
#endif
 
7161
#ifdef HAVE_CONFSTR
 
7162
        {"confstr",     posix_confstr, METH_VARARGS, posix_confstr__doc__},
 
7163
#endif
 
7164
#ifdef HAVE_SYSCONF
 
7165
        {"sysconf",     posix_sysconf, METH_VARARGS, posix_sysconf__doc__},
 
7166
#endif
 
7167
#ifdef HAVE_FPATHCONF
 
7168
        {"fpathconf",   posix_fpathconf, METH_VARARGS, posix_fpathconf__doc__},
 
7169
#endif
 
7170
#ifdef HAVE_PATHCONF
 
7171
        {"pathconf",    posix_pathconf, METH_VARARGS, posix_pathconf__doc__},
 
7172
#endif
 
7173
        {"abort",       posix_abort, METH_NOARGS, posix_abort__doc__},
 
7174
#ifdef MS_WINDOWS
 
7175
        {"_getfullpathname",    posix__getfullpathname, METH_VARARGS, NULL},
 
7176
#endif
 
7177
#ifdef HAVE_GETLOADAVG
 
7178
        {"getloadavg",  posix_getloadavg, METH_NOARGS, posix_getloadavg__doc__},
 
7179
#endif
 
7180
 #ifdef MS_WINDOWS
 
7181
        {"urandom", win32_urandom, METH_VARARGS, win32_urandom__doc__},
 
7182
 #endif
 
7183
 #ifdef __VMS
 
7184
        {"urandom", vms_urandom, METH_VARARGS, vms_urandom__doc__},
 
7185
 #endif
 
7186
        {NULL,          NULL}            /* Sentinel */
 
7187
};
 
7188
 
 
7189
 
 
7190
static int
 
7191
ins(PyObject *module, char *symbol, long value)
 
7192
{
 
7193
        return PyModule_AddIntConstant(module, symbol, value);
 
7194
}
 
7195
 
 
7196
#if defined(PYOS_OS2)
 
7197
/* Insert Platform-Specific Constant Values (Strings & Numbers) of Common Use */
 
7198
static int insertvalues(PyObject *module)
 
7199
{
 
7200
    APIRET    rc;
 
7201
    ULONG     values[QSV_MAX+1];
 
7202
    PyObject *v;
 
7203
    char     *ver, tmp[50];
 
7204
 
 
7205
    Py_BEGIN_ALLOW_THREADS
 
7206
    rc = DosQuerySysInfo(1L, QSV_MAX, &values[1], sizeof(ULONG) * QSV_MAX);
 
7207
    Py_END_ALLOW_THREADS
 
7208
 
 
7209
    if (rc != NO_ERROR) {
 
7210
        os2_error(rc);
 
7211
        return -1;
 
7212
    }
 
7213
 
 
7214
    if (ins(module, "meminstalled", values[QSV_TOTPHYSMEM])) return -1;
 
7215
    if (ins(module, "memkernel",    values[QSV_TOTRESMEM])) return -1;
 
7216
    if (ins(module, "memvirtual",   values[QSV_TOTAVAILMEM])) return -1;
 
7217
    if (ins(module, "maxpathlen",   values[QSV_MAX_PATH_LENGTH])) return -1;
 
7218
    if (ins(module, "maxnamelen",   values[QSV_MAX_COMP_LENGTH])) return -1;
 
7219
    if (ins(module, "revision",     values[QSV_VERSION_REVISION])) return -1;
 
7220
    if (ins(module, "timeslice",    values[QSV_MIN_SLICE])) return -1;
 
7221
 
 
7222
    switch (values[QSV_VERSION_MINOR]) {
 
7223
    case 0:  ver = "2.00"; break;
 
7224
    case 10: ver = "2.10"; break;
 
7225
    case 11: ver = "2.11"; break;
 
7226
    case 30: ver = "3.00"; break;
 
7227
    case 40: ver = "4.00"; break;
 
7228
    case 50: ver = "5.00"; break;
 
7229
    default:
 
7230
        PyOS_snprintf(tmp, sizeof(tmp),
 
7231
                      "%d-%d", values[QSV_VERSION_MAJOR],
 
7232
                      values[QSV_VERSION_MINOR]);
 
7233
        ver = &tmp[0];
 
7234
    }
 
7235
 
 
7236
    /* Add Indicator of the Version of the Operating System */
 
7237
    if (PyModule_AddStringConstant(module, "version", tmp) < 0)
 
7238
        return -1;
 
7239
 
 
7240
    /* Add Indicator of Which Drive was Used to Boot the System */
 
7241
    tmp[0] = 'A' + values[QSV_BOOT_DRIVE] - 1;
 
7242
    tmp[1] = ':';
 
7243
    tmp[2] = '\0';
 
7244
 
 
7245
    return PyModule_AddStringConstant(module, "bootdrive", tmp);
 
7246
}
 
7247
#endif
 
7248
 
 
7249
static int
 
7250
all_ins(PyObject *d)
 
7251
{
 
7252
#ifdef F_OK
 
7253
        if (ins(d, "F_OK", (long)F_OK)) return -1;
 
7254
#endif
 
7255
#ifdef R_OK
 
7256
        if (ins(d, "R_OK", (long)R_OK)) return -1;
 
7257
#endif
 
7258
#ifdef W_OK
 
7259
        if (ins(d, "W_OK", (long)W_OK)) return -1;
 
7260
#endif
 
7261
#ifdef X_OK
 
7262
        if (ins(d, "X_OK", (long)X_OK)) return -1;
 
7263
#endif
 
7264
#ifdef NGROUPS_MAX
 
7265
        if (ins(d, "NGROUPS_MAX", (long)NGROUPS_MAX)) return -1;
 
7266
#endif
 
7267
#ifdef TMP_MAX
 
7268
        if (ins(d, "TMP_MAX", (long)TMP_MAX)) return -1;
 
7269
#endif
 
7270
#ifdef WCONTINUED
 
7271
        if (ins(d, "WCONTINUED", (long)WCONTINUED)) return -1;
 
7272
#endif
 
7273
#ifdef WNOHANG
 
7274
        if (ins(d, "WNOHANG", (long)WNOHANG)) return -1;
 
7275
#endif
 
7276
#ifdef WUNTRACED
 
7277
        if (ins(d, "WUNTRACED", (long)WUNTRACED)) return -1;
 
7278
#endif
 
7279
#ifdef O_RDONLY
 
7280
        if (ins(d, "O_RDONLY", (long)O_RDONLY)) return -1;
 
7281
#endif
 
7282
#ifdef O_WRONLY
 
7283
        if (ins(d, "O_WRONLY", (long)O_WRONLY)) return -1;
 
7284
#endif
 
7285
#ifdef O_RDWR
 
7286
        if (ins(d, "O_RDWR", (long)O_RDWR)) return -1;
 
7287
#endif
 
7288
#ifdef O_NDELAY
 
7289
        if (ins(d, "O_NDELAY", (long)O_NDELAY)) return -1;
 
7290
#endif
 
7291
#ifdef O_NONBLOCK
 
7292
        if (ins(d, "O_NONBLOCK", (long)O_NONBLOCK)) return -1;
 
7293
#endif
 
7294
#ifdef O_APPEND
 
7295
        if (ins(d, "O_APPEND", (long)O_APPEND)) return -1;
 
7296
#endif
 
7297
#ifdef O_DSYNC
 
7298
        if (ins(d, "O_DSYNC", (long)O_DSYNC)) return -1;
 
7299
#endif
 
7300
#ifdef O_RSYNC
 
7301
        if (ins(d, "O_RSYNC", (long)O_RSYNC)) return -1;
 
7302
#endif
 
7303
#ifdef O_SYNC
 
7304
        if (ins(d, "O_SYNC", (long)O_SYNC)) return -1;
 
7305
#endif
 
7306
#ifdef O_NOCTTY
 
7307
        if (ins(d, "O_NOCTTY", (long)O_NOCTTY)) return -1;
 
7308
#endif
 
7309
#ifdef O_CREAT
 
7310
        if (ins(d, "O_CREAT", (long)O_CREAT)) return -1;
 
7311
#endif
 
7312
#ifdef O_EXCL
 
7313
        if (ins(d, "O_EXCL", (long)O_EXCL)) return -1;
 
7314
#endif
 
7315
#ifdef O_TRUNC
 
7316
        if (ins(d, "O_TRUNC", (long)O_TRUNC)) return -1;
 
7317
#endif
 
7318
#ifdef O_BINARY
 
7319
        if (ins(d, "O_BINARY", (long)O_BINARY)) return -1;
 
7320
#endif
 
7321
#ifdef O_TEXT
 
7322
        if (ins(d, "O_TEXT", (long)O_TEXT)) return -1;
 
7323
#endif
 
7324
#ifdef O_LARGEFILE
 
7325
        if (ins(d, "O_LARGEFILE", (long)O_LARGEFILE)) return -1;
 
7326
#endif
 
7327
#ifdef O_SHLOCK
 
7328
        if (ins(d, "O_SHLOCK", (long)O_SHLOCK)) return -1;
 
7329
#endif
 
7330
#ifdef O_EXLOCK
 
7331
        if (ins(d, "O_EXLOCK", (long)O_EXLOCK)) return -1;
 
7332
#endif
 
7333
 
 
7334
/* MS Windows */
 
7335
#ifdef O_NOINHERIT
 
7336
        /* Don't inherit in child processes. */
 
7337
        if (ins(d, "O_NOINHERIT", (long)O_NOINHERIT)) return -1;
 
7338
#endif
 
7339
#ifdef _O_SHORT_LIVED
 
7340
        /* Optimize for short life (keep in memory). */
 
7341
        /* MS forgot to define this one with a non-underscore form too. */
 
7342
        if (ins(d, "O_SHORT_LIVED", (long)_O_SHORT_LIVED)) return -1;
 
7343
#endif
 
7344
#ifdef O_TEMPORARY
 
7345
        /* Automatically delete when last handle is closed. */
 
7346
        if (ins(d, "O_TEMPORARY", (long)O_TEMPORARY)) return -1;
 
7347
#endif
 
7348
#ifdef O_RANDOM
 
7349
        /* Optimize for random access. */
 
7350
        if (ins(d, "O_RANDOM", (long)O_RANDOM)) return -1;
 
7351
#endif
 
7352
#ifdef O_SEQUENTIAL
 
7353
        /* Optimize for sequential access. */
 
7354
        if (ins(d, "O_SEQUENTIAL", (long)O_SEQUENTIAL)) return -1;
 
7355
#endif
 
7356
 
 
7357
/* GNU extensions. */
 
7358
#ifdef O_ASYNC
 
7359
        /* Send a SIGIO signal whenever input or output 
 
7360
           becomes available on file descriptor */
 
7361
        if (ins(d, "O_ASYNC", (long)O_ASYNC)) return -1;
 
7362
#endif
 
7363
#ifdef O_DIRECT
 
7364
        /* Direct disk access. */
 
7365
        if (ins(d, "O_DIRECT", (long)O_DIRECT)) return -1;
 
7366
#endif
 
7367
#ifdef O_DIRECTORY
 
7368
        /* Must be a directory.  */
 
7369
        if (ins(d, "O_DIRECTORY", (long)O_DIRECTORY)) return -1;
 
7370
#endif
 
7371
#ifdef O_NOFOLLOW
 
7372
        /* Do not follow links.  */
 
7373
        if (ins(d, "O_NOFOLLOW", (long)O_NOFOLLOW)) return -1;
 
7374
#endif
 
7375
#ifdef O_NOATIME
 
7376
        /* Do not update the access time. */
 
7377
        if (ins(d, "O_NOATIME", (long)O_NOATIME)) return -1;
 
7378
#endif
 
7379
 
 
7380
        /* These come from sysexits.h */
 
7381
#ifdef EX_OK
 
7382
        if (ins(d, "EX_OK", (long)EX_OK)) return -1;
 
7383
#endif /* EX_OK */
 
7384
#ifdef EX_USAGE
 
7385
        if (ins(d, "EX_USAGE", (long)EX_USAGE)) return -1;
 
7386
#endif /* EX_USAGE */
 
7387
#ifdef EX_DATAERR
 
7388
        if (ins(d, "EX_DATAERR", (long)EX_DATAERR)) return -1;
 
7389
#endif /* EX_DATAERR */
 
7390
#ifdef EX_NOINPUT
 
7391
        if (ins(d, "EX_NOINPUT", (long)EX_NOINPUT)) return -1;
 
7392
#endif /* EX_NOINPUT */
 
7393
#ifdef EX_NOUSER
 
7394
        if (ins(d, "EX_NOUSER", (long)EX_NOUSER)) return -1;
 
7395
#endif /* EX_NOUSER */
 
7396
#ifdef EX_NOHOST
 
7397
        if (ins(d, "EX_NOHOST", (long)EX_NOHOST)) return -1;
 
7398
#endif /* EX_NOHOST */
 
7399
#ifdef EX_UNAVAILABLE
 
7400
        if (ins(d, "EX_UNAVAILABLE", (long)EX_UNAVAILABLE)) return -1;
 
7401
#endif /* EX_UNAVAILABLE */
 
7402
#ifdef EX_SOFTWARE
 
7403
        if (ins(d, "EX_SOFTWARE", (long)EX_SOFTWARE)) return -1;
 
7404
#endif /* EX_SOFTWARE */
 
7405
#ifdef EX_OSERR
 
7406
        if (ins(d, "EX_OSERR", (long)EX_OSERR)) return -1;
 
7407
#endif /* EX_OSERR */
 
7408
#ifdef EX_OSFILE
 
7409
        if (ins(d, "EX_OSFILE", (long)EX_OSFILE)) return -1;
 
7410
#endif /* EX_OSFILE */
 
7411
#ifdef EX_CANTCREAT
 
7412
        if (ins(d, "EX_CANTCREAT", (long)EX_CANTCREAT)) return -1;
 
7413
#endif /* EX_CANTCREAT */
 
7414
#ifdef EX_IOERR
 
7415
        if (ins(d, "EX_IOERR", (long)EX_IOERR)) return -1;
 
7416
#endif /* EX_IOERR */
 
7417
#ifdef EX_TEMPFAIL
 
7418
        if (ins(d, "EX_TEMPFAIL", (long)EX_TEMPFAIL)) return -1;
 
7419
#endif /* EX_TEMPFAIL */
 
7420
#ifdef EX_PROTOCOL
 
7421
        if (ins(d, "EX_PROTOCOL", (long)EX_PROTOCOL)) return -1;
 
7422
#endif /* EX_PROTOCOL */
 
7423
#ifdef EX_NOPERM
 
7424
        if (ins(d, "EX_NOPERM", (long)EX_NOPERM)) return -1;
 
7425
#endif /* EX_NOPERM */
 
7426
#ifdef EX_CONFIG
 
7427
        if (ins(d, "EX_CONFIG", (long)EX_CONFIG)) return -1;
 
7428
#endif /* EX_CONFIG */
 
7429
#ifdef EX_NOTFOUND
 
7430
        if (ins(d, "EX_NOTFOUND", (long)EX_NOTFOUND)) return -1;
 
7431
#endif /* EX_NOTFOUND */
 
7432
 
 
7433
#ifdef HAVE_SPAWNV
 
7434
#if defined(PYOS_OS2) && defined(PYCC_GCC)
 
7435
        if (ins(d, "P_WAIT", (long)P_WAIT)) return -1;
 
7436
        if (ins(d, "P_NOWAIT", (long)P_NOWAIT)) return -1;
 
7437
        if (ins(d, "P_OVERLAY", (long)P_OVERLAY)) return -1;
 
7438
        if (ins(d, "P_DEBUG", (long)P_DEBUG)) return -1;
 
7439
        if (ins(d, "P_SESSION", (long)P_SESSION)) return -1;
 
7440
        if (ins(d, "P_DETACH", (long)P_DETACH)) return -1;
 
7441
        if (ins(d, "P_PM", (long)P_PM)) return -1;
 
7442
        if (ins(d, "P_DEFAULT", (long)P_DEFAULT)) return -1;
 
7443
        if (ins(d, "P_MINIMIZE", (long)P_MINIMIZE)) return -1;
 
7444
        if (ins(d, "P_MAXIMIZE", (long)P_MAXIMIZE)) return -1;
 
7445
        if (ins(d, "P_FULLSCREEN", (long)P_FULLSCREEN)) return -1;
 
7446
        if (ins(d, "P_WINDOWED", (long)P_WINDOWED)) return -1;
 
7447
        if (ins(d, "P_FOREGROUND", (long)P_FOREGROUND)) return -1;
 
7448
        if (ins(d, "P_BACKGROUND", (long)P_BACKGROUND)) return -1;
 
7449
        if (ins(d, "P_NOCLOSE", (long)P_NOCLOSE)) return -1;
 
7450
        if (ins(d, "P_NOSESSION", (long)P_NOSESSION)) return -1;
 
7451
        if (ins(d, "P_QUOTE", (long)P_QUOTE)) return -1;
 
7452
        if (ins(d, "P_TILDE", (long)P_TILDE)) return -1;
 
7453
        if (ins(d, "P_UNRELATED", (long)P_UNRELATED)) return -1;
 
7454
        if (ins(d, "P_DEBUGDESC", (long)P_DEBUGDESC)) return -1;
 
7455
#else
 
7456
        if (ins(d, "P_WAIT", (long)_P_WAIT)) return -1;
 
7457
        if (ins(d, "P_NOWAIT", (long)_P_NOWAIT)) return -1;
 
7458
        if (ins(d, "P_OVERLAY", (long)_OLD_P_OVERLAY)) return -1;
 
7459
        if (ins(d, "P_NOWAITO", (long)_P_NOWAITO)) return -1;
 
7460
        if (ins(d, "P_DETACH", (long)_P_DETACH)) return -1;
 
7461
#endif
 
7462
#endif
 
7463
 
 
7464
#if defined(PYOS_OS2)
 
7465
        if (insertvalues(d)) return -1;
 
7466
#endif
 
7467
        return 0;
 
7468
}
 
7469
 
 
7470
 
 
7471
#if (defined(_MSC_VER) || defined(__WATCOMC__) || defined(__BORLANDC__)) && !defined(__QNX__)
 
7472
#define INITFUNC PyInit_nt
 
7473
#define MODNAME "nt"
 
7474
 
 
7475
#elif defined(PYOS_OS2)
 
7476
#define INITFUNC PyInit_os2
 
7477
#define MODNAME "os2"
 
7478
 
 
7479
#else
 
7480
#define INITFUNC PyInit_posix
 
7481
#define MODNAME "posix"
 
7482
#endif
 
7483
 
 
7484
static struct PyModuleDef posixmodule = {
 
7485
        PyModuleDef_HEAD_INIT,
 
7486
        MODNAME,
 
7487
        posix__doc__,
 
7488
        -1,
 
7489
        posix_methods,
 
7490
        NULL,
 
7491
        NULL,
 
7492
        NULL,
 
7493
        NULL
 
7494
};
 
7495
 
 
7496
 
 
7497
PyMODINIT_FUNC
 
7498
INITFUNC(void)
 
7499
{
 
7500
        PyObject *m, *v;
 
7501
 
 
7502
        m = PyModule_Create(&posixmodule);
 
7503
        if (m == NULL)
 
7504
                return NULL;
 
7505
 
 
7506
        /* Initialize environ dictionary */
 
7507
        v = convertenviron();
 
7508
        Py_XINCREF(v);
 
7509
        if (v == NULL || PyModule_AddObject(m, "environ", v) != 0)
 
7510
                return NULL;
 
7511
        Py_DECREF(v);
 
7512
 
 
7513
        if (all_ins(m))
 
7514
                return NULL;
 
7515
 
 
7516
        if (setup_confname_tables(m))
 
7517
                return NULL;
 
7518
 
 
7519
        Py_INCREF(PyExc_OSError);
 
7520
        PyModule_AddObject(m, "error", PyExc_OSError);
 
7521
 
 
7522
#ifdef HAVE_PUTENV
 
7523
        if (posix_putenv_garbage == NULL)
 
7524
                posix_putenv_garbage = PyDict_New();
 
7525
#endif
 
7526
 
 
7527
        if (!initialized) {
 
7528
                stat_result_desc.name = MODNAME ".stat_result";
 
7529
                stat_result_desc.fields[7].name = PyStructSequence_UnnamedField;
 
7530
                stat_result_desc.fields[8].name = PyStructSequence_UnnamedField;
 
7531
                stat_result_desc.fields[9].name = PyStructSequence_UnnamedField;
 
7532
                PyStructSequence_InitType(&StatResultType, &stat_result_desc);
 
7533
                structseq_new = StatResultType.tp_new;
 
7534
                StatResultType.tp_new = statresult_new;
 
7535
 
 
7536
                statvfs_result_desc.name = MODNAME ".statvfs_result";
 
7537
                PyStructSequence_InitType(&StatVFSResultType, &statvfs_result_desc);
 
7538
#ifdef NEED_TICKS_PER_SECOND
 
7539
#  if defined(HAVE_SYSCONF) && defined(_SC_CLK_TCK)
 
7540
                ticks_per_second = sysconf(_SC_CLK_TCK);
 
7541
#  elif defined(HZ)
 
7542
                ticks_per_second = HZ;
 
7543
#  else
 
7544
                ticks_per_second = 60; /* magic fallback value; may be bogus */
 
7545
#  endif
 
7546
#endif
 
7547
        }
 
7548
        Py_INCREF((PyObject*) &StatResultType);
 
7549
        PyModule_AddObject(m, "stat_result", (PyObject*) &StatResultType);
 
7550
        Py_INCREF((PyObject*) &StatVFSResultType);
 
7551
        PyModule_AddObject(m, "statvfs_result",
 
7552
                           (PyObject*) &StatVFSResultType);
 
7553
        initialized = 1;
 
7554
 
 
7555
#ifdef __APPLE__
 
7556
        /*
 
7557
         * Step 2 of weak-linking support on Mac OS X.
 
7558
         *
 
7559
         * The code below removes functions that are not available on the
 
7560
         * currently active platform. 
 
7561
         *
 
7562
         * This block allow one to use a python binary that was build on
 
7563
         * OSX 10.4 on OSX 10.3, without loosing access to new APIs on 
 
7564
         * OSX 10.4.
 
7565
         */
 
7566
#ifdef HAVE_FSTATVFS
 
7567
        if (fstatvfs == NULL) {
 
7568
                if (PyObject_DelAttrString(m, "fstatvfs") == -1) {
 
7569
                        return NULL;
 
7570
                }
 
7571
        }
 
7572
#endif /* HAVE_FSTATVFS */
 
7573
 
 
7574
#ifdef HAVE_STATVFS
 
7575
        if (statvfs == NULL) {
 
7576
                if (PyObject_DelAttrString(m, "statvfs") == -1) {
 
7577
                        return NULL;
 
7578
                }
 
7579
        }
 
7580
#endif /* HAVE_STATVFS */
 
7581
 
 
7582
# ifdef HAVE_LCHOWN
 
7583
        if (lchown == NULL) {
 
7584
                if (PyObject_DelAttrString(m, "lchown") == -1) {
 
7585
                        return NULL;
 
7586
                }
 
7587
        }
 
7588
#endif /* HAVE_LCHOWN */
 
7589
 
 
7590
 
 
7591
#endif /* __APPLE__ */
 
7592
        return m;
 
7593
 
 
7594
}
 
7595
 
 
7596
#ifdef __cplusplus
 
7597
}
 
7598
#endif