aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRaimo Niskanen <[email protected]>2015-11-25 11:43:20 +0100
committerRaimo Niskanen <[email protected]>2015-11-26 11:04:50 +0100
commit5c6ddf14e8264e61225c0bb5cdc79d537f58be3f (patch)
tree3a58452aedc5e98e73e75cff33defee13e4cb98c
parent6b5ea6ecb4eed204496cf196d98e7453df02c6dd (diff)
downloadotp-5c6ddf14e8264e61225c0bb5cdc79d537f58be3f.tar.gz
otp-5c6ddf14e8264e61225c0bb5cdc79d537f58be3f.tar.bz2
otp-5c6ddf14e8264e61225c0bb5cdc79d537f58be3f.zip
Fix file:pread and :pwrite to use character encoding
-rw-r--r--lib/kernel/src/file_io_server.erl46
-rw-r--r--lib/kernel/test/file_SUITE.erl37
2 files changed, 75 insertions, 8 deletions
diff --git a/lib/kernel/src/file_io_server.erl b/lib/kernel/src/file_io_server.erl
index 5b2cae6b02..9c425d2175 100644
--- a/lib/kernel/src/file_io_server.erl
+++ b/lib/kernel/src/file_io_server.erl
@@ -214,26 +214,58 @@ file_request({allocate, Offset, Length},
#state{handle = Handle} = State) ->
Reply = ?PRIM_FILE:allocate(Handle, Offset, Length),
{reply, Reply, State};
+file_request({pread,At,Sz}, State)
+ when At =:= cur;
+ At =:= {cur,0} ->
+ case get_chars(Sz, latin1, State) of
+ {reply,Reply,NewState}
+ when is_list(Reply);
+ is_binary(Reply) ->
+ {reply,{ok,Reply},NewState};
+ {stop,_,Reply,NewState} ->
+ {error,Reply,NewState};
+ Other ->
+ Other
+ end;
file_request({pread,At,Sz},
- #state{handle=Handle,buf=Buf,read_mode=ReadMode}=State) ->
+ #state{handle=Handle,buf=Buf}=State) ->
case position(Handle, At, Buf) of
{error,_} = Reply ->
{error,Reply,State};
_ ->
- case ?PRIM_FILE:read(Handle, Sz) of
- {ok,Bin} when ReadMode =:= list ->
- std_reply({ok,binary_to_list(Bin)}, State);
- Reply ->
- std_reply(Reply, State)
+ case get_chars(Sz, latin1, State#state{buf= <<>>}) of
+ {reply,Reply,NewState}
+ when is_list(Reply);
+ is_binary(Reply) ->
+ {reply,{ok,Reply},NewState};
+ {stop,_,Reply,NewState} ->
+ {error,Reply,NewState};
+ Other ->
+ Other
end
end;
+file_request({pwrite,At,Data},
+ #state{buf= <<>>}=State)
+ when At =:= cur;
+ At =:= {cur,0} ->
+ case put_chars(Data, latin1, State) of
+ {stop,_,Reply,NewState} ->
+ {error,Reply,NewState};
+ Other ->
+ Other
+ end;
file_request({pwrite,At,Data},
#state{handle=Handle,buf=Buf}=State) ->
case position(Handle, At, Buf) of
{error,_} = Reply ->
{error,Reply,State};
_ ->
- std_reply(?PRIM_FILE:write(Handle, Data), State)
+ case put_chars(Data, latin1, State) of
+ {stop,_,Reply,NewState} ->
+ {error,Reply,NewState};
+ Other ->
+ Other
+ end
end;
file_request(datasync,
#state{handle=Handle}=State) ->
diff --git a/lib/kernel/test/file_SUITE.erl b/lib/kernel/test/file_SUITE.erl
index e9300bf019..87d2de4cae 100644
--- a/lib/kernel/test/file_SUITE.erl
+++ b/lib/kernel/test/file_SUITE.erl
@@ -79,6 +79,7 @@
-export([interleaved_read_write/1]).
+-export([unicode/1]).
-export([altname/1]).
-export([large_file/1, large_write/1]).
@@ -110,7 +111,7 @@
suite() -> [{ct_hooks,[ts_install_cth]}].
all() ->
- [altname, read_write_file, {group, dirs},
+ [unicode, altname, read_write_file, {group, dirs},
{group, files}, delete, rename, names, {group, errors},
{group, compression}, {group, links}, copy,
delayed_write, read_ahead, segment_read, segment_write,
@@ -2631,6 +2632,40 @@ compress_async_crash_loop(N, Path, ExpectedData) ->
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+unicode(Config) when is_list(Config) ->
+ Dir = ?config(priv_dir, Config),
+ Name = filename:join(Dir, "data-utf8.txt"),
+ Txt = lists:seq(128, 255),
+ D = unicode:characters_to_binary(Txt, latin1, latin1),
+ {ok,Fd1} =
+ ?FILE_MODULE:open(Name, [write,read,binary,{encoding,unicode}]),
+ ok = ?FILE_MODULE:truncate(Fd1),
+ ok = ?FILE_MODULE:write(Fd1, Txt),
+ {ok,0} = ?FILE_MODULE:position(Fd1, bof),
+ {ok,D} = ?FILE_MODULE:read(Fd1, 129),
+ {ok,0} = ?FILE_MODULE:position(Fd1, bof),
+ {ok,D1} = ?FILE_MODULE:read(Fd1, 64),
+ {ok,Pos} = ?FILE_MODULE:position(Fd1, cur),
+ {ok,D2} = ?FILE_MODULE:pread(Fd1, {cur,0}, 65),
+ D = <<D1/binary, D2/binary>>,
+ {ok,D1} = ?FILE_MODULE:pread(Fd1, bof, 64),
+ {ok,Pos} = ?FILE_MODULE:position(Fd1, Pos),
+ {ok,D2} = ?FILE_MODULE:read(Fd1, 64),
+ ok = ?FILE_MODULE:close(Fd1),
+ %%
+ RawD = unicode:characters_to_binary(Txt, latin1, unicode),
+ {ok,RawD} = ?FILE_MODULE:read_file(Name),
+ %%
+ {ok,Fd2} = ?FILE_MODULE:open(Name, [read,{encoding,unicode}]),
+ {ok,Txt} = ?FILE_MODULE:read(Fd2, 129),
+ {Txt1,Txt2} = lists:split(64, Txt),
+ {ok,Txt2} = ?FILE_MODULE:pread(Fd2, Pos, 65),
+ {ok,0} = ?FILE_MODULE:position(Fd2, bof),
+ {ok,Txt1} = ?FILE_MODULE:read(Fd2, 64),
+ ok = ?FILE_MODULE:close(Fd2).
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
altname(doc) ->
"Test the file:altname/1 function";
altname(suite) ->