~ubuntu-branches/ubuntu/precise/python3.2/precise-proposed

« back to all changes in this revision

Viewing changes to Modules/_posixsubprocess.c

  • Committer: Package Import Robot
  • Author(s): Matthias Klose
  • Date: 2012-03-09 18:40:39 UTC
  • mfrom: (30.1.2 sid)
  • Revision ID: package-import@ubuntu.com-20120309184039-j3yk2emxr1plyo21
Tags: 3.2.3~rc1-1
* Python 3.2.3 release candidate 1.
* Update to 20120309 from the 3.2 branch.
* Fix libpython.a symlink. Closes: #660146.
* Build-depend on xauth.
* Run the gdb tests for the debug build only.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* Authors: Gregory P. Smith & Jeffrey Yasskin */
2
2
#include "Python.h"
3
 
#ifdef HAVE_PIPE2
4
 
#define _GNU_SOURCE
 
3
#if defined(HAVE_PIPE2) && !defined(_GNU_SOURCE)
 
4
# define _GNU_SOURCE
5
5
#endif
6
6
#include <unistd.h>
7
7
#include <fcntl.h>
8
 
 
 
8
#ifdef HAVE_SYS_TYPES_H
 
9
#include <sys/types.h>
 
10
#endif
 
11
#if defined(HAVE_SYS_STAT_H) && defined(__FreeBSD__)
 
12
#include <sys/stat.h>
 
13
#endif
 
14
#ifdef HAVE_SYS_SYSCALL_H
 
15
#include <sys/syscall.h>
 
16
#endif
 
17
#ifdef HAVE_DIRENT_H
 
18
#include <dirent.h>
 
19
#endif
 
20
 
 
21
#if defined(sun)
 
22
/* readdir64 is used to work around Solaris 9 bug 6395699. */
 
23
# define readdir readdir64
 
24
# define dirent dirent64
 
25
# if !defined(HAVE_DIRFD)
 
26
/* Some versions of Solaris lack dirfd(). */
 
27
#  define dirfd(dirp) ((dirp)->dd_fd)
 
28
#  define HAVE_DIRFD
 
29
# endif
 
30
#endif
 
31
 
 
32
#if defined(__FreeBSD__) || (defined(__APPLE__) && defined(__MACH__))
 
33
# define FD_DIR "/dev/fd"
 
34
#else
 
35
# define FD_DIR "/proc/self/fd"
 
36
#endif
9
37
 
10
38
#define POSIX_CALL(call)   if ((call) == -1) goto error
11
39
 
15
43
 
16
44
 
17
45
/* Given the gc module call gc.enable() and return 0 on success. */
18
 
static int _enable_gc(PyObject *gc_module)
 
46
static int
 
47
_enable_gc(PyObject *gc_module)
19
48
{
20
49
    PyObject *result;
21
50
    result = PyObject_CallMethod(gc_module, "enable", NULL);
26
55
}
27
56
 
28
57
 
 
58
/* Convert ASCII to a positive int, no libc call. no overflow. -1 on error. */
 
59
static int
 
60
_pos_int_from_ascii(char *name)
 
61
{
 
62
    int num = 0;
 
63
    while (*name >= '0' && *name <= '9') {
 
64
        num = num * 10 + (*name - '0');
 
65
        ++name;
 
66
    }
 
67
    if (*name)
 
68
        return -1;  /* Non digit found, not a number. */
 
69
    return num;
 
70
}
 
71
 
 
72
 
 
73
#if defined(__FreeBSD__)
 
74
/* When /dev/fd isn't mounted it is often a static directory populated
 
75
 * with 0 1 2 or entries for 0 .. 63 on FreeBSD, NetBSD and OpenBSD.
 
76
 * NetBSD and OpenBSD have a /proc fs available (though not necessarily
 
77
 * mounted) and do not have fdescfs for /dev/fd.  MacOS X has a devfs
 
78
 * that properly supports /dev/fd.
 
79
 */
 
