#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
int main(int argc, char *argv[])
{
int fd1, fd2;
int n;
char buf[BUFSIZ];
fd1 = open(argv[1], O_RDONLY);
fd2 = open(argv[2], O_WRONLY | O_CREAT, 0644);
while ((n = read(fd1, buf, BUFSIZ)) > 0)
write(fd2, buf, n);
close(fd1);
close(fd2);
return 0;
}
2) ์ด ์ฝ๋๊ฐ ํ๋ ์ผ (๋์ ์ค๋ช )
- open(argv[1], O_RDONLY)
→ ์ฒซ ๋ฒ์งธ ์ธ์๋ก ๋ฐ์ ์ ๋ ฅ ํ์ผ์ ์ฝ๊ธฐ ์ ์ฉ์ผ๋ก ์ฐ๋ค. - open(argv[2], O_WRONLY | O_CREAT, 0644)
→ ๋ ๋ฒ์งธ ์ธ์๋ก ๋ฐ์ ์ถ๋ ฅ ํ์ผ์ ์ฐ๊ธฐ ์ ์ฉ์ผ๋ก ์ฐ๋ค. ์์ผ๋ฉด 0644 ๊ถํ์ผ๋ก ์๋ก ๋ง๋ ๋ค. (์ด๋ฏธ ์์ผ๋ฉด “์ด๊ธฐ๋ง” ํ๊ณ ์๋ฅด์ง ์์) - read → write ๋ฃจํ
→ ์ ๋ ฅ ํ์ผ์์ ์ต๋ BUFSIZ(stdio๊ฐ ์ ํด๋ ์ ๋นํ ํฌ๊ธฐ)๋งํผ ์ฝ์ด์, ์ฝํ ๋ฐ์ดํธ ์ n๋งํผ ์ถ๋ ฅ ํ์ผ์ ์ด๋ค. 0์ด ๋์ค๋ฉด EOF๋ผ ๋ณต์ฌ ์ข ๋ฃ. - close
→ ๋ ํ์ผ ๋์คํฌ๋ฆฝํฐ๋ฅผ ๋ซ๊ณ ์ข ๋ฃ.
๊ฒฐ๋ก ์ ์ผ๋ก ๊ฐ๋จํ ํ์ผ ๋ณต์ฌ ํ๋ก๊ทธ๋จ์ด์ผ.
3) ์๋ณธ ์ฝ๋์ ๋ฌธ์ /์ฃผ์์
- ์๋ฌ ์ฒดํฌ๊ฐ ์์
- argc ํ์ธ์ด ์์ด ์ธ์ ๊ฐ์๊ฐ ๋ถ์กฑํด๋ ๊ทธ๋๋ก ์ ๊ทผ(์ธ๊ทธํดํธ ์ํ).
- open/read/write/close ๋ฐํ๊ฐ์ ํ์ธํ์ง ์์ → ํ์ผ์ ๋ชป ์ด๊ฑฐ๋, ์ฝ๊ธฐ/์ฐ๊ธฐ ์ค ์ค๋ฅ๊ฐ ๋๋ ๋ชจ๋ฆ.
- ๋ถ๋ถ ์ฐ๊ธฐ(partial write) ๋ฏธ์ฒ๋ฆฌ
- write๋ ์์ฒญํ ๋ฐ์ดํธ ์ ๋ถ๋ฅผ ํญ์ ์ฐ๋ ๊ฒ ์๋. ์ ํธ(EINTR)๋ ๊ธฐํ ์ด์ ๋ก ์ผ๋ถ๋ง ์ธ ์ ์์ด. ๊ทธ๋ผ ๋จ์ ๋งํผ์ ๋ค์ ์จ์ผ ํจ.
- ๋์ ํ์ผ์ ์๋ฅด์ง ์์(O_TRUNC ๋๋ฝ)
- fd2๋ฅผ ์ด ๋ O_TRUNC๊ฐ ์์ด์ ์ด๋ฏธ ์กด์ฌํ๋ ํ์ผ์ด ๋ ๊ธธ์๋ค๋ฉด ์๋ถ๋ถ๋ง ์ ๋ฐ์ดํฐ๋ก ๋ฎ์ด๊ณ ๋ท๋ถ๋ถ์ ์ด์ ๋ด์ฉ์ด ๋จ๋๋ค.
- “์ ํํ ๊ฐ์ ๋ด์ฉ์ผ๋ก ๋ณต์ฌ”ํ๋ ค๋ฉด O_TRUNC๋ฅผ ๋ฃ๋ ๊ฒ ์์ .
- ๋์ผ ํ์ผ ์์ฒด ๋ณต์ฌ ๋ฐฉ์ง ์์
- argv[1]์ argv[2]๊ฐ ๊ฐ์ ํ์ผ(๊ฐ์ device+inode)์ด๋ฉด, ์ด๊ณ ์ฐ๋ ์๊ฐ ์๋ณธ์ ์ค์ค๋ก ๋ฎ์ด๋ฒ๋ฆฌ๋ ํฉ๋นํ ์ํฉ ๋ฐ์ ๊ฐ๋ฅ. fstat๋ก ๋์ผ์ฑ ์ฒดํฌ๊ฐ ์ข์.
- ๊ถํ/umask ์ดํด ํ์
- 0644๋ “์์ฒญ ๊ถํ”; ์ค์ ์์ฑ ๊ถํ์ umask์ ์ํด ๋ ์ ํ๋ ์ ์์.
4) ๊ฐ์ ๋ฒ์ : ์๋ฌ ์ฒ๋ฆฌ + ์์ ์ฅ์น ํฌํจ
์๋๋ ์ค๋ฌด์ ์ผ๋ก ์์ ํ๊ฒ ๋ค๋ฌ์ ๋ฒ์ ์ด์ผ.
- ์ธ์ ํ์ธ
- open ์๋ฌ ์ฒ๋ฆฌ
- ๋์ ํ์ผ O_TRUNC
- ๋ถ๋ถ ์ฐ๊ธฐ ์ฒ๋ฆฌ
- EINTR ๋์
- ๋์ผ ํ์ผ(๊ฐ์ device+inode) ๋ณต์ฌ ๊ธ์ง
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
static ssize_t write_all(int fd, const void *buf, size_t n)
{
const char *p = (const char *)buf;
size_t left = n;
while (left > 0) {
ssize_t w = write(fd, p, left);
if (w < 0) {
if (errno == EINTR) continue; // interrupted by signal: retry
return -1; // real error
}
p += w;
left -= w;
}
return (ssize_t)n;
}
int main(int argc, char *argv[])
{
if (argc != 3) {
fprintf(stderr, "Usage: %s <src> <dst>\n", argv[0]);
return 1;
}
int fd1 = open(argv[1], O_RDONLY);
if (fd1 < 0) {
fprintf(stderr, "open src '%s' failed: %s\n", argv[1], strerror(errno));
return 1;
}
// O_TRUNC: ๋์ ํ์ผ์ด ์ด๋ฏธ ์์ผ๋ฉด ๊ธธ์ด๋ฅผ 0์ผ๋ก ์๋ผ์ '์ ํํ ๊ฐ์ ํฌ๊ธฐ'๊ฐ ๋๊ฒ ํจ
int fd2 = open(argv[2], O_WRONLY | O_CREAT | O_TRUNC, 0644);
if (fd2 < 0) {
fprintf(stderr, "open dst '%s' failed: %s\n", argv[2], strerror(errno));
close(fd1);
return 1;
}
// ๊ฐ์ ํ์ผ์ธ์ง ๊ฒ์ฌ (device + inode)
struct stat st_src, st_dst;
if (fstat(fd1, &st_src) == 0 && fstat(fd2, &st_dst) == 0) {
if (st_src.st_dev == st_dst.st_dev && st_src.st_ino == st_dst.st_ino) {
fprintf(stderr, "Refusing to copy a file onto itself.\n");
close(fd1);
close(fd2);
return 1;
}
}
char buf[BUFSIZ];
for (;;) {
ssize_t r = read(fd1, buf, sizeof(buf));
if (r == 0) break; // EOF
if (r < 0) {
if (errno == EINTR) continue; // retry on signal
fprintf(stderr, "read failed: %s\n", strerror(errno));
close(fd1);
close(fd2);
return 1;
}
if (write_all(fd2, buf, (size_t)r) < 0) {
fprintf(stderr, "write failed: %s\n", strerror(errno));
close(fd1);
close(fd2);
return 1;
}
}
if (close(fd1) < 0) {
fprintf(stderr, "close(src) failed: %s\n", strerror(errno));
// ๊ณ์ ์งํ (์ด๋ฏธ ๋ณต์ฌ๋ณธ์ ๋๋ถ๋ถ ์์ฑ๋จ)
}
if (close(fd2) < 0) {
fprintf(stderr, "close(dst) failed: %s\n", strerror(errno));
return 1;
}
return 0;
}
gcc -Wall -Wextra -O2 -o 2 copy.c
# -Wall -Wextra : ๊ฒฝ๊ณ ๋ฅผ ๋๊ฒ ์ผฌ(ํ์ง↑)
# -O2 : ์ต์ ํ(์๋/์ฉ๋ ์ ๋นํ)
[Linux/Unix] ๋ฆฌ๋ ์ค/์ ๋์ค ์์คํ ํ๋ก๊ทธ๋๋ฐ์ ์ดํด
๐ 1[02] ๋ฆฌ๋ ์ค์ ๋์ค์์คํ ํ๋ก๊ทธ๋๋ฐ์์ดํด๋ฆฌ๋ ์ค/์ ๋์ค ์์คํ ๊ตฌ์กฐ์ ํ์ค, ์์คํ ํธ์ถ๊ณผ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ํจ์, man ํ์ด์ง ์ฌ์ฉ๋ฒ๐งญ 2[02] vivi ์๋ํฐ ์ฌ์ฉ๋ฒ — ๋ชจ๋, ๋ช ๋ น์ด, ํธ์ง, ์ ์ฅ ๋ฑ
lxvxxu.tistory.com

