ex1. 명령행 인자로 받은 파일의 크기를 알려주는 프로그램을 작성하시오
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
if (argc == 1) {
printf("usage: ex1 filename\n");
exit(1);
}
struct stat statbuf;
stat(argv[1], &statbuf);
printf("SIZE = %d\n", (int)statbuf.st_size);
return 0;
}
ex2. 명령행 인자로 받은 파일의 종류를 출력하는 프로그램을 작성하시오
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
if (argc == 1) {
printf("usage: ex2 filename\n");
exit(1);
}
struct stat statbuf;
int kind;
stat(argv[1], &statbuf);
printf("mode = %o\n", (unsigned int)statbuf.st_mode);
kind = statbuf.st_mode & S_IFMT;
switch (kind) {
case S_IFLNK:
printf("%s: symbolic link\n", argv[1]);
break;
case S_IFDIR:
printf("%s: directory\n", argv[1]);
break;
case S_IFREG:
printf("%s: regular file\n", argv[1]);
break;
}
return 0;
}
ex3. 명령행 인자로 받은 파일의 정보를 추출해 다음 예와 같이 출력하는 프로그램을 작성하시오
- 파일명:
- inode번호:
- 파일종류:
- 접근권한:
- UID:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
if (argc == 1) {
printf("usage: ex3 filename\n");
exit(1);
}
struct stat statbuf;
int kind;
stat(argv[1], &statbuf);
printf("file name: %s\n", argv[1]);
printf("inode: = %d\n", (int)statbuf.st_ino);
kind = statbuf.st_mode & S_IFMT;
switch (kind) {
case S_IFLNK:
printf("link file\n");
break;
case S_IFDIR:
printf("directory\n");
break;
case S_IFREG:
printf("regular file\n");
break;
}
printf("permission %o\n", (unsigned int)statbuf.st_mode);
printf("UID: %d\n", (unsigned int)statbuf.st_uid);
return 0;
}
ex4. 명령행 인자로 받은 파일의 UID와 접근권한을 다음 예와 같이 출력하는 프로그램을 작성하시오
a.c 1000 rw-r—r—
// S_IRUSR=0, S_IWUSR=1, S_IXUSR=2, S_IRGRP=0, S_IWGRP=1, …
CheckMode(statbuf.st_mode, S_IRUSR, 0);
CheckMode(statbuf.st_mode, S_IWUSR, 1);
CheckMode(statbuf.st_mode, S_IXUSR, 2);
CheckMode(statbuf.st_mode, S_IRGRP, 0);
……
void CheckMode(unsigned int mode, int m, int k) {
if ((mode & m) != 0) {
switch(k) {
case 0: /* r */
printf("r");
break;
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
void CheckMode(unsigned int mode, int m, int k) {
if ((mode & m) != 0) {
switch(k) {
case 0: /* r */
printf("r");
break;
case 1: /* 1 */
printf("w");
break;
case 2: /* 2 */
printf("x");
break;
}
}
else
printf("-");
}
int main(int argc, char* argv[]) {
if (argc == 1) {
printf("usage: ex4 filename\n");
exit(1);
}
struct stat statbuf;
int kind;
stat(argv[1], &statbuf);
printf("%s %d ", argv[1], (unsigned int)statbuf.st_uid);
// 유저 체크
CheckMode(statbuf.st_mode, S_IRUSR, 0);
CheckMode(statbuf.st_mode, S_IWUSR, 1);
CheckMode(statbuf.st_mode, S_IXUSR, 2);
// 그룹 체크
CheckMode(statbuf.st_mode, S_IRGRP, 0);
CheckMode(statbuf.st_mode, S_IWGRP, 1);
CheckMode(statbuf.st_mode, S_IXGRP, 2);
// 기타 사용자 체크
CheckMode(statbuf.st_mode, S_IROTH, 0);
CheckMode(statbuf.st_mode, S_IWOTH, 1);
CheckMode(statbuf.st_mode, S_IXOTH, 2);
printf("\n");
return 0;
}
ex5. 현재 디렉터리에 있는 모든 파일 및 하위 디렉터리의 이름과 inode를 출력하는 프로그램을 작성하시오
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
int main() {
DIR* dp;
struct dirent* dent;
struct stat statbuf;
if ((dp = opendir(".")) == NULL) {
perror("opendir");
exit(1);
}
while (dent = readdir(dp)) {
stat(dent->d_name, &statbuf);
printf("name: %s ", dent->d_name);
printf("inode = %d\n", (int)statbuf.st_ino);
}
closedir(dp);
return 0;
}
ex6. 현재 디렉터리에서 . 과 .. 항목을 제외하고 하위 디렉터리만 출력하는 프로그램을 작성하시오
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
int main() {
DIR* dp;
struct dirent* dent;
int count;
struct stat statbuf;
if ((dp = opendir(".")) == NULL) {
perror("opendir");
exit(1);
}
while (dent = readdir(dp)) {
if (dent->d_name[0] == '.')
continue;
stat(dent->d_name, &statbuf);
if (S_ISDIR(statbuf.st_mode)) {
printf("name: %s, inode: %d\n", dent->d_name, statbuf.st_ino);
}
}
closedir(dp);
return 0;
}
hw1. 명령행 인자로 받은 파일의 기존 접근권한을 출력하고 접근권한을 변경하는 프로그램을 작성하시오
./hw1 g+w test.txt
int x;
switch (argv[1][0]) {
case 'u':
switch (argv[1][2]) {
case 'r': x = S_IRUSR; break;
case 'w': x = S_IWUSR; break;
case 'x': x = S_IXUSR; break;
……
if (argv[1][1] == '+') buf.st_mode |= x;
else if (argv[1][1] == '-') buf.st_mode &= ~(x);
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
void print_permissions(struct stat buf);
int main(int argc, char* argv[]) {
if (argc < 3) {
printf("usage: hw1 permission_command file_name\n");
exit(1);
}
struct stat buf;
stat(argv[2], &buf);
print_permissions(buf);
int x = 0;
switch (argv[1][2]) {
case 'r':
x = (argv[1][0] == 'u') ? S_IRUSR : (argv[1][0] == 'g') ? S_IRGRP : S_IROTH;
break;
case 'w':
x = (argv[1][0] == 'u') ? S_IWUSR : (argv[1][0] == 'g') ? S_IWGRP : S_IWOTH;
break;
case 'x':
x = (argv[1][0] == 'u') ? S_IXUSR : (argv[1][0] == 'g') ? S_IXGRP : S_IXOTH;
break;
default:
printf("invalid permission\n");
exit(1);
}
if (argv[1][1] == '+') {
buf.st_mode |= x;
} else if (argv[1][1] == '-') {
buf.st_mode &= ~x;
}
chmod(argv[2], buf.st_mode); // 파일에 새로운 권한 적용
printf("== after updated ==\n");
print_permissions(buf);
return 0;
}
void print_permissions(struct stat buf) {
printf("permission: ");
printf((buf.st_mode & S_IRUSR) ? "r" : "-");
printf((buf.st_mode & S_IWUSR) ? "w" : "-");
printf((buf.st_mode & S_IXUSR) ? "x" : "-");
printf((buf.st_mode & S_IRGRP) ? "r" : "-");
printf((buf.st_mode & S_IWGRP) ? "w" : "-");
printf((buf.st_mode & S_IXGRP) ? "x" : "-");
printf((buf.st_mode & S_IROTH) ? "r" : "-");
printf((buf.st_mode & S_IWOTH) ? "w" : "-");
printf((buf.st_mode & S_IXOTH) ? "x" : "-");
printf("\n");
}
hw2. 명령행 인자로 받은 파일의 기존 접근권한을 출력하고 접근권한을 변경하는 프로그램을 작성하시오
./hw2 777 test.txt
int x, a;
for (a = 0; a < 3; a++) {
x = 0;
switch (argv[1][a]) {
case '7': x |= S_IRWXU; break;
case '6': x |= (S_IRUSR | S_IWUSR); break;
case '5': x |= (S_IRUSR | S_IXUSR); break;
case '4': x |= S_IRUSR; break;
case '3': x |= (S_IWUSR | S_IXUSR); break;
…………
}
if (a == 0) buf.st_mode |= x;
if (a == 1) buf.st_mode |= (x>>3);
if (a == 2) buf.st_mode |= (x>>6);
// 반드시 chmod를 실행해야 파일접근권한이 수정됨
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
void print_permissions(struct stat buf);
int main(int argc, char* argv[]) {
if (argc < 3) {
printf("usage: hw2 permission_mode file_name\n");
exit(1);
}
struct stat buf;
stat(argv[2], &buf);
print_permissions(buf);
int x, a;
for (a = 0; a < 3; a++) {
switch (argv[1][a]) {
case '7':
x |= S_IRWXU;
break;
case '6':
x |= (S_IRUSR | S_IWUSR);
break;
case '5':
x |= (S_IRUSR | S_IXUSR);
break;
case '4':
x |= S_IRUSR;
break;
case '3':
x |= (S_IWUSR | S_IXUSR);
break;
case '2':
x |= S_IWUSR;
break;
case '1':
x |= S_IXUSR;
break;
case '0':
x = 0;
break;
default:
printf("invalid mode\n");
exit(1);
}
if (a == 0) { // 사용자 권한 설정
buf.st_mode = (buf.st_mode & ~S_IRWXU) | x;
}
if (a == 1) { // 그룹 권한 설정
buf.st_mode = (buf.st_mode & ~S_IRWXG) | (x >> 3);
}
if (a == 2) { // 기타 사용자 권한 설정
buf.st_mode = (buf.st_mode & ~S_IRWXO) | (x >> 6);
}
}
chmod(argv[2], buf.st_mode); // 파일에 새로운 권한 적용
printf("== after updated ==\n");
print_permissions(buf);
return 0;
}
void print_permissions(struct stat buf) {
printf("permission: ");
printf((buf.st_mode & S_IRUSR) ? "r" : "-");
printf((buf.st_mode & S_IWUSR) ? "w" : "-");
printf((buf.st_mode & S_IXUSR) ? "x" : "-");
printf((buf.st_mode & S_IRGRP) ? "r" : "-");
printf((buf.st_mode & S_IWGRP) ? "w" : "-");
printf((buf.st_mode & S_IXGRP) ? "x" : "-");
printf((buf.st_mode & S_IROTH) ? "r" : "-");
printf((buf.st_mode & S_IWOTH) ? "w" : "-");
printf((buf.st_mode & S_IXOTH) ? "x" : "-");
printf("\n");
}
ex1. 명령행 인자로 받은 파일의 심볼릭 링크를 생성하고, 심볼릭 링크 파일의 내용과 원본 파일의 경로를 출력하는 프로그램을 작성하시오
./ex1 testdata
n = 0;
while (argv[1][n] != '.') {
buf[n] = argv[1][n];
n++;
}
buf[n] = '\0';
printf("buf: %s\n", buf);
sprintf(symname, "%s.sym", buf);
printf("symname: %s\n", symname);
symlink(argv[1], symname);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
if (argc == 1) {
printf("usage: mysym filename\n");
exit(1);
}
char buf[256];
char symname[1024];
int n;
n = 0;
while(argv[1][n] != '.') {
buf[n] = argv[1][n];
n++;
}
buf[n] = '\0';
printf("buf: %s\n", buf);
sprintf(symname, "%s.sym", buf); // sprintf() 함수는 문자열을 포맷팅하는 함수(symname에 문자열을 저장)
printf("symname: %s\n", symname);
symlink(argv[1], symname);
n = readlink(symname, buf, sizeof(buf));
if (n == -1) {
perror("readlink");
exit(1);
}
buf[n] = '\0';
printf("%s: READLINK = %s\n", symname, buf);
realpath(symname, buf);
printf("%s: REALPATH = %s\n", symname, buf);
return 0;
}
ex2. 현재 디렉터리에서 inode가 같은 파일을 검색해 inode를 출력하는 프로그램을 작성하시오
(하드 링크로 여러 개의 파일을 생성한 후 실행함)
#include <stdio.h>
#include <stdlib.h>
#include <dirent.h>
#include <sys/stat.h>
int main(void) {
DIR* dp;
struct dirent* dent;
struct stat statbuf;
int count, i, j, isSameInode;
int ind[256], curInode;
if ((dp = opendir(".")) == NULL) {
perror("opendir");
exit(1);
}
count = 0;
while (dent = readdir(dp)) { // 디렉터리 내의 파일들을 하나씩 읽어옴
lstat(dent->d_name, &statbuf);
ind[count] = (int)statbuf.st_ino;
count++;
}
closedir(dp);
isSameInode = 0;
for (i = 0; i < count; i++) {
curInode = ind[i];
for (j = 0; j < count; j++) {
if (j != i && (curInode == ind[j]) && (ind[j] != -1)) {
printf("same inode: %d\n", curInode);
ind[j] = -1; // 이미 처리한 inode 번호는 -1로 표시하여 중복처리 방지
isSameInode = 1; // 동일한 inode를 찾았음을 표시
}
}
}
if (!isSameInode) {
printf("no same inode file\n");
}
return 0;
}
※ stat()이 아닌 lstat()을 써야 한다
ex3. 현재 디렉터리에 어떤 파일의 하드 링크가 여러 개 있을 때 그 중에 한 파일만 남기고, 링크를 모두 끊는 프로그램을 작성하시오
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
int main(void) {
DIR* dp;
struct dirent* dent;
struct stat statbuf;
if ((dp = opendir(".")) == NULL) {
perror("opendir");
exit(1);
}
while (dent = readdir(dp)) {
stat(dent->d_name, &statbuf);
if (((statbuf.st_mode & S_IFMT) == S_IFREG) && (statbuf.st_nlink > 1)) {
unlink(dent->d_name);
}
}
closedir(dp);
return 0;
}
참고 및 출처: 시스템 프로그래밍 리눅스&유닉스(이종원)
'Computer Science > UNIX & Linux' 카테고리의 다른 글
[UNIX/Linux] ep3+) 저수준 파일 입출력 함수 실습 (4) | 2024.10.02 |
---|---|
[UNIX/Linux] ep3) 저수준 파일 입출력 (5) | 2024.09.30 |
[UNIX/Linux] ep2) 파일 다루기 (0) | 2024.09.24 |
[UNIX/Linux] ep1+) 디렉터리 함수 실습 (1) | 2024.09.20 |
[UNIX/Linux] ep1) 디렉터리 다루기 (2) | 2024.09.11 |