1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
|
#include "svmsg_file.h"
#define TIMEOUT 10
static int clientId;
static void /* SIGALRM handler: interrupts blocked system call */
handler(int sig)
{
printf("msg Send timeout\n"); /* UNSAFE (see Section 21.1.2) */
}
static void
removeQueue(void)
{
if (msgctl(clientId, IPC_RMID, NULL) == -1)
errExit("msgctl");
}
void set_timeout(int num_secs) {
struct sigaction sa;
sa.sa_flags = 0;
sigemptyset(&sa.sa_mask);
sa.sa_handler = handler;
if (sigaction(SIGALRM, &sa, NULL) == -1)
errExit("sigaction");
alarm(num_secs);
}
void cancel_timeout() {
int savedErrno;
savedErrno = errno;
alarm(0); /* Ensure timer is turned off */
errno = savedErrno;
}
int
main(int argc, char *argv[])
{
struct requestMsg req;
struct responseMsg resp;
int serverId, numMsgs;
ssize_t msgLen, totBytes;
if (argc != 2 || strcmp(argv[1], "--help") == 0)
usageErr("%s pathname\n", argv[0]);
if (strlen(argv[1]) > sizeof(req.pathname) - 1)
cmdLineErr("pathname too long (max: %ld bytes)\n",
(long) sizeof(req.pathname) - 1);
/* Get server's queue identifier; create queue for response */
serverId = msgget(SERVER_KEY, S_IWUSR);
if (serverId == -1)
errExit("msgget - server message queue");
clientId = msgget(IPC_PRIVATE, S_IRUSR | S_IWUSR | S_IWGRP);
if (clientId == -1)
errExit("msgget - client message queue");
if (atexit(removeQueue) != 0)
errExit("atexit");
/* Send message asking for file named in argv[1] */
req.mtype = 1; /* Any type will do */
req.clientId = clientId;
strncpy(req.pathname, argv[1], sizeof(req.pathname) - 1);
req.pathname[sizeof(req.pathname) - 1] = '\0';
/* Ensure string is terminated */
set_timeout(TIMEOUT);
if (msgsnd(serverId, &req, REQ_MSG_SIZE, 0) == -1)
errExit("msgsnd");
cancel_timeout();
/* Get first response, which may be failure notification */
set_timeout(TIMEOUT);
msgLen = msgrcv(clientId, &resp, RESP_MSG_SIZE, 0, 0);
cancel_timeout();
if (msgLen == -1)
errExit("msgrcv");
if (resp.mtype == RESP_MT_FAILURE) {
printf("%s\n", resp.data); /* Display msg from server */
exit(EXIT_FAILURE);
}
/* File was opened successfully by server; process messages
(including the one already received) containing file data */
totBytes = msgLen; /* Count first message */
for (numMsgs = 1; resp.mtype == RESP_MT_DATA; numMsgs++) {
msgLen = msgrcv(clientId, &resp, RESP_MSG_SIZE, 0, 0);
// printf(resp.data);
if (msgLen == -1)
errExit("msgrcv");
totBytes += msgLen;
}
printf("Received %ld bytes (%d messages)\n", (long) totBytes, numMsgs);
exit(EXIT_SUCCESS);
}
|