~ubuntu-branches/ubuntu/natty/python3.1/natty-security

« back to all changes in this revision

Viewing changes to Parser/myreadline.c

  • Committer: Bazaar Package Importer
  • Author(s): Matthias Klose
  • Date: 2010-07-06 16:52:42 UTC
  • mfrom: (1.2.1 upstream) (2.1.11 sid)
  • Revision ID: james.westby@ubuntu.com-20100706165242-2xv4i019r3et6c0j
Tags: 3.1.2+20100706-1ubuntu1
* Merge with Debian; remaining changes:
  - Regenerate the control file.
  - Add debian/patches/overwrite-semaphore-check for Lucid buildds.

Show diffs side-by-side

added added

removed removed

Lines of Context:
35
35
static int
36
36
my_fgets(char *buf, int len, FILE *fp)
37
37
{
38
 
        char *p;
39
 
        for (;;) {
40
 
                if (PyOS_InputHook != NULL)
41
 
                        (void)(PyOS_InputHook)();
42
 
                errno = 0;
43
 
                p = fgets(buf, len, fp);
44
 
                if (p != NULL)
45
 
                        return 0; /* No error */
 
38
    char *p;
 
39
    for (;;) {
 
40
        if (PyOS_InputHook != NULL)
 
41
            (void)(PyOS_InputHook)();
 
42
        errno = 0;
 
43
        p = fgets(buf, len, fp);
 
44
        if (p != NULL)
 
45
            return 0; /* No error */
46
46
#ifdef MS_WINDOWS
47
 
                /* In the case of a Ctrl+C or some other external event 
48
 
                   interrupting the operation:
49
 
                   Win2k/NT: ERROR_OPERATION_ABORTED is the most recent Win32 
50
 
                   error code (and feof() returns TRUE).
51
 
                   Win9x: Ctrl+C seems to have no effect on fgets() returning
52
 
                   early - the signal handler is called, but the fgets()
53
 
                   only returns "normally" (ie, when Enter hit or feof())
54
 
                */
55
 
                if (GetLastError()==ERROR_OPERATION_ABORTED) {
56
 
                        /* Signals come asynchronously, so we sleep a brief 
57
 
                           moment before checking if the handler has been 
58
 
                           triggered (we cant just return 1 before the 
59
 
                           signal handler has been called, as the later 
60
 
                           signal may be treated as a separate interrupt).
61
 
                        */
62
 
                        Sleep(1);
63
 
                        if (PyOS_InterruptOccurred()) {
64
 
                                return 1; /* Interrupt */
65
 
                        }
66
 
                        /* Either the sleep wasn't long enough (need a
67
 
                           short loop retrying?) or not interrupted at all
68
 
                           (in which case we should revisit the whole thing!)
69
 
                           Logging some warning would be nice.  assert is not
70
 
                           viable as under the debugger, the various dialogs
71
 
                           mean the condition is not true.
72
 
                        */
73
 
                }
 
47
        /* In the case of a Ctrl+C or some other external event
 
48
           interrupting the operation:
 
49
           Win2k/NT: ERROR_OPERATION_ABORTED is the most recent Win32
 
50
           error code (and feof() returns TRUE).
 
51
           Win9x: Ctrl+C seems to have no effect on fgets() returning
 
52
           early - the signal handler is called, but the fgets()
 
53
           only returns "normally" (ie, when Enter hit or feof())
 
54
        */
 
55
        if (GetLastError()==ERROR_OPERATION_ABORTED) {
 
56
            /* Signals come asynchronously, so we sleep a brief
 
57
               moment before checking if the handler has been
 
58
               triggered (we cant just return 1 before the
 
59
               signal handler has been called, as the later
 
60
               signal may be treated as a separate interrupt).
 
61
            */
 
62
            Sleep(1);
 
63
            if (PyOS_InterruptOccurred()) {
 
64
                return 1; /* Interrupt */
 
65
            }
 
66
            /* Either the sleep wasn't long enough (need a
 
67
               short loop retrying?) or not interrupted at all
 
68
               (in which case we should revisit the whole thing!)
 
69
               Logging some warning would be nice.  assert is not
 
70
               viable as under the debugger, the various dialogs
 
71
               mean the condition is not true.
 
72
            */
 
73
        }
74
74
#endif /* MS_WINDOWS */
75
 
                if (feof(fp)) {
76
 
                        return -1; /* EOF */
77
 
                }
 
75
        if (feof(fp)) {
 
76
            return -1; /* EOF */
 
77
        }
78
78
#ifdef EINTR
79
 
                if (errno == EINTR) {
80
 
                        int s;
81
 
#ifdef WITH_THREAD
82
 
                        PyEval_RestoreThread(_PyOS_ReadlineTState);
83
 
#endif
84
 
                        s = PyErr_CheckSignals();
85
 
#ifdef WITH_THREAD
86
 
                        PyEval_SaveThread();
87
 
#endif
88
 
                        if (s < 0) {
89
 
                                return 1;
90
 
                        }
91
 
                }
92
 
#endif
93
 
                if (PyOS_InterruptOccurred()) {
94
 
                        return 1; /* Interrupt */
95
 
                }
96
 
                return -2; /* Error */
97
 
        }
98
 
        /* NOTREACHED */
 
79
        if (errno == EINTR) {
 
80
            int s;
 
81
#ifdef WITH_THREAD
 
82
            PyEval_RestoreThread(_PyOS_ReadlineTState);
 
83
#endif
 
84
            s = PyErr_CheckSignals();
 
85
#ifdef WITH_THREAD
 
86
            PyEval_SaveThread();
 
87
#endif
 
88
            if (s < 0) {
 
89
                return 1;
 
90
            }
 
91
        }
 
92
#endif
 
93
        if (PyOS_InterruptOccurred()) {
 
94
            return 1; /* Interrupt */
 
95
        }
 
96
        return -2; /* Error */
 
97
    }
 
98
    /* NOTREACHED */
99
99
}
100
100
 