https://lxvxxu.tistory.com/155
[Linux/Unix] 04-3. Inode ์ ๋ณด ์ถ๋ ฅ
#include #include #include int main() { DIR *dp; struct dirent *dent; dp = opendir("."); while ((dent = readdir(dp))) { printf("Name : %s ", dent->d_name); printf("Inode : %d\n", (int)dent->d_ino); } closedir(dp);} ์ข์! ์ฌ์ง ์ ์ฝ๋๋ ํ์ฌ ๋
lxvxxu.tistory.com

5) $ ./2 test.txt test.bak ์ ์คํํ๋ฉด?
- ์๋ณธ ์ฝ๋(์ฌ์ง ๋ฒ์ )
- test.txt ๋ด์ฉ์ ์ฝ์ด test.bak์ ์๋๋ค.
- test.bak๊ฐ ์์ผ๋ฉด 0644 ๊ถํ์ผ๋ก ์๋ก ๋ง๋ค์ด ๋ณต์ฌ๋จ.
- test.bak๊ฐ ์ด๋ฏธ ์์๋ค๋ฉด ์๋ถ๋ถ์ ์ ๋ด์ฉ์ผ๋ก ๋ฎ์ง๋ง, ์๋ ํ์ผ์ด ๋ ๊ธธ์์ ๊ฒฝ์ฐ ๋ท๋ถ๋ถ์ ์ด์ ๋ด์ฉ์ด ๋จ์ต๋๋ค. (์๋๋ฉด O_TRUNC๊ฐ ์๊ธฐ ๋๋ฌธ)
- ๊ฐ์ ์ฝ๋(์ ์๋ฌ ์ฒ๋ฆฌ ๋ฒ์ )
- test.bak์ด ์์ผ๋ฉด ๋ง๋ค๊ณ , ์์ผ๋ฉด ๊ธธ์ด๋ฅผ 0์ผ๋ก ์๋ผ(O_TRUNC) test.txt์ ๋ฑ ๊ฐ์ ๋ด์ฉ์ด ๋๋๋ก ๋ณต์ฌํฉ๋๋ค.
- ์ธ์ ๋ถ์กฑ/ํ์ผ ์ด๊ธฐ ์คํจ/์ฝ๊ธฐ·์ฐ๊ธฐ ์ค๋ฅ/๋์ผ ํ์ผ ๋ณต์ฌ ์๋๋ฅผ ์ ๋ถ ๊ฐ์งํด ์น์ ํ ์๋ฌ ๋ฉ์์ง๋ฅผ ์ถ๋ ฅํฉ๋๋ค.
ํ์ํ๋ฉด O_EXCL์ ๋ํด O_CREAT|O_EXCL๋ก “์ด๋ฏธ ์กด์ฌํ๋ฉด ์คํจ(๋ฎ์ด์ฐ๊ธฐ ๊ธ์ง)” ์ ์ฑ ์ผ๋ก ๋ฐ๊ฟ ์๋ ์์ด. ๋ fsync(fd2)๋ก ๋์คํฌ ๋๊ธฐํ๊น์ง ๋ณด์ฅํ๊ณ ์ถ๋ค๋ฉด ๋ณต์ฌ ๋์ ํ ๋ฒ ํธ์ถํด ์ฃผ๋ฉด ์ข์.