80
static int
 
81
_is_fdescfs_mounted_on_dev_fd()
 
82
{
 
83
    struct stat dev_stat;
 
84
    struct stat dev_fd_stat;
 
85
    if (stat("/dev", &dev_stat) != 0)
 
86
        return 0;
 
87
    if (stat(FD_DIR, &dev_fd_stat) != 0)
 
88
        return 0; 
 
89
    if (dev_stat.st_dev == dev_fd_stat.st_dev)
 
90
        return 0;  /* / == /dev == /dev/fd means it is static. #fail */
 
91
    return 1;
 
92
}
 
93
#endif
 
94
 
 
95
 
 
96
/* Returns 1 if there is a problem with fd_sequence, 0 otherwise. */
 
97
static int
 
98
_sanity_check_python_fd_sequence(PyObject *fd_sequence)
 
99
{
 
100
    Py_ssize_t seq_idx, seq_len = PySequence_Length(fd_sequence);
 
101
    long prev_fd = -1;
 
102
    for (seq_idx = 0; seq_idx < seq_len; ++seq_idx) {
 
103
        PyObject* py_fd = PySequence_Fast_GET_ITEM(fd_sequence, seq_idx);
 
104
        long iter_fd = PyLong_AsLong(py_fd);
 
105
        if (iter_fd < 0 || iter_fd < prev_fd || iter_fd > INT_MAX) {
 
106
            /* Negative, overflow, not a Long, unsorted, too big for a fd. */
 
107
            return 1;
 
108
        }
 
109
    }
 
110
    return 0;
 
111
}
 
112
 
 
113
 
 
114
/* Is fd found in the sorted Python Sequence? */
 
115
static int
 
116
_is_fd_in_sorted_fd_sequence(int fd, PyObject *fd_sequence)
 
117
{
 
118
    /* Binary search. */
 
119
    Py_ssize_t search_min = 0;
 
120
    Py_ssize_t search_max = PySequence_Length(fd_sequence) - 1;
 
121
    if (search_max < 0)
 
122
        return 0;
 
123
    do {
 
124
        long middle = (search_min + search_max) / 2;
 
125
        long middle_fd = PyLong_AsLong(
 
126
                PySequence_Fast_GET_ITEM(fd_sequence, middle));
 
127
        if (fd == middle_fd)
 
128
            return 1;
 
129
        if (fd > middle_fd)
 
130
            search_min = middle + 1;
 
131
        else
 
132
            search_max = middle - 1;
 
133
    } while (search_min <= search_max);
 
134
    return 0;
 
135
}
 
136
 
 
137
 
 
138
/* Close all file descriptors in the range start_fd inclusive to
 
139
 * end_fd exclusive except for those in py_fds_to_keep.  If the
 
140
 * range defined by [start_fd, end_fd) is large this will take a
 
141
 * long time as it calls close() on EVERY possible fd.
 
142
 */
 
143
static void
 
144
_close_fds_by_brute_force(int start_fd, int end_fd, PyObject *py_fds_to_keep)
 
145
{
 
146
    Py_ssize_t num_fds_to_keep = PySequence_Length(py_fds_to_keep);
 
147
    Py_ssize_t keep_seq_idx;
 
148
    int fd_num;
 
149
    /* As py_fds_to_keep is sorted we can loop through the list closing
 
150
     * fds inbetween any in the keep list falling within our range. */
 
151
    for (keep_seq_idx = 0; keep_seq_idx < num_fds_to_keep; ++keep_seq_idx) {
 
152
        PyObject* py_keep_fd = PySequence_Fast_GET_ITEM(py_fds_to_keep,
 
153
                                                        keep_seq_idx);
 
154
        int keep_fd = PyLong_AsLong(py_keep_fd);
 
155
        if (keep_fd < start_fd)
 
156
            continue;
 
157
        for (fd_num = start_fd; fd_num < keep_fd; ++fd_num) {
 
158
            while (close(fd_num) < 0 && errno == EINTR);
 
159
        }
 
160
        start_fd = keep_fd + 1;
 
161
    }
 
162
    if (start_fd <= end_fd) {
 
163
        for (fd_num = start_fd; fd_num < end_fd; ++fd_num) {
 
164
            while (close(fd_num) < 0 && errno == EINTR);
 
165
        }
 
166
    }
 
167
}
 