101
101
 
104
104
char *
105
105
PyOS_StdioReadline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
106
106
{
107
 
        size_t n;
108
 
        char *p;
109
 
        n = 100;
110
 
        if ((p = (char *)PyMem_MALLOC(n)) == NULL)
111
 
                return NULL;
112
 
        fflush(sys_stdout);
113
 
        if (prompt)
114
 
                fprintf(stderr, "%s", prompt);
115
 
        fflush(stderr);
116
 
        switch (my_fgets(p, (int)n, sys_stdin)) {
117
 
        case 0: /* Normal case */
118
 
                break;
119
 
        case 1: /* Interrupt */
120
 
                PyMem_FREE(p);
121
 
                return NULL;
122
 
        case -1: /* EOF */
123
 
        case -2: /* Error */
124
 
        default: /* Shouldn't happen */
125
 
                *p = '\0';
126
 
                break;
127
 
        }
128
 
        n = strlen(p);
129
 
        while (n > 0 && p[n-1] != '\n') {
130
 
                size_t incr = n+2;
131
 
                p = (char *)PyMem_REALLOC(p, n + incr);
132
 
                if (p == NULL)
133
 
                        return NULL;
134
 
                if (incr > INT_MAX) {
135
 
                        PyErr_SetString(PyExc_OverflowError, "input line too long");
136
 
                }
137
 
                if (my_fgets(p+n, (int)incr, sys_stdin) != 0)
138
 
                        break;
139
 
                n += strlen(p+n);
140
 
        }
141
 
        return (char *)PyMem_REALLOC(p, n+1);
 
107
    size_t n;
 
108
    char *p;
 
109
    n = 100;
 
110
    if ((p = (char *)PyMem_MALLOC(n)) == NULL)
 
111
        return NULL;
 
112
    fflush(sys_stdout);
 
113
    if (prompt)
 
114
        fprintf(stderr, "%s", prompt);
 
115
    fflush(stderr);
 
116
    switch (my_fgets(p, (int)n, sys_stdin)) {
 
117
    case 0: /* Normal case */
 
118
        break;
 
119
    case 1: /* Interrupt */
 
120
        PyMem_FREE(p);
 
121
        return NULL;
 
122
    case -1: /* EOF */
 
123
    case -2: /* Error */
 
124
    default: /* Shouldn't happen */
 
125
        *p = '\0';
 
126
        break;
 
127
    }
 
128
    n = strlen(p);
 
129
    while (n > 0 && p[n-1] != '\n') {
 
130
        size_t incr = n+2;
 
131
        p = (char *)PyMem_REALLOC(p, n + incr);
 
132
        if (p == NULL)
 
133
            return NULL;
 
134
        if (incr > INT_MAX) {
 
135
            PyErr_SetString(PyExc_OverflowError, "input line too long");
 
136
        }
 
137
        if (my_fgets(p+n, (int)incr, sys_stdin) != 0)
 
138
            break;
 
139
        n += strlen(p+n);
 
140
    }
 
141
    return (char *)PyMem_REALLOC(p, n+1);
142
142
}
143
143
 
