https://1d1cblog.tistory.com/375
filedir.c
#include "th.h"
char *stat_name(char rcvmsg[BUFFER_SIZE]){
struct stat statbuf;
char *sndmsg = malloc(BUFFER_SIZE);
if(stat(rcvmsg, &statbuf) < 0) out("stat error", NULL, 0, NULL);
if(S_ISREG(statbuf.st_mode)){
strcpy(sndmsg, "file");
}
else if(S_ISDIR(statbuf.st_mode)){
strcpy(sndmsg, "directory");
}
return sndmsg;
}
void print_file(const char *path){
int fd, n;
unsigned char buf[BUFFER_SIZE];
fd = open(path, O_RDONLY);
if(fd < 0) out("open error", NULL, fd, NULL);
for(;;){
n = read(fd, buf, sizeof buf);
if(n < 0) out("read error", NULL, fd, NULL);
if(n == 0) break;
if(write(STDOUT_FILENO, buf, n) < 0) out("write error", NULL, fd, NULL);
}
if(close(fd) < 0) out("close error", NULL, fd, NULL);
}
void print_file_lib(const char *path){
char *n;
unsigned char buf[BUFFER_SIZE];
FILE *f = fopen(path, "r");
if(!f) out("fopen error", f, 0, NULL);
while(1){
n = fgets(buf, BUFFER_SIZE, f);
if(!n) break;
printf("%s", buf);
}
if(fclose(f) == EOF) out("fclose error", f, 0, NULL);
}
void print_dir(char *path) {
DIR *d;
struct dirent *ent;
struct stat st;
d = opendir(path);
if(!d) out("opendir error", NULL, 0, d);
while(ent = readdir(d)){
char fpath[BUFFER_SIZE] = { };
strcat(fpath, path);
strcat(fpath, "/");
strcat(fpath, ent->d_name);
if(stat(fpath, &st) < 0) out("dir: stat error", NULL, 0, NULL);
if(S_ISDIR(st.st_mode)){
printf("%s/\n", ent->d_name);
}else if(S_ISREG(st.st_mode)) printf("%s*\n", ent->d_name);
}
closedir(d);
}
void out(const char *s, FILE *f, int fd, DIR *d){
perror(s);
if(f) fclose(f);
if(fd) close(fd);
if(d) closedir(d);
exit(1);
}
inout.c
#include "th.h"
char *input_msg(){
char *str = malloc(BUFFER_SIZE);
printf("\nfile or directory name: ");
scanf("%s", str); getchar();
return str;
}
void output_msg(char rcvmsg[BUFFER_SIZE], char sndmsg[BUFFER_SIZE]){
if(!strcmp(rcvmsg, "file"))
print_file_lib(sndmsg);
else if(!strcmp(rcvmsg, "directory"))
print_dir(sndmsg);
}
sem.c
#include "th.h"
void s_init(sem_t sem, unsigned int val){
if(sem_init(&sem, 0, val) == -1){
perror("sem_init error");
exit(1);
}
}
void s_destroy(sem_t sem){
sem_destroy(&sem);
}
void s_wait(sem_t sem){
sem_wait(&sem);
}
void s_post(sem_t sem){
sem_post(&sem);
}
shm.c
#include "th.h"
void create_shm(key_t key, size_t size){
shmid = shmget(key, size, 0666|IPC_CREAT|IPC_EXCL);
if (shmid == -1){
perror("shmget failed : ");
exit(0);
}
}
char *at_shm(int shmid){
char *shared_memory;
shared_memory = shmat(shmid, (void *)0, 0);
if (shared_memory == (void *)-1){
perror("shmat failed : ");
exit(0);
}
return shared_memory;
}
void rmv_shm(){
if(shmctl(shmid,IPC_RMID,NULL)==-1){
printf("shmctl failed\n");
}
}
th.h
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <errno.h>
#include <dirent.h>
#include <fcntl.h>
#include <unistd.h>
#include <string.h>
#include <pthread.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <semaphore.h>
#define BUFFER_SIZE 2048
union semun{
int val;
struct semid_ds *buf;
unsigned short *array;
};
int shmid;
static sem_t sem_one, sem_two, sem_three;
char *stat_name(char rcvmsg[BUFFER_SIZE]);
void print_file(const char *path);
void print_file_lib(const char *path);
void print_dir(char *path);
void out(const char *s, FILE *f, int fd, DIR *d);
void s_wait(sem_t sem);
void s_post(sem_t sem);
void s_init(sem_t sem, unsigned int val);
void s_destroy(sem_t sem);
void create_shm(key_t key, size_t size);
char *at_shm(int shmid);
void rmv_shm();
pthread_t create_thread(pthread_t thread, void *(*start_routine)(void *));
void join_thread(pthread_t thread);
void *sub_thread(void *command);
char *input_msg();
void output_msg(char rcvmsg[BUFFER_SIZE], char sndmsg[BUFFER_SIZE]);
thread.c
#include "th.h"
pthread_t create_thread(pthread_t thread, void *(*start_routine)(void *)){
if(pthread_create(&(thread), NULL, start_routine, NULL))
out("pthread create error", NULL, 0, NULL);
return thread;
}
void join_thread(pthread_t thread){
printf("join thread\n");
if(pthread_join(thread, NULL))
out("pthread_join error", NULL, 0, NULL);
}
void *sub_thread(void *command){
struct stat statbuf;
char *shared_memory;
char sndmsg[BUFFER_SIZE];
char rcvmsg[BUFFER_SIZE];
pthread_t tid;
tid = pthread_self();
printf("[tid]: %lx\n", tid);
while(1){
printf("sub1\n");
printf("one: 1 -> 0\n");
sem_wait(&sem_one); //1 -> 0
printf("22222\n");
printf("sub2\n");
printf("shmid: %d\n", shmid);
shared_memory = at_shm(shmid);
printf("1sub, name: %s\n\n", shared_memory);
if(!strcmp(shared_memory, "exit")){
break;
}
sprintf(shared_memory, "%s", stat_name(shared_memory));
printf("2sub, name: %s\n\n", shared_memory);
printf("sub3\n");
printf("two: 0 -> 1\n");
sem_post(&sem_two); //0 -> 1
printf("sub4\n");
}
}
main.c
#include "th.h"
int main(int argc, char *argv[]){
key_t key = 12345;
pthread_t thread;
char *shared_memory;
char sndmsg[BUFFER_SIZE];
char rcvmsg[BUFFER_SIZE];
create_shm(key, BUFFER_SIZE);
sem_init(&sem_one, 0, 0);
sem_init(&sem_two, 0, 1);
thread = create_thread(thread, sub_thread);
sleep(1);
while(1){
printf("two: 1 -> 0\n");
sem_wait(&sem_two); //1 -> 0
strcpy(sndmsg, input_msg());
printf("main3\n");
if(!strlen(sndmsg)){
printf("no command\n");
continue;
}
printf("main4\n");
shared_memory = at_shm(shmid);
sprintf(shared_memory, "%s", sndmsg);
sleep(2);
printf("main5\n");
printf("main, name: %s\n", shared_memory);
if(!strcmp(sndmsg, "exit")){
sleep(1);
break;
}
printf("main2, stat: %s\n", shared_memory);
output_msg(shared_memory, sndmsg);
printf("main output: %s, %s\n", shared_memory, sndmsg);
printf("one: 0 -> 1\n");
sem_post(&sem_one); //0 -> 1
printf("111111\n");
sleep(1);
}
rmv_shm();
join_thread(thread);
exit(0);
}
makefile
a.out: main.o shm.o thread.o filedir.o inout.o sem.o
gcc -g -pthread -o a.out main.o shm.o thread.o filedir.o inout.o sem.o
main.o: th.h main.c
gcc -c -o main.o main.c
shm.o: th.h shm.c
gcc -c -o shm.o shm.c
sem.o: th.h sem.c
gcc -c -o sem.o sem.c
thread.o: th.h thread.c
gcc -c -o thread.o thread.c
filedir.o: th.h filedir.c
gcc -c -o filedir.o filedir.c
inout.o: th.h inout.c
gcc -c -o inout.o inout.c
lock.c
#include <semaphore.h>
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
void * read(void * arg);
void * accu(void * arg);
static sem_t sem_one;
static sem_t sem_two;
static int num;
int main(int argc, char *argv[]){
pthread_t id_t1, id_t2;
sem_init(&sem_one, 0, 0);
sem_init(&sem_two, 0, 1);
//pthread_create(&id_t1, NULL, read, NULL);
pthread_create(&id_t2, NULL, accu, NULL);
for(int i=0; i<5; i++){
fputs("Input num: ", stdout);
printf("two: 1 -> 0\n");
sem_wait(&sem_two); // sem_two 열쇠 감소(count : 1 -> 0)
scanf("%d", &num);
printf("one: 0 -> 1\n");
sem_post(&sem_one); // sem_one 열쇠를 하나 줌(count : 0 -> 1)
printf("\n");
}
pthread_join(id_t1, NULL);
pthread_join(id_t2, NULL);
sem_destroy(&sem_one);
sem_destroy(&sem_two);
return 0;
}
void * read(void * arg){
int i;
for(i=0; i<5; i++){
fputs("Input num: ", stdout);
printf("two: 1 -> 0\n");
sem_wait(&sem_two); // sem_two 열쇠 감소(count : 1 -> 0)
scanf("%d", &num);
printf("one: 0 -> 1\n");
sem_post(&sem_one); // sem_one 열쇠를 하나 줌(count : 0 -> 1)
}
}
void * accu(void * arg){
int sum=0, i;
for(i=0; i<5; i++){
printf("one: 1 -> 0\n");
sem_wait(&sem_one); // sem_one 열쇠 감소(count : 1 -> 0)
sum+=num;
printf("%d\n", sum);
printf("two: 0 -> 1\n");
sem_post(&sem_two); // sem_two 열쇠를 하나 줌(count : 0 -> 1)
}
}