@@ -183,7 +183,7 @@ public void CloseStreams(PythonFileManager? manager) {
183
183
/// </summary>
184
184
/// <remarks>
185
185
/// PythonFileManager emulates a file descriptor table. On Windows, .NET uses Win32 API which uses file handles
186
- /// rather than file descriptors. The emulation is necesary to support Python API, which in some places uses file descriptors.
186
+ /// rather than file descriptors. The emulation is necessary to support Python API, which in some places uses file descriptors.
187
187
///
188
188
/// The manager maintains a mapping between open files (or system file-like objects) and a "descriptor", being a small non-negative integer.
189
189
/// Unlike in CPython, the descriptors are allocated lazily, meaning they are allocated only when they become exposed (requested)
@@ -198,7 +198,7 @@ public void CloseStreams(PythonFileManager? manager) {
198
198
/// In such situations, only one of the FileIO may be opened with flag `closefd` (CPython rule).
199
199
///
200
200
/// The second lever of sharing of open files is below the file descriptor level. A file descriptor can be duplicated using dup/dup2,
201
- /// but the duplicated descriptor is still refering to the same open file in the filesystem. In such case, the manager maintains
201
+ /// but the duplicated descriptor is still referring to the same open file in the filesystem. In such case, the manager maintains
202
202
/// a separate StreamBox for the duplicated descriptor, but the StreamBoxes for both descriptors share the underlying Streams.
203
203
/// Both such descriptors have to be closed independently by the user code (either explicitly by os.close(fd) or through close()
204
204
/// on the FileIO objects), but the underlying shared streams are closed only when all such duplicated descriptors are closed.
@@ -211,21 +211,39 @@ internal class PythonFileManager {
211
211
/// </summary>
212
212
public const int LIMIT_OFILE = 0x100000 ; // hard limit on Linux
213
213
214
+
215
+ // Values of the Errno codes below have to be identical with values defined in PythonErrorNumber
216
+
217
+ #region Generated Common Errno Codes
218
+
219
+ // *** BEGIN GENERATED CODE ***
220
+ // generated by function: generate_common_errno_codes from: generate_os_codes.py
221
+
222
+ internal const int ENOENT = 2 ;
223
+ internal const int EBADF = 9 ;
224
+ internal const int EACCES = 13 ;
225
+ internal const int EMFILE = 24 ;
226
+
227
+ // *** END GENERATED CODE ***
228
+
229
+ #endregion
230
+
231
+
214
232
private readonly object _synchObject = new ( ) ;
215
233
private readonly Dictionary < int , StreamBox > _table = new ( ) ;
216
234
private const int _offset = 3 ; // number of lowest keys that are not automatically allocated
217
235
private int _current = _offset ; // lowest potentially unused key in _objects at or above _offset
218
236
private readonly ConcurrentDictionary < Stream , int > _refs = new ( ) ;
219
237
220
238
// This version of Add is used with genuine file descriptors (Unix).
221
- // Exception: support dup2 on all frameworks/platfroms .
239
+ // Exception: support dup2 on all frameworks/platforms .
222
240
public int Add ( int id , StreamBox streams ) {
223
241
ContractUtils . RequiresNotNull ( streams , nameof ( streams ) ) ;
224
242
ContractUtils . Requires ( streams . Id < 0 , nameof ( streams ) ) ;
225
243
ContractUtils . Requires ( id >= 0 , nameof ( id ) ) ;
226
244
lock ( _synchObject ) {
227
245
if ( _table . ContainsKey ( id ) ) {
228
- throw PythonOps . OSError ( 9 , "Bad file descriptor" , id . ToString ( ) ) ;
246
+ throw PythonOps . OSError ( EBADF , "Bad file descriptor" , id . ToString ( ) ) ;
229
247
}
230
248
streams . Id = id ;
231
249
_table . Add ( id , streams ) ;
@@ -243,7 +261,7 @@ public int Add(StreamBox streams) {
243
261
while ( _table . ContainsKey ( _current ) ) {
244
262
_current ++ ;
245
263
if ( _current >= LIMIT_OFILE )
246
- throw PythonOps . OSError ( 24 , "Too many open files" ) ;
264
+ throw PythonOps . OSError ( EMFILE , "Too many open files" ) ;
247
265
}
248
266
streams . Id = _current ;
249
267
_table . Add ( _current , streams ) ;
@@ -280,7 +298,7 @@ public StreamBox GetStreams(int id) {
280
298
if ( TryGetStreams ( id , out StreamBox ? streams ) ) {
281
299
return streams ;
282
300
}
283
- throw PythonOps . OSError ( 9 , "Bad file descriptor" ) ;
301
+ throw PythonOps . OSError ( EBADF , "Bad file descriptor" ) ;
284
302
}
285
303
286
304
public int GetOrAssignId ( StreamBox streams ) {
0 commit comments