144
144
 
155
155
char *
156
156
PyOS_Readline(FILE *sys_stdin, FILE *sys_stdout, char *prompt)
157
157
{
158
 
        char *rv;
159
 
 
160
 
        if (_PyOS_ReadlineTState == PyThreadState_GET()) {
161
 
                PyErr_SetString(PyExc_RuntimeError,
162
 
                                "can't re-enter readline");
163
 
                return NULL;
164
 
        }
165
 
        
166
 
 
167
 
        if (PyOS_ReadlineFunctionPointer == NULL) {
 
158
    char *rv;
 
159
 
 
160
    if (_PyOS_ReadlineTState == PyThreadState_GET()) {
 
161
        PyErr_SetString(PyExc_RuntimeError,
 
162
                        "can't re-enter readline");
 
163
        return NULL;
 
164
    }
 
165
 
 
166
 
 
167
    if (PyOS_ReadlineFunctionPointer == NULL) {
168
168
#ifdef __VMS
169
 
                PyOS_ReadlineFunctionPointer = vms__StdioReadline;
 
169
        PyOS_ReadlineFunctionPointer = vms__StdioReadline;
170
170
#else
171
 
                PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
172
 
#endif
173
 
        }
174
 
        
175
 
#ifdef WITH_THREAD
176
 
        if (_PyOS_ReadlineLock == NULL) {
177
 
                _PyOS_ReadlineLock = PyThread_allocate_lock();          
178
 
        }
179
 
#endif
180
 
 
181
 
        _PyOS_ReadlineTState = PyThreadState_GET();
182
 
        Py_BEGIN_ALLOW_THREADS
183
 
#ifdef WITH_THREAD
184
 
        PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
185
 
#endif
186
 
 
187
 
        /* This is needed to handle the unlikely case that the
188
 
         * interpreter is in interactive mode *and* stdin/out are not
189
 
         * a tty.  This can happen, for example if python is run like
190
 
         * this: python -i < test1.py
191
 
         */
192
 
        if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))
193
 
                rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);
194
 
        else
195
 
                rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
196
 
                                                     prompt);
197
 
        Py_END_ALLOW_THREADS
198
 
 
199
 
#ifdef WITH_THREAD
200
 
        PyThread_release_lock(_PyOS_ReadlineLock);
201
 
#endif
202
 
 
203
 
        _PyOS_ReadlineTState = NULL;
204
 
 
205
 
        return rv;
 
171
        PyOS_ReadlineFunctionPointer = PyOS_StdioReadline;
 
172
#endif
 
173
    }
 
174
 
 
175
#ifdef WITH_THREAD
 
176
    if (_PyOS_ReadlineLock == NULL) {
 
177
        _PyOS_ReadlineLock = PyThread_allocate_lock();
 
178
    }
 
179
#endif
 
180
 
 
181
    _PyOS_ReadlineTState = PyThreadState_GET();
 
182
    Py_BEGIN_ALLOW_THREADS
 
183
#ifdef WITH_THREAD
 
184
    PyThread_acquire_lock(_PyOS_ReadlineLock, 1);
 
185
#endif
 
186
 
 
187
    /* This is needed to handle the unlikely case that the
 
188
     * interpreter is in interactive mode *and* stdin/out are not
 
189
     * a tty.  This can happen, for example if python is run like
 
190
     * this: python -i < test1.py
 
191
     */
 
192
    if (!isatty (fileno (sys_stdin)) || !isatty (fileno (sys_stdout)))
 
193
        rv = PyOS_StdioReadline (sys_stdin, sys_stdout, prompt);
 
194
    else
 
195
        rv = (*PyOS_ReadlineFunctionPointer)(sys_stdin, sys_stdout,
 
196
                                             prompt);
 
197
    Py_END_ALLOW_THREADS
 
198
 
 
199
#ifdef WITH_THREAD
 
200
    PyThread_release_lock(_PyOS_ReadlineLock);
 
201
#endif
 
202
 
 
203
    _PyOS_ReadlineTState = NULL;
 
204
 
 
205
    return rv;
206
206
}