168
 
 
169
 
 
170
#if defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)
 
171
/* It doesn't matter if d_name has room for NAME_MAX chars; we're using this
 
172
 * only to read a directory of short file descriptor number names.  The kernel
 
173
 * will return an error if we didn't give it enough space.  Highly Unlikely.
 
174
 * This structure is very old and stable: It will not change unless the kernel
 
175
 * chooses to break compatibility with all existing binaries.  Highly Unlikely.
 
176
 */
 
177
struct linux_dirent {
 
178
   unsigned long  d_ino;        /* Inode number */
 
179
   unsigned long  d_off;        /* Offset to next linux_dirent */
 
180
   unsigned short d_reclen;     /* Length of this linux_dirent */
 
181
   char           d_name[256];  /* Filename (null-terminated) */
 
182
};
 
183
 
 
184
/* Close all open file descriptors in the range start_fd inclusive to end_fd
 
185
 * exclusive. Do not close any in the sorted py_fds_to_keep list.
 
186
 *
 
187
 * This version is async signal safe as it does not make any unsafe C library
 
188
 * calls, malloc calls or handle any locks.  It is _unfortunate_ to be forced
 
189
 * to resort to making a kernel system call directly but this is the ONLY api
 
190
 * available that does no harm.  opendir/readdir/closedir perform memory
 
191
 * allocation and locking so while they usually work they are not guaranteed
 
192
 * to (especially if you have replaced your malloc implementation).  A version
 
193
 * of this function that uses those can be found in the _maybe_unsafe variant.
 
194
 *
 
195
 * This is Linux specific because that is all I am ready to test it on.  It
 
196
 * should be easy to add OS specific dirent or dirent64 structures and modify
 
197
 * it with some cpp #define magic to work on other OSes as well if you want.
 
198
 */
 
199
static void
 
200
_close_open_fd_range_safe(int start_fd, int end_fd, PyObject* py_fds_to_keep)
 
201
{
 
202
    int fd_dir_fd;
 
203
    if (start_fd >= end_fd)
 
204
        return;
 
205
        fd_dir_fd = open(FD_DIR, O_RDONLY | O_CLOEXEC, 0);
 
206
    if (fd_dir_fd == -1) {
 
207
        /* No way to get a list of open fds. */
 
208
        _close_fds_by_brute_force(start_fd, end_fd, py_fds_to_keep);
 
209
        return;
 
210
    } else {
 
211
        char buffer[sizeof(struct linux_dirent)];
 
212
        int bytes;
 
213
        while ((bytes = syscall(SYS_getdents, fd_dir_fd,
 
214
                                (struct linux_dirent *)buffer,
 
215
                                sizeof(buffer))) > 0) {
 
216
            struct linux_dirent *entry;
 
217
            int offset;
 
218
            for (offset = 0; offset < bytes; offset += entry->d_reclen) {
 
219
                int fd;
 
220
                entry = (struct linux_dirent *)(buffer + offset);
 
221
                if ((fd = _pos_int_from_ascii(entry->d_name)) < 0)
 
222
                    continue;  /* Not a number. */
 
223
                if (fd != fd_dir_fd && fd >= start_fd && fd < end_fd &&
 
224
                    !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) {
 
225
                    while (close(fd) < 0 && errno == EINTR);
 
226
                }
 
227
            }
 
228
        }
 
229
        close(fd_dir_fd);
 
230
    }
 
231
}
 
232
 
 
233
#define _close_open_fd_range _close_open_fd_range_safe
 
