Linux API Calls to implement rm, mv, and cp [closed]

丶灬走出姿态 提交于 2021-01-20 12:00:53

问题


I'm writing my own little shell in C, or at least I'm going to start today. I want to implement three functions.

  • remove file1

What system calls would I need for this? Just open file and delete its contents or is there a system call to delete a file besides using rm?

  • mycopy source destination

For this I was thinking of having a buffer and open file1 read into buffer and write out to file2 but I don't know how to actually put this into code if anyone can throw together a little example that would help a bunch.

  • move source destination

Would this just implement copy and remove?

My main problem is using the argv[] parameters I've never done that so its new to me.


回答1:


You can use strace to see what system calls the linux coreutils use. The system calls have man pages as well, which you can look up (e.g. man unlink).

For example...

jason@io /tmp $ strace rm foo
execve("/bin/rm", ["rm", "foo"], [/* 66 vars */]) = 0
brk(0)                                  = 0x20dd000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2a46c76000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=135313, ...}) = 0
mmap(NULL, 135313, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2a46c54000
close(3)                                = 0
open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3
read(3, "\177ELF\2\1\1\3\0\0\0\0\0\0\0\0\3\0>\0\1\0\0\0\300\370\1\0\0\0\0\0"..., 832) = 832
fstat(3, {st_mode=S_IFREG|0755, st_size=1677176, ...}) = 0
mmap(NULL, 3784472, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0x7f2a466ba000
mprotect(0x7f2a4684d000, 2093056, PROT_NONE) = 0
mmap(0x7f2a46a4c000, 24576, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x192000) = 0x7f2a46a4c000
mmap(0x7f2a46a52000, 16152, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0x7f2a46a52000
close(3)                                = 0
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2a46c53000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2a46c52000
mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0x7f2a46c51000
arch_prctl(ARCH_SET_FS, 0x7f2a46c52700) = 0
mprotect(0x7f2a46a4c000, 16384, PROT_READ) = 0
mprotect(0x7f2a46c77000, 4096, PROT_READ) = 0
munmap(0x7f2a46c54000, 135313)          = 0
brk(0)                                  = 0x20dd000
brk(0x20fe000)                          = 0x20fe000
open("/usr/lib64/locale/locale-archive", O_RDONLY|O_CLOEXEC) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=1607712, ...}) = 0
mmap(NULL, 1607712, PROT_READ, MAP_PRIVATE, 3, 0) = 0x7f2a46ac8000
close(3)                                = 0
ioctl(0, TCGETS, {B38400 opost isig icanon echo ...}) = 0
newfstatat(AT_FDCWD, "foo", {st_mode=S_IFREG|0644, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
geteuid()                               = 1000
newfstatat(AT_FDCWD, "foo", {st_mode=S_IFREG|0644, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
faccessat(AT_FDCWD, "foo", W_OK)        = 0
unlinkat(AT_FDCWD, "foo", 0)            = 0
lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)
close(0)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
+++ exited with 0 +++



回答2:


I'm writing my own little shell in C, or at least I'm going to start today.

If you're writing a shell, you don't need to implement these functions; they already exist as the coreutils executables rm, cp, and mv. These are not typically part of a shell, and don't need to be.

Regardless!

./remove file1 What system calls would I need for this? Just open file and delete its contents or is there a system call to delete a file besides using rm?

unlink().

./mycopy source destination For this I was thinking of having a buffer and open file1 read into buffer and write out to file2 but I don't know how to actually put this into code if anyone can throw together a little example that would help a bunch.

Correct. There's no "single-step" call for this; just open() (twice), read(), and write().

And then ./move would just implement copy and remove pretty much right ?

No! That'd be really slow for large files, and wouldn't work at all for directories. The system call you want is rename().

(However, note that rename() doesn't work across file systems. In that case, you do need to copy and remove files… possibly even recursively, if you're moving a directory.)



来源:https://stackoverflow.com/questions/33763569/linux-api-calls-to-implement-rm-mv-and-cp

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!