Skip to content

Instantly share code, notes, and snippets.

@acious
Created June 7, 2017 16:35
Show Gist options
  • Save acious/44ce75ec83a99c816d3ca26edddca19b to your computer and use it in GitHub Desktop.
Save acious/44ce75ec83a99c816d3ca26edddca19b to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#include <dirent.h>
#include <ctype.h>
#define FIFO_FILE "/tmp/fifo"
void readFile(char *string);
void argErrorCheck(int argc, char **args);
void executeW(char *filename);
pid_t getOFMPid();
char *ltrim(char *s);
pid_t ofm_pid;
int main(int argc, char *argv[]) {
argErrorCheck(argc, argv);
if (!strcmp("-r", argv[2])) {
// 읽기
readFile(argv[1]);
} else if (!strcmp("-w", argv[2])) {
// 쓰기
executeW(argv[1]);
} else if (!strcmp("-rw", argv[2])) {
// 읽기쓰기
char modifyDecide[3];
readFile(argv[1]);
printf("Would you like to modify '%s'? (yes/no)\n", argv[1]);
scanf("%s", modifyDecide);
if (!strcmp("yes", modifyDecide)) {
executeW(argv[1]);
} else if (!strcmp("no", modifyDecide)) {
exit(0);
} else {
printf("wrong correct.\n");
exit(0);
}
}
return 0;
}
void executeW(char *filename) {
// ▶ ssu_ofm이 만든 디몬 프로세스와 시그널을 주고받으며 동기화한 다음, vim에디터를 실행함.
// ▶ ssu_vim이 수정하려는 파일에 접근할 수 있는지 여부를 확인하기 위해서 SIGUSR1 시그널을 사용함
// ▶ ssu_ofm으로부터 시그널을 받기 전까지는 대기 상태(무한 루프)에 접어듬.
// ▶ 루프 중에 1초 간격으로 Waiting for Token...<FILENAME> 문자열을 출력함.
// ▶ ssu_vim이 ssu_ofm으로부터 수정하려는 파일에 접근이 가능하다는 시그널인 SIGUSR1을 받으면,
// 자식 프로세스를 생성하여 vim에디터를 실행시킴
// ▶ ssu_vim은 자식 프로세스인 vim에디터가 수행을 마칠 때까지 대기해야 함
// ▶ 자식 프로세스인 vim에디터가 수행을 마치면 ssu_vim은 수행을 마쳤다고 ssu_ofm에게 SIGUSR2
// 를 전송
// ▶ SIGUSR2 시그널을 전송하고 나서 ssu_vim은 종료
//ssu_ofm의 pid를 가져와야한다.
ofm_pid = getOFMPid();
printf("ofmPid : %d", ofm_pid);
kill(ofm_pid, SIGUSR1);
while (1) {
printf("Waiting for Token...<%s>\n", filename);
sleep(1);
}
}
pid_t getOFMPid() {
char *procDefaultPath = "/proc/";
int pid = 0;
struct dirent *dentry;
struct stat statbuf;
char filename[255];
DIR *dirp;
if ((dirp = opendir(procDefaultPath)) == NULL || chdir(procDefaultPath) == -1) {
fprintf(stderr, "error on getProcFD : opendir, chdir error for %s\n", procDefaultPath);
exit(1);
}
while ((dentry = readdir(dirp)) != NULL) {
memcpy(filename, dentry->d_name, 255);
if (!isdigit(filename[0]))
continue;
pid = atoi(filename);
char procAfterPath[255] = {0};
sprintf(procAfterPath, "%s%s", filename, "/status");
char procStatusPath[255] = {0};
sprintf(procStatusPath, "%s%s", procDefaultPath, procAfterPath);
FILE *fp;
char buf[1024];
if ((fp = fopen(procStatusPath, "r")) == NULL) {
fprintf(stderr, "fopen error for %s\n", procStatusPath);
exit(1);
} else {
fgets(buf, 1024, fp);
if (strstr(buf, "ssu_ofm") <= 0) {
continue;
} else {
return pid;
}
}
}
return 0;
}
void argErrorCheck(int argc, char **args) {
int checkCount = 0;
for (int i = 2; i < argc; ++i) {
if (!strcmp("-r", args[i]) || !strcmp("-w", args[i]) || !strcmp("-rw", args[i])) {
checkCount++;
}
}
if (checkCount > 1) {
fprintf(stderr, "Error : Please input args only one : -r / -w / -rw\n");
exit(0);
}
}
void readFile(char *filename) {
FILE *fp;
int character;
if ((fp = fopen(filename, "r")) == NULL) {
fprintf(stderr, "fopen error for %s\n", filename);
exit(1);
}
character = fgetc(fp);
while (!feof(fp)) {
fputc(character, stdout);
if (ferror(fp)) {
fprintf(stderr, "Error detected. When filereading.\n");
clearerr(fp);
}
character = fgetc(fp);
}
fclose(fp);
}
char *ltrim(char *s) {
char *begin;
begin = s;
while (*begin != '\0') {
if (isspace(*begin))
begin++;
else {
s = begin;
break;
}
}
return s;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment