Skip to content

Instantly share code, notes, and snippets.

@deeev-sb
Created May 6, 2020 20:02
Show Gist options
  • Save deeev-sb/fb74d303a9f8a0fc9e0d622524222c1e to your computer and use it in GitHub Desktop.
Save deeev-sb/fb74d303a9f8a0fc9e0d622524222c1e to your computer and use it in GitHub Desktop.
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#define TRUE 1
#define FALSE 0
#define NUM_RECORDS 100
struct record // rec-proc.c에서의 record data structure와 동일
{
char name[20]; // account owner
int id; // account umber
int balance; // balance (계좌 잔고)
};
int reclock(int fd, int recno, int len, int type); // record lock에 대한 argument define
// (file descriptor, record number, record length, record lock type)
void display_record(struct record *curr); // record 정보 출력 함수
int main()
{
struct record current; // record 임시 저장소
int record_no; // record number
int fd, pos, i, n; // file descriptor, record position, ...
char yes;
char operation;
int amount;
char buffer[100];
int quit = FALSE;
fd = open("./account", O_RDWR | O_CREAT, S_IRUSR | S_IWUSR); // file open
while (1)
{
printf("enter account number (0-99): "); // user가 읽으려는 account number를 입력 받음
scanf("%d", &record_no); // user가 읽으려는 account number
fgets(buffer, 100, stdin);
if (record_no < 0 && record_no >= NUM_RECORDS)
break;
printf("enter operation name (c/r/d/q): ");
scanf("%c", &operation);
switch (operation)
{
case 'c': // create (record 생성)
reclock(fd, record_no, sizeof(struct record), F_WRLCK); // file의 특정 영역에 writer's lock 설정
pos = record_no * sizeof(struct record); // record number에 해당되는 file position 계산
lseek(fd, pos, SEEK_SET); // record의 해당 position 위치를 찾아냄
printf("> id ? ");
scanf("%d", &current.id); // user로부터 id 입력 받음
printf("> name ? ");
scanf("%s", current.name); // user로부터 name 입력 받음
current.balance = 0; // 새로 생성한 account이므로 balance는 0
n = write(fd, &current, sizeof(struct record)); // 입력받은 정보들을 record에 write
display_record(&current); // update된 record 정보 출력
reclock(fd, record_no, sizeof(struct record), F_UNLCK); // 설정한 lock 해제
break;
case 'r': // inquiry (read balance)
reclock(fd, record_no, sizeof(struct record), F_RDLCK); // file의 특정 영역에 reader's lock 설정
pos = record_no * sizeof(struct record); // record number에 해당되는 file position 계산
lseek(fd, pos, SEEK_SET); // record의 해당 position 위치를 찾아냄
n = read(fd, &current, sizeof(struct record)); // read record
display_record(&current); // record 정보 출력
reclock(fd, record_no, sizeof(struct record), F_UNLCK); // 설정한 lock
break;
case 'd': // deposit (입금)
reclock(fd, record_no, sizeof(struct record), F_WRLCK); // file의 특정 영역에 writer's lock 설정
pos = record_no * sizeof(struct record); // record number에 해당되는 file position 계산
lseek(fd, pos, SEEK_SET); // record의 해당 position 위치를 찾아냄
n = read(fd, &current, sizeof(struct record)); // read record
display_record(&current); // record 정보 출력
printf("enter amount\n");
scanf("%d", &amount); // 입금할 금액 입력
current.balance += amount; // 현재 balance에 입금할 금액만큼 더해줌
lseek(fd, pos, SEEK_SET); // 해당 위치로 가서
write(fd, &current, sizeof(struct record)); // 더한 금액을 write
reclock(fd, record_no, sizeof(struct record), F_UNLCK); // 설정한 lock 해제
break;
case 'q': // quit (종료)
quit = TRUE;
break;
default:
printf("illegal input\n");
continue;
}
}
close(fd);
fflush(NULL);
}
int reclock(int fd, int recno, int len, int type) // lock에 대한 설정
{
struct flock fl;
switch (type)
{
case F_RDLCK:
case F_WRLCK:
case F_UNLCK:
fl.l_type = type;
fl.l_whence = SEEK_SET;
fl.l_start = recno * len;
fl.l_len = len;
fcntl(fd, F_SETLKW, &fl);
return 1;
default:
return -1;
}
}
void display_record(struct record *curr) // record 정보 출력 함수
{
printf("\n");
printf("id: %d \n", curr->id);
printf("name: %s \n", curr->name);
printf("balance: %d \n", curr->balance);
printf("\n");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment