Skip to content

Commit

Permalink
Merge commit 'b90d14224227d388377b708ce715ce41cf2aeed2'
Browse files Browse the repository at this point in the history
  • Loading branch information
StefanKarpinski committed Nov 19, 2013
2 parents be9421e + b90d142 commit e54ff95
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 2 deletions.
4 changes: 2 additions & 2 deletions base/file.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ end
# The following use Unix command line facilites

rm(path::String) = FS.unlink(path)
cp(src::String, dst::String) = run(`cp $src $dst`)
mv(src::String, dst::String) = run(`mv $src $dst`)
cp(src::String, dst::String) = FS.sendfile(src, dst)
mv(src::String, dst::String) = FS.rename(src, dst)
touch(path::String) = run(`touch $path`)

# Obtain a temporary filename.
Expand Down
47 changes: 47 additions & 0 deletions base/fs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export File,
# close,
write,
unlink,
rename,
sendfile,
JL_O_WRONLY,
JL_O_RDONLY,
JL_O_RDWR,
Expand Down Expand Up @@ -102,6 +104,51 @@ function unlink(f::File)
f
end

# For move command
function rename(src::String, dst::String)
err = ccall(:jl_fs_rename, Int32, (Ptr{Uint8}, Ptr{Uint8}), bytestring(src),
bytestring(dst))

# on error, default to cp && rm
if err < 0
# first copy
err = sendfile(src, dst)
uv_error("sendfile when moving file", err)

# then rm
err = unlink(src)
uv_error("removing when moving file", err)
end
end

# For copy command
function sendfile(src::String, dst::String)
flags = JL_O_RDONLY
src_file = open(src, flags)
if !src_file.open
error("Src file is not open")
end

flags = JL_O_CREAT | JL_O_RDWR
mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP| S_IROTH | S_IWOTH
dst_file = open(dst, flags, mode)
if !dst_file.open
error("Dst file is not open")
end

src_stat = stat(src_file)
err = ccall(:jl_fs_sendfile, Int32, (Int32, Int32, Int64, Csize_t),
fd(src_file), fd(dst_file), 0, src_stat.size)
uv_error("sendfile", err)

if src_file.open
close(src_file)
end
if dst_file.open
close(dst_file)
end
end

function write(f::File, buf::Ptr{Uint8}, len::Integer, offset::Integer=-1)
if !f.open
error("file is not open")
Expand Down
18 changes: 18 additions & 0 deletions src/jl_uv.c
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,24 @@ DLLEXPORT int jl_fs_unlink(char *path)
return ret;
}

DLLEXPORT int jl_fs_rename(char *src_path, char *dst_path)
{
uv_fs_t req;
int ret = uv_fs_rename(jl_io_loop, &req, src_path, dst_path, NULL);
uv_fs_req_cleanup(&req);
return ret;
}

DLLEXPORT int jl_fs_sendfile(int src_fd, int dst_fd,
int64_t in_offset, size_t len)
{
uv_fs_t req;
int ret = uv_fs_sendfile(jl_io_loop, &req, dst_fd, src_fd,
in_offset, len, NULL);
uv_fs_req_cleanup(&req);
return ret;
}

DLLEXPORT int jl_fs_write(int handle, char *buf, size_t len, size_t offset)
{
uv_fs_t req;
Expand Down
2 changes: 2 additions & 0 deletions src/julia.expmap
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,8 @@
jl_fs_poll_start;
jl_fs_event_init;
jl_fs_unlink;
jl_fs_rename;
jl_fs_sendfile;
jl_fs_write;
jl_fs_write_byte;
jl_fs_read;
Expand Down
36 changes: 36 additions & 0 deletions test/file.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,24 @@ mv(file, newfile)
@test isfile(newfile) == true
file = newfile

# Test renaming directories
a_tmpdir = mktempdir()
b_tmpdir = joinpath(dir, "b_tmpdir")

# grab a_tmpdir's file info before renaming
a_stat = stat(a_tmpdir)

# rename, then make sure b_tmpdir does exist and a_tmpdir doesn't
mv(a_tmpdir, b_tmpdir)
@test isdir(b_tmpdir) == true
@test isdir(a_tmpdir) == false

# get b_tmpdir's file info and compare with a_tmpdir
b_stat = stat(b_tmpdir)
@test Base.samefile(a_stat, b_stat) == true

rmdir(b_tmpdir)

#######################################################################
# This section tests file watchers. #
#######################################################################
Expand Down Expand Up @@ -184,6 +202,24 @@ emptyf = open(emptyfile)
close(emptyf)
rm(emptyfile)

# Test copy file
afile = joinpath(dir, "a.txt")
touch(afile)
af = open(afile, "r+")
write(af, "This is indeed a test")

bfile = joinpath(dir, "b.txt")
cp(afile, bfile)

a_stat = stat(afile)
b_stat = stat(bfile)
@test a_stat.mode == b_stat.mode
@test a_stat.size == b_stat.size

close(af)
rm(afile)
rm(bfile)

############
# Clean up #
############
Expand Down

0 comments on commit e54ff95

Please sign in to comment.