@@ -134,22 +134,22 @@ open(Name, Modes) ->
134134 % % the public file interface, which has leaked through for ages because of
135135 % % "raw files."
136136 try open_nif (encode_path (Name ), Modes ) of
137- {ok , Ref } -> {ok , make_fd (Ref , Modes )};
137+ {ok , Ref } -> {ok , make_fd (Modes , Ref )};
138138 {error , Reason } -> {error , Reason }
139139 catch
140140 error :badarg -> {error , badarg }
141141 end .
142142
143143file_desc_to_ref (FileDescriptorId , Modes ) ->
144144 try file_desc_to_ref_nif (FileDescriptorId ) of
145- {ok , Ref } -> {ok , make_fd (Ref , Modes )};
145+ {ok , Ref } -> {ok , make_fd (Modes , Ref )};
146146 {error , Reason } -> {error , Reason }
147147 catch
148148 error :badarg -> {error , badarg }
149149 end .
150150
151- make_fd (FRef , Modes ) ->
152- # file_descriptor {module = ? MODULE , data = build_fd_data (FRef , Modes ) }.
151+ make_fd (Modes , FRef ) ->
152+ # file_descriptor {module = ? MODULE , data = build_fd_data (Modes , FRef ) }.
153153
154154close (Fd ) ->
155155 try
@@ -163,9 +163,10 @@ read(Fd, Size) ->
163163 try
164164 #{ handle := FRef ,
165165 r_ahead_size := RASz ,
166- r_buffer := RBuf } = get_fd_data (Fd ),
166+ r_buffer := RBuf } = get_fd_data_for_read (Fd ),
167167 read_1 (FRef , RBuf , prim_buffer :size (RBuf ), RASz , Size )
168168 catch
169+ throw :Err -> Err ;
169170 error :badarg -> {error , badarg }
170171 end .
171172
@@ -206,11 +207,12 @@ read_line(Fd) ->
206207 try
207208 #{ handle := FRef ,
208209 r_ahead_size := RASz ,
209- r_buffer := RBuf } = get_fd_data (Fd ),
210+ r_buffer := RBuf } = get_fd_data_for_read (Fd ),
210211 SearchResult = prim_buffer :find_byte_index (RBuf , $\n ),
211212 LineSize = max (? MIN_READLINE_SIZE , RASz ),
212213 read_line_1 (FRef , RBuf , SearchResult , LineSize )
213214 catch
215+ throw :Err -> Err ;
214216 error :badarg -> {error , badarg }
215217 end .
216218
@@ -304,8 +306,10 @@ datasync(Fd) ->
304306position (Fd , {cur , Offset }) ->
305307 try
306308 % % Adjust our current position according to how much we've read ahead.
307- #{ r_buffer := RBuf } = get_fd_data (Fd ),
308- position_1 (Fd , cur , Offset - prim_buffer :size (RBuf ))
309+ case get_fd_data (Fd ) of
310+ #{ r_buffer := RBuf } -> position_1 (Fd , cur , Offset - prim_buffer :size (RBuf ));
311+ #{} -> position_1 (Fd , cur , Offset )
312+ end
309313 catch
310314 error :badarg -> {error , badarg }
311315 end ;
@@ -321,9 +325,13 @@ position(Fd, eof) -> position(Fd, {eof, 0});
321325position (Fd , Offset ) -> position (Fd , {bof , Offset }).
322326
323327position_1 (Fd , Mark , Offset ) ->
324- #{ handle := FRef , r_buffer := RBuf } = get_fd_data (Fd ),
325- prim_buffer :wipe (RBuf ),
326- seek_nif (FRef , Mark , Offset ).
328+ case get_fd_data (Fd ) of
329+ #{ handle := FRef , r_buffer := RBuf } ->
330+ prim_buffer :wipe (RBuf ),
331+ seek_nif (FRef , Mark , Offset );
332+ #{ handle := FRef } ->
333+ seek_nif (FRef , Mark , Offset )
334+ end .
327335
328336pread (Fd , Offset , Size ) ->
329337 try
@@ -361,9 +369,14 @@ pread_list(FRef, [{Offset, Size} | Rest], ResultList) ->
361369
362370pwrite (Fd , Offset , IOData ) ->
363371 try
364- #{ handle := FRef , r_buffer := RBuf } = get_fd_data (Fd ),
365- prim_buffer :wipe (RBuf ),
366- pwrite_plain (FRef , Offset , erlang :iolist_to_iovec (IOData ))
372+ IOVec = erlang :iolist_to_iovec (IOData ),
373+ case get_fd_data (Fd ) of
374+ #{ handle := FRef , r_buffer := RBuf } ->
375+ prim_buffer :wipe (RBuf ),
376+ pwrite_plain (FRef , Offset , IOVec );
377+ #{ handle := FRef } ->
378+ pwrite_plain (FRef , Offset , IOVec )
379+ end
367380 catch
368381 error :badarg -> {error , badarg }
369382 end .
@@ -379,9 +392,13 @@ pwrite_plain(FRef, Offset, IOVec) ->
379392
380393pwrite (Fd , LocBytes ) ->
381394 try
382- #{ handle := FRef , r_buffer := RBuf } = get_fd_data (Fd ),
383- prim_buffer :wipe (RBuf ),
384- pwrite_list (FRef , LocBytes , 0 )
395+ case get_fd_data (Fd ) of
396+ #{ handle := FRef , r_buffer := RBuf } ->
397+ prim_buffer :wipe (RBuf ),
398+ pwrite_list (FRef , LocBytes , 0 );
399+ #{ handle := FRef } ->
400+ pwrite_list (FRef , LocBytes , 0 )
401+ end
385402 catch
386403 error :badarg -> {error , badarg }
387404 end .
@@ -470,10 +487,13 @@ get_handle(Fd) ->
470487% % Resets the write head to the position the user believes we're at, which may
471488% % not be the same as the real one when read caching is in effect.
472489reset_write_position (Fd ) ->
473- #{ r_buffer := RBuf } = Fd # file_descriptor .data ,
474- case prim_buffer :size (RBuf ) of
475- Size when Size > 0 -> position (Fd , cur );
476- Size when Size =:= 0 -> ok
490+ case Fd # file_descriptor .data of
491+ #{ r_buffer := RBuf } ->
492+ case prim_buffer :size (RBuf ) of
493+ Size when Size > 0 -> position (Fd , cur );
494+ Size when Size =:= 0 -> ok
495+ end ;
496+ _ -> ok
477497 end .
478498
479499get_fd_data (# file_descriptor { data = Data }) ->
@@ -483,24 +503,28 @@ get_fd_data(#file_descriptor{ data = Data }) ->
483503 _ -> error (not_on_controlling_process )
484504 end .
485505
486- build_fd_data (FRef , Modes ) ->
487- Defaults =
488- #{ owner => self (),
489- handle => FRef ,
490- r_ahead_size => 0 ,
491- r_buffer => prim_buffer :new () },
492- fill_fd_option_map (Modes , Defaults ).
493-
494- fill_fd_option_map ([], Map ) ->
495- Map ;
496-
497- fill_fd_option_map ([read_ahead | Modes ], Map ) ->
498- fill_fd_option_map ([{read_ahead , 64 bsl 10 } | Modes ], Map );
499- fill_fd_option_map ([{read_ahead , Size } | Modes ], Map ) ->
500- fill_fd_option_map (Modes , Map #{ r_ahead_size => Size });
501-
502- fill_fd_option_map ([_Ignored | Modes ], Map ) ->
503- fill_fd_option_map (Modes , Map ).
506+ get_fd_data_for_read (Fd ) ->
507+ case get_fd_data (Fd ) of
508+ #{ r_buffer := _ } = Data -> Data ;
509+ _ -> throw ({error , ebadf })
510+ end .
511+
512+ build_fd_data (Modes , FRef ) -> build_fd_data (Modes , FRef , self (), 0 , default ).
513+
514+ build_fd_data ([], FRef , Owner , _RASz , write ) ->
515+ #{ handle => FRef , owner => Owner };
516+ build_fd_data ([], FRef , Owner , RASz , Mode ) when Mode =:= read ; Mode =:= default ->
517+ #{ handle => FRef , owner => Owner , r_ahead_size => RASz , r_buffer => prim_buffer :new () };
518+ build_fd_data ([read_ahead | Modes ], FRef , Owner , _ , Mode ) ->
519+ build_fd_data (Modes , FRef , Owner , 64 bsl 10 , Mode );
520+ build_fd_data ([{read_ahead , RASz } | Modes ], FRef , Owner , _ , Mode ) ->
521+ build_fd_data (Modes , FRef , Owner , RASz , Mode );
522+ build_fd_data ([write | Modes ], FRef , Owner , RASz , default ) ->
523+ build_fd_data (Modes , FRef , Owner , RASz , write );
524+ build_fd_data ([read | Modes ], FRef , Owner , RASz , _Mode ) ->
525+ build_fd_data (Modes , FRef , Owner , RASz , read );
526+ build_fd_data ([_Ignored | Modes ], FRef , Owner , RASz , Mode ) ->
527+ build_fd_data (Modes , FRef , Owner , RASz , Mode ).
504528
505529open_nif (_Name , _Modes ) ->
506530 erlang :nif_error (undef ).
0 commit comments