์ข์, 0644 ๊ถํ์ ๊น๋ํ๊ฒ ์ชผ๊ฐ์ ์ค๋ช ํด๋ณผ๊ฒ.
0644๊ฐ ๋ปํ๋ ๊ฒ
- 8์ง์ ํ๊ธฐ: ์์ 0์ 8์ง์(octal)๋ผ๋ ๋ป.
- ๋ค ์๋ฆฌ:
- 0 → ํน์๋นํธ(SETUID, SETGID, sticky) ์์
- 6 → ์์ ์(owner) ๊ถํ
- 4 → ๊ทธ๋ฃน(group) ๊ถํ
- 4 → ๊ธฐํ(other) ๊ถํ
- r=4, w=2, x=1 ์ด๋ผ๋ ๊ฐ ํฉ์ผ๋ก ํํ:
- 6 = 4(r) + 2(w) = rw-
- 4 = 4(r) = r--
๊ทธ๋์ 0644 = ์์ ์ rw-, ๊ทธ๋ฃน r--, ๊ธฐํ r-- ์ด๊ณ , ls -l๋ก ๋ณด๋ฉด ๋ณดํต:
(๋งจ ์์ -๋ ํ์ผ ํ์ : -(์ผ๋ฐํ์ผ), d(๋๋ ํฐ๋ฆฌ) ๋ฑ)
ํ์ผ๊ณผ ๋๋ ํฐ๋ฆฌ์์์ ์ฐจ์ด
๊ถํ ๋นํธ์ ์๋ฏธ๊ฐ ํ์ผ๊ณผ ๋๋ ํฐ๋ฆฌ์์ ์กฐ๊ธ ๋ค๋ฅด๊ฒ ๋๊ปด์ ธ:
์ผ๋ฐ ํ์ผ์ 0644
- ์์ ์: ์ฝ๊ธฐ/์ฐ๊ธฐ ๊ฐ๋ฅ (์์ ๊ฐ๋ฅ)
- ๊ทธ๋ฃน/๊ธฐํ: ์ฝ๊ธฐ๋ง ๊ฐ๋ฅ (์์ ๋ถ๊ฐ)
- ์คํ(x) ์์: ์คํ ํ์ผ์ด ์๋ → ์คํฌ๋ฆฝํธ/๋ฐ์ด๋๋ฆฌ๋ก ์คํ ์ ๋จ
๋๋ ํฐ๋ฆฌ์ 0644 (์ฃผ์!)
- r(์ฝ๊ธฐ): ๋๋ ํฐ๋ฆฌ ๋ชฉ๋ก์ ์ฝ์ ๊ถ๋ฆฌ
- x(์คํ): ๋๋ ํฐ๋ฆฌ ์ง์ /ํ์ ๊ถ๋ฆฌ(search/traverse)
- 0644๋ x๊ฐ ์ ๋ถ ๋น ์ ธ์:
- cd๋ก ๋ค์ด๊ฐ์ง ๋ชปํจ
- ํ์ผ ์กด์ฌ ์ฌ๋ถ ํ์ธ๋ ์ ํ๋จ
- ls๋ ์ ๋๋ก ๋ชป ํ ์ ์์(ํ๋ซํผ/์ํฉ์ ๋ฐ๋ผ ์๋ฌ)
→ ๋๋ ํฐ๋ฆฌ๋ ๋ณดํต 0755(r-x r-x r-x)๋ 0700์ฒ๋ผ ์คํ(x) ๋นํธ๋ฅผ ์ผ์ ์.
์ 0644๊ฐ ํํ ๊น? (umask์์ ๊ด๊ณ)
์ ํ์ผ์ ๊ธฐ๋ณธ ๊ถํ์:
- ํ์ผ: 0666 & ~umask
- ๋๋ ํฐ๋ฆฌ: 0777 & ~umask
์ผ๋ฐ์ ์ธ ๊ธฐ๋ณธ umask๊ฐ 022๋ผ๋ฉด:
- ํ์ผ: 0666 & 0755 = 0644
- ๋๋ ํฐ๋ฆฌ: 0777 & 0755 = 0755
๊ทธ๋์ ์๋ก ๋ง๋ ์ผ๋ฐ ํ์ผ์ด ๋์ฒด๋ก 0644, ๋๋ ํฐ๋ฆฌ๋ 0755์ธ ๊ฒ.
์ค์ /๋ณ๊ฒฝ ๋ฐฉ๋ฒ
์ซ์ ํ๊ธฐ
๊ธฐํธ ํ๊ธฐ(๋๋ฑ ์๋ฏธ)
chmod u=rw,go=r file.txt
# ๋๋
chmod a=r,u+w file.txt
ํ์คํ ์คํ ๋นํธ ์ ๊ฑฐ
์ฒดํฌํ๊ธฐ
ls -l file.txt
# -rw-r--r-- ... file.txt
stat -c '%a %A %n' file.txt
# 644 -rw-r--r-- file.txt
์ค์ ํ & ํจ์
- ์คํ ์คํฌ๋ฆฝํธ๋ 0755์ฒ๋ผ ์คํ ๋นํธ๋ฅผ ์ค์ผ ์คํ๋จ:
-
chmod 0755 run.sh
- ๋ฏผ๊ฐํ ์ค์ ํ์ผ(SSH ํค ๋ฑ)์ ๋๋ฌด ๋์ ๊ถํ์ด๋ฉด ํ๋ก๊ทธ๋จ์ด ๊ฑฐ๋ถํจ:
-
chmod 0600 ~/.ssh/id_rsa
- ์ฌ๋ณผ๋ฆญ ๋งํฌ์ chmod ํด๋ ๋ณดํต ๋งํฌ ์์ฒด ๊ถํ์ ์๋ฏธ ์๊ณ , ๋์ ํ์ผ ๊ถํ์ ์ ์ฉ๋๊ฑฐ๋ ๋ฌด์๋จ(์์คํ ์ ๋ฐ๋ผ ๋ค๋ฆ).
- ACL/๋ฅ๋ ฅ(capabilities) ์ด ์ถ๊ฐ๋ก ์ค์ ๋ ํ๊ฒฝ์์ ๋จ์ 0644๋ง์ผ๋ก ์ ๊ทผ ์ ์ด๊ฐ ์์ ํ ์ค๋ช ๋์ง ์์ ์ ์์ด์.
- ๊ณต์ ํ๊ฒฝ์์ 0644๋ “๋ค๋ฅธ ์ฌ์ฉ์์๊ฒ ์ฝ๊ธฐ ํ์ฉ”์ด๋ฏ๋ก, ๋ฏผ๊ฐํ ๋ด์ฉ์ด๋ผ๋ฉด 0600์ ๊ณ ๋ ค.
์์ฝ ํ ์ค
0644 = ์์ ์ ์ฝ๊ธฐ/์ฐ๊ธฐ, ๋๋จธ์ง๋ ์ฝ๊ธฐ๋ง, ์คํ์ ์์.
์ผ๋ฐ ํ์ผ์ ๊ธฐ๋ณธ ๊ถํ์ผ๋ก ์ ์ ํ๊ณ , ๋๋ ํฐ๋ฆฌ์ ๋ถ์ ์ (๋์ 0755๋ฅผ ์ฌ์ฉ).
'6. CS ๊ธฐ์ด ๐ > Linux & Unix ๐ง' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
| [Linux/Unix][7-1] sysocnf(3) ํจ์ ํ์ฉ (0) | 2025.10.21 |
|---|---|
| [Linux/Unix][6-3] ํฉ&ํ๊ท ์ถ๋ ฅ ํ๋ก๊ทธ๋จ (0) | 2025.10.21 |
| [Linux/Unix][6-1] txt write err ์ฒ๋ฆฌ (0) | 2025.10.21 |
| [Linux/Unix][5-2] ํ๋ ๋งํฌ vs ์ฌ๋ณผ๋ฆญ ๋งํฌ (0) | 2025.10.21 |
| [Linux/Unix][5-1] stat ๊ตฌ์กฐ์ฒด์ ๋ฉค๋ฒ // st_mode (0) | 2025.10.21 |