234
 
 
235
#else  /* NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */
 
236
 
 
237
 
 
238
/* Close all open file descriptors in the range start_fd inclusive to end_fd
 
239
 * exclusive. Do not close any in the sorted py_fds_to_keep list.
 
240
 *
 
241
 * This function violates the strict use of async signal safe functions. :(
 
242
 * It calls opendir(), readdir() and closedir().  Of these, the one most
 
243
 * likely to ever cause a problem is opendir() as it performs an internal
 
244
 * malloc().  Practically this should not be a problem.  The Java VM makes the
 
245
 * same calls between fork and exec in its own UNIXProcess_md.c implementation.
 
246
 *
 
247
 * readdir_r() is not used because it provides no benefit.  It is typically
 
248
 * implemented as readdir() followed by memcpy().  See also:
 
249
 *   http://womble.decadent.org.uk/readdir_r-advisory.html
 
250
 */
 
251
static void
 
252
_close_open_fd_range_maybe_unsafe(int start_fd, int end_fd,
 
253
                                  PyObject* py_fds_to_keep)
 
254
{
 
255
    DIR *proc_fd_dir;
 
256
#ifndef HAVE_DIRFD
 
257
    while (_is_fd_in_sorted_fd_sequence(start_fd, py_fds_to_keep) &&
 
258
           (start_fd < end_fd)) {
 
259
        ++start_fd;
 
260
    }
 
261
    if (start_fd >= end_fd)
 
262
        return;
 
263
    /* Close our lowest fd before we call opendir so that it is likely to
 
264
     * reuse that fd otherwise we might close opendir's file descriptor in
 
265
     * our loop.  This trick assumes that fd's are allocated on a lowest
 
266
     * available basis. */
 
267
    while (close(start_fd) < 0 && errno == EINTR);
 
268
    ++start_fd;
 
269
#endif
 
270
    if (start_fd >= end_fd)
 
271
        return;
 
272
 
 
273
#if defined(__FreeBSD__)
 
274
    if (!_is_fdescfs_mounted_on_dev_fd())
 
275
        proc_fd_dir = NULL;
 
276
    else
 
277
#endif
 
278
        proc_fd_dir = opendir(FD_DIR);
 
279
    if (!proc_fd_dir) {
 
280
        /* No way to get a list of open fds. */
 
281
        _close_fds_by_brute_force(start_fd, end_fd, py_fds_to_keep);
 
282
    } else {
 
283
        struct dirent *dir_entry;
 
284
#ifdef HAVE_DIRFD
 
285
        int fd_used_by_opendir = dirfd(proc_fd_dir);
 
286
#else
 
287
        int fd_used_by_opendir = start_fd - 1;
 
288
#endif
 
289
        errno = 0;
 
290
        while ((dir_entry = readdir(proc_fd_dir))) {
 
291
            int fd;
 
292
            if ((fd = _pos_int_from_ascii(dir_entry->d_name)) < 0)
 
293
                continue;  /* Not a number. */
 
294
            if (fd != fd_used_by_opendir && fd >= start_fd && fd < end_fd &&
 
295
                !_is_fd_in_sorted_fd_sequence(fd, py_fds_to_keep)) {
 
296
                while (close(fd) < 0 && errno == EINTR);
 
297
            }
 
298
            errno = 0;
 
299
        }
 
300
        if (errno) {
 
301
            /* readdir error, revert behavior. Highly Unlikely. */
 
302
            _close_fds_by_brute_force(start_fd, end_fd, py_fds_to_keep);
 
303
        }
 
304
        closedir(proc_fd_dir);
 
305
    }
 
306
}
 
307
 
 
308
#define _close_open_fd_range _close_open_fd_range_maybe_unsafe
 
309
 
 
310
#endif  /* else NOT (defined(__linux__) && defined(HAVE_SYS_SYSCALL_H)) */
 
311
 
 
312
 
