1. 코드 분석
1. tlpi-dist/svipc/svmsg_demo_server.c
1. 코드
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <sys/stat.h>
#include "tlpi_hdr.h"
#define KEY_FILE "/some-path/some-file"
int
main(int argc, char *argv[])
{
int msqid;
key_t key;
const int MQ_PERMS = S_IRUSR | S_IWUSR | S_IWGRP;
key = ftok(KEY_FILE, 1);
if (key == -1)
errExit("ftok");
while ((msqid = msgget(key, IPC_CREAT | IPC_EXCL | MQ_PERMS)) ==
-1) {
if (errno == EEXIST) {
msqid = msgget(key, 0);
if (msqid == -1)
errExit("msgget() failed to retrieve old queue ID");
if (msgctl(msqid, IPC_RMID, NULL) == -1)
errExit("msgget() failed to delete old queue");
printf("Removed old message queue (id=%d)\n", msqid);
} else {
errExit("msgget() failed");
}
}
printf("Queue created with id %d\n", msqid);
exit(EXIT_SUCCESS);
}
2. 동작 모습

3. 디버깅 및 분석
2. tlpi-dist/svsem/svsem_demo.c
1. 코드
#include <sys/types.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include "curr_time.h"
#include "semun.h"
#include "tlpi_hdr.h"
int
main(int argc, char *argv[])
{
int semid;
if (argc < 2 || argc > 3 || strcmp(argv[1], "--help") == 0)
usageErr("%s init-value\n"
" or: %s semid operation\n", argv[0], argv[0]);
if (argc == 2) {
union semun arg;
semid = semget(IPC_PRIVATE, 1, S_IRUSR | S_IWUSR);
if (semid == -1)
errExit("semid");
arg.val = getInt(argv[1], 0, "init-value");
if (semctl(semid, 0, SETVAL, arg) == -1)
errExit("semctl");
printf("Semaphore ID = %d\n", semid);
} else {
struct sembuf sop;
semid = getInt(argv[1], 0, "semid");
sop.sem_num = 0;
sop.sem_op = getInt(argv[2], 0, "operation");
sop.sem_flg = 0;
printf("%ld: about to semop at %s\n", (long) getpid(), currTime("%T"));
if (semop(semid, &sop, 1) == -1)
errExit("semop");
printf("%ld: semop completed at %s\n", (long) getpid(), currTime("%T"));
}
exit(EXIT_SUCCESS);
}
2. 동작 모습

3. 디버깅 및 분석
3. tlpi-dist/svshm/svshm_xfr_writer.c
1. 코드
#include "semun.h"
#include "svshm_xfr.h"
int
main(int argc, char *argv[])
{
int semid, shmid, bytes, xfrs;
struct shmseg *shmp;
union semun dummy;
semid = semget(SEM_KEY, 2, IPC_CREAT | OBJ_PERMS);
if (semid == -1)
errExit("semget");
if (initSemAvailable(semid, WRITE_SEM) == -1)
errExit("initSemAvailable");
if (initSemInUse(semid, READ_SEM) == -1)
errExit("initSemInUse");
shmid = shmget(SHM_KEY, sizeof(struct shmseg), IPC_CREAT | OBJ_PERMS);
if (shmid == -1)
errExit("shmget");
shmp = shmat(shmid, NULL, 0);
if (shmp == (void *) -1)
errExit("shmat");
for (xfrs = 0, bytes = 0; ; xfrs++, bytes += shmp->cnt) {
if (reserveSem(semid, WRITE_SEM) == -1)
errExit("reserveSem");
shmp->cnt = read(STDIN_FILENO, shmp->buf, BUF_SIZE);
if (shmp->cnt == -1)
errExit("read");
if (releaseSem(semid, READ_SEM) == -1)
errExit("releaseSem");
if (shmp->cnt == 0)
break;
}
if (reserveSem(semid, WRITE_SEM) == -1)
errExit("reserveSem");
if (semctl(semid, 0, IPC_RMID, dummy) == -1)
errExit("semctl");
if (shmdt(shmp) == -1)
errExit("shmdt");
if (shmctl(shmid, IPC_RMID, NULL) == -1)
errExit("shmctl");
fprintf(stderr, "Sent %d bytes (%d xfrs)\n", bytes, xfrs);
exit(EXIT_SUCCESS);
}
2. 동작 모습

3. 디버깅 및 분석
4. tlpi-dist/svshm/svshm_xfr_reader.c
1. 코드
#include "svshm_xfr.h"
int
main(int argc, char *argv[])
{
int semid, shmid, xfrs, bytes;
struct shmseg *shmp;
semid = semget(SEM_KEY, 0, 0);
if (semid == -1)
errExit("semget");
shmid = shmget(SHM_KEY, 0, 0);
if (shmid == -1)
errExit("shmget");
shmp = shmat(shmid, NULL, SHM_RDONLY);
if (shmp == (void *) -1)
errExit("shmat");
for (xfrs = 0, bytes = 0; ; xfrs++) {
if (reserveSem(semid, READ_SEM) == -1)
errExit("reserveSem");
if (shmp->cnt == 0)
break;
bytes += shmp->cnt;
if (write(STDOUT_FILENO, shmp->buf, shmp->cnt) != shmp->cnt)
fatal("partial/failed write");
if (releaseSem(semid, WRITE_SEM) == -1)
errExit("releaseSem");
}
if (shmdt(shmp) == -1)
errExit("shmdt");
if (releaseSem(semid, WRITE_SEM) == -1)
errExit("releaseSem");
fprintf(stderr, "Received %d bytes (%d xfrs)\n", bytes, xfrs);
exit(EXIT_SUCCESS);
}
2. 동작 모습

3. 디버깅 및 분석