29
313
/*
30
314
 * This function is code executed in the child process immediately after fork
31
315
 * to set things up and call exec().
37
321
 * This restriction is documented at
38
322
 * http://www.opengroup.org/onlinepubs/009695399/functions/fork.html.
39
323
 */
40
 
static void child_exec(char *const exec_array[],
41
 
                       char *const argv[],
42
 
                       char *const envp[],
43
 
                       const char *cwd,
44
 
                       int p2cread, int p2cwrite,
45
 
                       int c2pread, int c2pwrite,
46
 
                       int errread, int errwrite,
47
 
                       int errpipe_read, int errpipe_write,
48
 
                       int close_fds, int restore_signals,
49
 
                       int call_setsid, Py_ssize_t num_fds_to_keep,
50
 
                       PyObject *py_fds_to_keep,
51
 
                       PyObject *preexec_fn,
52
 
                       PyObject *preexec_fn_args_tuple)
 
324
static void
 
325
child_exec(char *const exec_array[],
 
326
           char *const argv[],
 
327
           char *const envp[],
 
328
           const char *cwd,
 
329
           int p2cread, int p2cwrite,
 
330
           int c2pread, int c2pwrite,
 
331
           int errread, int errwrite,
 
332
           int errpipe_read, int errpipe_write,
 
333
           int close_fds, int restore_signals,
 
334
           int call_setsid,
 
335
           PyObject *py_fds_to_keep,
 
336
           PyObject *preexec_fn,
 
337
           PyObject *preexec_fn_args_tuple)
53
338
{
54
 
    int i, saved_errno, fd_num;
 
339
    int i, saved_errno, unused;
55
340
    PyObject *result;
56
341
    const char* err_msg = "";
57
342
    /* Buffer large enough to hold a hex integer.  We can't malloc. */
113
398
        POSIX_CALL(close(errwrite));
114
399
    }
115
400
 
116
 
    /* close() is intentionally not checked for errors here as we are closing */
117
 
    /* a large range of fds, some of which may be invalid. */
118
401
    if (close_fds) {
119
 
        Py_ssize_t keep_seq_idx;
120
 
        int start_fd = 3;
121
 
        for (keep_seq_idx = 0; keep_seq_idx < num_fds_to_keep; ++keep_seq_idx) {
122
 
            PyObject* py_keep_fd = PySequence_Fast_GET_ITEM(py_fds_to_keep,
123
 
                                                            keep_seq_idx);
124
 
            int keep_fd = PyLong_AsLong(py_keep_fd);
125
 
            if (keep_fd < 0) {  /* Negative number, overflow or not a Long. */
126
 
                err_msg = "bad value in fds_to_keep.";
127
 
                errno = 0;  /* We don't want to report an OSError. */
128
 
                goto error;
129
 
            }
130
 
            if (keep_fd < start_fd)
131
 
                continue;
132
 
            for (fd_num = start_fd; fd_num < keep_fd; ++fd_num) {
133
 
                close(fd_num);
134
 
            }
135
 
            start_fd = keep_fd + 1;
136
 
        }
137
 
        if (start_fd <= max_fd) {
138
 
            for (fd_num = start_fd; fd_num < max_fd; ++fd_num) {
139
 
                close(fd_num);
140
 
            }
141
 
        }
 
402
        int local_max_fd = max_fd;
 
403
#if defined(__NetBSD__)
 
404
        local_max_fd = fcntl(0, F_MAXFD);
 
405
        if (local_max_fd < 0)
 
406
            local_max_fd = max_fd;
 
407
#endif
 
408
        /* TODO HP-UX could use pstat_getproc() if anyone cares about it. */
 
409
        _close_open_fd_range(3, local_max_fd, py_fds_to_keep);
142
410
    }
143
411
 
144
412
    if (cwd)
189
457
error:
190
458
    saved_errno = errno;
191
459
    /* Report the posix error to our parent process. */
 
460
    /* We ignore all write() return values as the total size of our writes is
 
461
     * less than PIPEBUF and we cannot do anything about an error anyways. */
192
462
    if (saved_errno) {
193
463
        char *cur;
194
 
        write(errpipe_write, "OSError:", 8);
 
464
        unused = write(errpipe_write, "OSError:", 8);
195
465
        cur = hex_errno + sizeof(hex_errno);
196
466
        while (saved_errno != 0 && cur > hex_errno) {
197
467
            *--cur = "0123456789ABCDEF"[saved_errno % 16];
198
468
            saved_errno /= 16;
199
469
        }
200
 
        write(errpipe_write, cur, hex_errno + sizeof(hex_errno) - cur);
201
 
        write(errpipe_write, ":", 1);
 
470
        unused = write(errpipe_write, cur, hex_errno + sizeof(hex_errno) - cur);
 
471
        unused = write(errpipe_write, ":", 1);
202
472
        /* We can't call strerror(saved_errno).  It is not async signal safe.
203
473
         * The parent process will look the error message up. */
204
474
    } else {
205
 
        write(errpipe_write, "RuntimeError:0:", 15);
206
 
        write(errpipe_write, err_msg, strlen(err_msg));
 
475
        unused = write(errpipe_write, "RuntimeError:0:", 15);
 
476
        unused = write(errpipe_write, err_msg, strlen(err_msg));
207
477
    }
 
478
    if (unused) return;  /* silly? yes! avoids gcc compiler warning. */
208
479
}
209
480
 
210
481
 
224
495
    pid_t pid;
225
496
    int need_to_reenable_gc = 0;
226
497
    char *const *exec_array, *const *argv = NULL, *const *envp = NULL;
227
 
    Py_ssize_t arg_num, num_fds_to_keep;
 
498
    Py_ssize_t arg_num;
228
499
 
229
500
    if (!PyArg_ParseTuple(
230
501
            args, "OOOOOOiiiiiiiiiiO:fork_exec",
240
511
        PyErr_SetString(PyExc_ValueError, "errpipe_write must be >= 3");
241
512
        return NULL;
242
513
    }
243
 
    num_fds_to_keep = PySequence_Length(py_fds_to_keep);
244
 
    if (num_fds_to_keep < 0) {
245
 
        PyErr_SetString(PyExc_ValueError, "bad fds_to_keep");
 
514
    if (PySequence_Length(py_fds_to_keep) < 0) {
 
515
        PyErr_SetString(PyExc_ValueError, "cannot get length of fds_to_keep");
 
516
        return NULL;
 
517
    }
 
518
    if (_sanity_check_python_fd_sequence(py_fds_to_keep)) {
 
519
        PyErr_SetString(PyExc_ValueError, "bad value(s) in fds_to_keep");
246
520
        return NULL;
247
521
    }
248
522
 
345
619
                   p2cread, p2cwrite, c2pread, c2pwrite,
346
620
                   errread, errwrite, errpipe_read, errpipe_write,
347
621
                   close_fds, restore_signals, call_setsid,
348
 
                   num_fds_to_keep, py_fds_to_keep,
349
 
                   preexec_fn, preexec_fn_args_tuple);
 
622
                   py_fds_to_keep, preexec_fn, preexec_fn_args_tuple);
350
623
        _exit(255);
351
624
        return NULL;  /* Dead code to avoid a potential compiler warning. */
352
625
    }
437
710
    Py_END_ALLOW_THREADS
438
711
    if (res != 0 && errno == ENOSYS)
439
712
    {
440
 
        if (PyErr_WarnEx(
441
 
                PyExc_RuntimeWarning,
442
 
                "pipe2 set errno ENOSYS; falling "
443
 
                "back to non-atomic pipe+fcntl.", 1) != 0) {
444
 
            return NULL;
445
 
        }
446
713
        {
447
714
#endif
448
715
        /* We hold the GIL which offers some protection from other code calling