Mercurial > hg > RemoteEditor > vim7
annotate src/reditor.c @ 34:e170173ecb68 current-release
before ack base protocol.
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Wed, 26 Nov 2008 15:02:10 +0900 |
parents | 8d4ffb7c9f4e |
children | 2820e371ab4b |
rev | line source |
---|---|
8 | 1 #include <stdio.h> |
2 #include <stdlib.h> | |
3 #include <sys/types.h> | |
4 #include <sys/socket.h> | |
5 #include <netinet/in.h> | |
6 #include <netdb.h> | |
7 #include <unistd.h> | |
8 #include <errno.h> | |
9 | |
10 #include "vim.h" | |
11 #include "reditor.h" | |
12 | |
13 /* Global variables of Vim */ | |
14 #include "globals.h" | |
15 | |
16 /* Wrapper for Vim */ | |
17 static void e_msg_wrp(char *msg); | |
18 static void free_wrp(void *p); | |
19 static BUFTYPE* make_new_buf_wrp(char *name); | |
20 static void free_buf_wrp(BUFTYPE *buf); | |
21 static BUFTYPE* find_buf_by_name_wrp(char *name); | |
22 static void open_buffer_memline_wrp(BUFTYPE *buf); | |
23 static BUFTYPE* get_curbuf_wrp(); | |
24 static BUFTYPE* set_curbuf_wrp(BUFTYPE *buf); | |
25 static char* get_memline_wrp(BUFTYPE *buf, long lnum); | |
26 static int append_memline_wrp(long lnum, char *text); | |
27 static int delete_memline_wrp(long lnum); | |
28 static void update_screen_now_wrp(); | |
29 static char *get_fullpath_wrp(BUFTYPE *buf); | |
30 /* Wrapper END */ | |
31 | |
32 | |
33 static rep_T* get_rep(); | |
34 | |
35 static int rep_connect(char *host); | |
36 | |
37 static void rep_free(void *obj); | |
38 | |
39 static BUFTYPE* get_buf_by_name(char *name); | |
40 static Session* init_session(Session *sn); | |
41 static Session* make_session(char *name, BUFTYPE *buf); | |
42 static void free_session(Session *sn); | |
43 static void free_session_list(Session *head); | |
44 static Session* set_cursession(Session *sn); | |
45 static Session* find_session_by_buf(BUFTYPE *buf); | |
27 | 46 // static Session* find_session_by_name(char *name); |
8 | 47 static char* get_fullpath(Session *session); |
26 | 48 static Session * get_waiting_session(int sid, char *text) ; |
49 static void set_waiting_session(Session *session); | |
8 | 50 |
51 static int writen(int fd, char *textbuf, unsigned int len); | |
52 | |
53 static rep_cmd* make_cmd(unsigned int cmd, | |
54 unsigned int sid, | |
55 unsigned int eid, | |
56 unsigned int seq, | |
57 unsigned int lnum, | |
27 | 58 unsigned int length, |
8 | 59 char *text); |
27 | 60 static void forwardCommand(rep_T *rep, rep_cmd *command); |
61 static void set_cmd_seq( rep_cmd *command, unsigned int cmd, unsigned int seq); | |
62 | |
8 | 63 static int free_cmd(rep_cmd *cmd); |
64 static int free_cmdlist(rep_cmdlist *cmdlist); | |
65 static void add_cmd_to_list(rep_cmdlist *cmdlist, rep_cmd *cmd); | |
66 | |
67 static unsigned int get_header(char *buf,int offset); | |
68 static int set_header(unsigned int num, char *pkt, int offset); | |
69 | |
27 | 70 static int rep_exe_cmd(rep_cmd *command); |
8 | 71 static int rep_exe_pktlist(rep_cmdlist *cmdlist); |
72 | |
26 | 73 static int rep_recv_cmds(int fd, rep_cmdlist *txtcmdlist); |
8 | 74 static int rep_send_cmds(int fd, rep_cmdlist *cmdlist); |
19 | 75 static int rep_send_cmd( int fd, rep_cmd *cur); |
8 | 76 |
77 | |
78 /* g_rep has an all information of Remote Editor */ | |
26 | 79 static rep_T g_rep; |
8 | 80 |
28 | 81 int lock_editor = 0; |
82 | |
8 | 83 /* |
84 * Wrapper for vim | |
85 */ | |
86 | |
87 /* エラーメッセージ出力 */ | |
88 static void | |
89 e_msg_wrp(msg) | |
90 char * msg; | |
91 { | |
92 EMSG(msg); | |
93 } | |
94 | |
95 /* 通常のメッセージを出力 */ | |
19 | 96 void |
8 | 97 puts_msg_wrp(msg) |
98 char * msg; | |
99 { | |
100 MSG_PUTS(msg); | |
101 } | |
102 | |
103 static void | |
104 free_wrp(p) | |
105 void *p; | |
106 { | |
107 vim_free(p); | |
108 return; | |
109 } | |
110 | |
111 | |
112 /* 空の新しいバッファを取得 */ | |
113 static BUFTYPE * | |
114 make_new_buf_wrp(name) | |
115 char * name; | |
116 { | |
117 return buflist_new((char_u*)name, NULL, 0, BLN_LISTED); | |
118 } | |
119 | |
120 static void | |
121 free_buf_wrp(buf) | |
122 BUFTYPE *buf; | |
123 { | |
124 close_buffer(NULL, buf, DOBUF_DEL); | |
125 return; | |
126 } | |
127 | |
128 | |
129 /* 名前からバッファへのポインタを取得 */ | |
130 static BUFTYPE * | |
131 find_buf_by_name_wrp(name) | |
132 char * name; | |
133 { | |
134 char *sfname = NULL; // sfname is used name's address | |
14 | 135 |
136 BUFTYPE *buf = NULL; //??? | |
8 | 137 |
138 fname_expand(buf, (char_u**)&name, (char_u**)&sfname); | |
139 buf = buflist_findname((char_u*)name); | |
140 | |
141 free_wrp(name); | |
142 return buf; | |
143 } | |
144 | |
145 static void | |
146 open_buffer_memline_wrp(buf) | |
147 BUFTYPE *buf; | |
148 { | |
149 BUFTYPE *oldbuf; | |
150 oldbuf = curbuf; | |
151 curbuf = buf; | |
152 open_buffer(FALSE, NULL); | |
153 curbuf = oldbuf; | |
154 return; | |
155 } | |
156 | |
157 | |
158 /* 現在編集中のバッファへのポインタを取得 */ | |
159 extern BUFTYPE *curbuf; | |
160 static BUFTYPE * | |
161 get_curbuf_wrp() | |
162 { | |
163 return curbuf; | |
164 } | |
165 | |
166 /* buf を編集対象にする。 | |
167 *それまで編集対象だったバッファへのポインタを返す */ | |
168 static BUFTYPE * | |
169 set_curbuf_wrp(buf) | |
170 BUFTYPE *buf; | |
171 { | |
172 BUFTYPE *cb; | |
173 if (buf == NULL) | |
174 return NULL; | |
175 | |
176 cb = get_curbuf_wrp(); | |
177 set_curbuf(buf,DOBUF_GOTO); | |
178 | |
179 return cb; | |
180 } | |
181 | |
182 /* 指定した行番号の行のテキスト(文字列)のポインタを取得 */ | |
183 static char * | |
184 get_memline_wrp(buf, lnum) | |
185 BUFTYPE *buf; // buf is curbuf | |
186 long lnum; | |
187 { | |
188 return (char*)ml_get_buf(buf, lnum, FALSE); | |
189 } | |
190 | |
191 /* 編集中のバッファの行の挿入 */ | |
192 static int | |
193 append_memline_wrp(lnum, text) | |
194 long lnum; | |
195 char *text; | |
196 { | |
197 int r; | |
198 int permit; | |
199 rep_T *rep; | |
200 rep = get_rep(); | |
201 permit = rep->permit; | |
202 rep->permit = FALSE; | |
203 | |
28 | 204 r = ml_append(lnum, (char_u*)text, strlen(text)+1, FALSE); |
205 appended_lines_mark(lnum,1); | |
8 | 206 |
207 rep->permit = permit; | |
208 return r; | |
209 } | |
210 | |
28 | 211 /* 編集中のバッファの行数を返す */ |
212 long | |
213 get_bufmaxline_wrp(buf) | |
214 BUFTYPE *buf; | |
215 { | |
216 return buf->b_ml.ml_line_count; | |
217 } | |
218 | |
8 | 219 /* 編集中のバッファの行の削除 */ |
220 static int | |
221 delete_memline_wrp(lnum) | |
222 long lnum; | |
223 { | |
224 int r; | |
225 int permit; | |
226 rep_T *rep; | |
227 rep = get_rep(); | |
228 permit = rep->permit; | |
229 rep->permit = FALSE; | |
230 | |
28 | 231 int maxline = get_bufmaxline_wrp(get_curbuf_wrp()); |
232 if (lnum+1>maxline) return 0; | |
233 r = ml_delete(lnum+1, FALSE); | |
234 deleted_lines_mark(lnum+1,1); | |
8 | 235 |
236 rep->permit = permit; | |
237 return r; | |
238 } | |
239 | |
240 /* バッファの編集後の後処理 */ | |
241 static void | |
242 update_screen_now_wrp() | |
243 { | |
244 check_cursor(); | |
245 update_screen(CLEAR); | |
246 return; | |
247 } | |
248 | |
249 | |
250 /* get full path of buffer */ | |
251 static char * | |
252 get_fullpath_wrp(buf) | |
253 BUFTYPE *buf; | |
254 { | |
255 return (char*)buf->b_ffname; | |
256 } | |
257 | |
258 | |
259 /* Wrapper END */ | |
260 | |
261 | |
262 static void | |
263 puts_sys_err() | |
264 { | |
27 | 265 char *err = strerror(errno); |
266 char *errmsg = (char*)alloca(strlen(err)+50); | |
8 | 267 |
27 | 268 sprintf(errmsg, "rep>> %d:%s", errno, err); |
8 | 269 e_msg_wrp(errmsg); |
270 return; | |
271 } | |
272 | |
273 | |
274 static rep_T* | |
275 get_rep() | |
276 { | |
277 return(&g_rep); | |
278 } | |
279 | |
280 int | |
281 rep_permit() | |
282 { | |
283 return(g_rep.permit); | |
284 } | |
285 | |
286 int | |
287 rep_session_permit() | |
288 { | |
289 return(g_rep.permit && g_rep.cursession && g_rep.cursession->permit); | |
290 } | |
291 | |
292 void | |
293 rep_start_create_cmds() | |
294 { | |
295 if (g_rep.cursession) { | |
296 g_rep.cursession->permit = TRUE; | |
297 } | |
298 return; | |
299 } | |
300 | |
301 void | |
302 rep_stop_create_cmds() | |
303 { | |
304 if (g_rep.cursession) { | |
305 g_rep.cursession->permit = FALSE; | |
306 } | |
307 return; | |
308 } | |
309 | |
310 | |
311 int | |
312 rep_init() | |
313 { | |
314 /* | |
315 * g_rep is global variable and it is zero cleared. | |
316 */ | |
317 | |
318 char def_hostname[] = "localhost"; | |
319 | |
320 // 現在編集対象のバッファはセッションに加える? | |
26 | 321 g_rep.shead = NULL; |
8 | 322 |
323 g_rep.cursession = NULL; | |
324 g_rep.servername = NULL; | |
26 | 325 g_rep.waiting_session = NULL; |
8 | 326 |
327 g_rep.smfd = -1; | |
328 | |
329 g_rep.eid = 0; | |
330 g_rep.seqno = 0; | |
26 | 331 g_rep.prevSeq = 0; |
332 g_rep.syncMode = 0; | |
8 | 333 |
334 g_rep.permit = FALSE; | |
25 | 335 |
336 #ifndef HOST_NAME_MAX | |
337 #define HOST_NAME_MAX 255 | |
338 #endif | |
339 g_rep.hostname = (char *)malloc(HOST_NAME_MAX); | |
8 | 340 if (gethostname(g_rep.hostname, sizeof(g_rep.hostname)) < 0) { |
341 strncpy(g_rep.hostname, def_hostname, sizeof(def_hostname)+1); | |
342 } | |
27 | 343 g_rep.nop = make_cmd(REPCMD_NOP, 0, 0, 0, 0, 0, ""); |
8 | 344 |
25 | 345 return TRUE; |
8 | 346 } |
347 | |
348 | |
349 static char default_host[] = "localhost"; | |
350 | |
351 static int | |
352 rep_connect(host) | |
353 char *host; /* "hostname:portnumber" */ | |
354 { | |
355 int sock; | |
356 struct hostent *hp; | |
357 struct sockaddr_in sin; | |
358 char *tmp; | |
359 int port; | |
360 | |
14 | 361 if (host == NULL || *host == '\n') { |
8 | 362 host = default_host; |
363 port = REP_PORT; | |
364 } else { | |
365 if ((tmp = strchr(host, ':')) == NULL ) { | |
366 return(-1); | |
367 } | |
368 *tmp = '\0'; | |
369 tmp++; | |
370 port = atol(tmp); | |
371 } | |
372 | |
373 if ((hp = gethostbyname(host)) == NULL) { | |
374 e_msg_wrp("rep_open: gethostbyname: ERROR"); | |
375 return(-1); | |
376 } | |
377 | |
378 if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) { | |
379 e_msg_wrp("rep_open: socket : ERROR"); | |
380 return(-1); | |
381 } | |
382 | |
383 bzero(&sin, sizeof(sin)); | |
384 sin.sin_family = AF_INET; | |
385 sin.sin_port = htons(port); | |
386 bcopy(hp->h_addr, &sin.sin_addr, hp->h_length); | |
387 | |
388 if (connect(sock, (struct sockaddr *)&sin, sizeof(sin)) < 0) { | |
389 e_msg_wrp("rep_open: connect: ERROR"); | |
390 return(-1); | |
391 } | |
392 | |
393 return(sock); | |
394 } | |
395 | |
396 | |
397 static BUFTYPE * | |
398 get_buf_by_name(name) | |
399 char *name; | |
400 { | |
401 BUFTYPE *buf; | |
402 if ((buf = find_buf_by_name_wrp(name)) == NULL) { | |
403 buf = make_new_buf_wrp(name); | |
404 } | |
405 | |
406 if (buf && (buf->b_ml.ml_mfp == NULL)) { | |
407 open_buffer_memline_wrp(buf); | |
408 } | |
409 | |
410 return buf; | |
411 } | |
412 | |
413 | |
414 /* About Session */ | |
415 | |
416 static Session * | |
417 init_session(sn) | |
418 Session *sn; | |
419 { | |
420 sn->next = NULL; | |
421 sn->buf = NULL; | |
422 sn->sname = NULL; | |
423 sn->new_cmdlist.head = NULL; | |
424 sn->new_cmdlist.num = 0; | |
425 sn->sent_cmdlist.head = NULL; | |
426 sn->sent_cmdlist.num = 0; | |
427 sn->sid = 0; | |
428 sn->permit = FALSE; | |
429 sn->prevline = -1; | |
26 | 430 sn->del_cmd = 0; |
8 | 431 |
432 return sn; | |
433 } | |
434 | |
435 /* | |
436 * Make a new session. | |
437 * if buf is NULL, buffer is found or made new one. | |
438 */ | |
439 static Session * | |
440 make_session(name, buf) | |
441 char *name; | |
442 BUFTYPE *buf; | |
443 { | |
444 Session *s; | |
445 | |
446 char *sname; | |
447 int namelen = strlen(name)+1; | |
448 | |
25 | 449 s = (Session*)malloc(sizeof(Session)); |
8 | 450 if (s == NULL) { |
451 return(NULL); | |
452 } | |
453 | |
25 | 454 if ((sname = (char*)malloc(namelen)) == NULL) { |
8 | 455 return NULL; |
456 } | |
457 strncpy(sname,name,namelen); | |
458 | |
459 init_session(s); | |
460 | |
461 if (buf == NULL) buf = get_buf_by_name(sname); | |
462 s->buf = buf; | |
463 | |
464 s->sname = sname; | |
465 | |
466 return s; | |
467 } | |
468 | |
469 static void | |
470 free_session(sn) | |
471 Session *sn; | |
472 { | |
473 | |
474 free_cmdlist(&sn->new_cmdlist); | |
475 free_cmdlist(&sn->sent_cmdlist); | |
476 free_buf_wrp(sn->buf); | |
477 | |
478 if (sn->sname) rep_free(sn->sname); | |
479 | |
480 init_session(sn); | |
481 | |
482 rep_free(sn); | |
483 return; | |
484 } | |
485 | |
486 static void | |
487 free_session_list(head) | |
488 Session *head; | |
489 { | |
490 Session *next; | |
491 for (; head; head=next) { | |
492 next = head->next; | |
493 head->next = NULL; | |
494 free_session(head); | |
495 } | |
496 return; | |
497 } | |
498 | |
26 | 499 static Session * |
500 get_waiting_session(int sid, char *text) { | |
501 rep_T *rep = get_rep(); | |
502 Session *session = rep->waiting_session; | |
503 if (session==NULL) return session; | |
504 rep->waiting_session = session->next; | |
505 session->sid = sid; | |
506 if (text!=0) { | |
507 // set session name to the buffer | |
508 update_screen_now_wrp(); | |
509 } | |
510 return session; | |
511 } | |
512 | |
8 | 513 static Session* |
514 set_cursession(sn) | |
515 Session *sn; | |
516 { | |
14 | 517 BUFTYPE *oldbuf = NULL; |
8 | 518 Session *oldsn; |
519 rep_T *rep = get_rep(); | |
520 | |
521 if (sn) oldbuf = set_curbuf_wrp(sn->buf); | |
522 rep->cursession = sn; | |
523 | |
524 oldsn = find_session_by_buf(oldbuf); | |
525 return oldsn; | |
526 } | |
527 | |
528 static Session* | |
529 find_session_by_id(id) | |
530 unsigned int id; | |
531 { | |
532 Session *cursn = NULL; | |
533 rep_T *rep = get_rep(); | |
534 | |
535 for (cursn = rep->shead; cursn; cursn = cursn->next) { | |
536 if (cursn->sid == id) { | |
537 return cursn; | |
538 } | |
539 } | |
540 | |
541 return NULL; | |
542 } | |
543 | |
544 static Session* | |
545 find_session_by_buf(buf) | |
546 BUFTYPE *buf; | |
547 { | |
548 Session *cursn = NULL; | |
549 rep_T *rep = get_rep(); | |
550 | |
551 if (buf == NULL) return NULL; | |
552 | |
553 for (cursn = rep->shead; cursn; cursn = cursn->next) { | |
554 if (cursn->buf == buf) break; | |
555 } | |
556 return cursn; | |
557 } | |
558 | |
27 | 559 /* |
8 | 560 static Session* |
561 find_session_by_name(name) | |
562 char *name; | |
563 { | |
564 BUFTYPE *buf; | |
565 buf = find_buf_by_name_wrp(name); | |
566 return find_session_by_buf(buf); | |
567 } | |
27 | 568 */ |
8 | 569 |
570 | |
571 static char* | |
572 get_fullpath(session) | |
573 Session *session; | |
574 { | |
575 BUFTYPE *buf; | |
576 if (session == NULL) { | |
577 buf = get_curbuf_wrp(); | |
578 } else { | |
579 buf = session->buf; | |
580 } | |
581 return get_fullpath_wrp(buf); | |
582 } | |
583 | |
26 | 584 static Session * |
585 append_session(Session *s1,Session *s2) | |
586 { | |
587 Session *s3=s1; | |
588 if (s1==NULL) return s2; | |
589 while(s1->next) s1 = s1->next; | |
590 s1->next = s2; | |
591 return s3; | |
592 } | |
593 | |
594 static void | |
595 set_waiting_session(Session *session) | |
596 { | |
597 rep_T *rep = get_rep(); | |
598 rep->waiting_session = append_session(rep->waiting_session,session); | |
599 } | |
8 | 600 |
601 /* End Session */ | |
602 | |
26 | 603 static int |
604 rep_join_put(int cmd) | |
8 | 605 { |
606 int sock; | |
607 rep_T *rep; | |
608 | |
609 rep = get_rep(); | |
610 if ((sock = rep_connect(NULL)) < 0) { | |
611 return FALSE; | |
612 } | |
613 if (rep->smfd > 0) { | |
614 close(rep->smfd); | |
615 } | |
616 | |
617 rep->smfd = sock; | |
618 rep->permit = TRUE; | |
26 | 619 |
620 /* get current buffer name */ | |
621 char *sname; | |
622 if ((sname = get_fullpath(rep->cursession)) == NULL) { | |
623 sname =NO_NAME; /* the buffer has not name */ | |
624 } | |
625 BUFTYPE *buf = get_curbuf_wrp(); | |
626 Session *session = make_session(sname,buf); | |
627 set_waiting_session(session); | |
628 | |
8 | 629 |
27 | 630 rep_cmd *command = make_cmd(cmd, 0, rep->eid, rep->seqno++, 0, 0, ""); |
631 forwardCommand(rep, command); | |
632 free_cmd(command); | |
8 | 633 |
634 return TRUE; | |
635 | |
636 } | |
637 | |
26 | 638 int rep_join() |
639 { | |
640 return rep_join_put(SMCMD_JOIN); | |
641 } | |
642 | |
8 | 643 int |
19 | 644 rep_put() |
8 | 645 { |
26 | 646 return rep_join_put(SMCMD_PUT); |
8 | 647 } |
648 | |
649 int | |
650 rep_remove() | |
651 { | |
652 rep_T *rep = get_rep(); | |
653 rep_cmd *cmd; | |
654 Session *sn = rep->cursession; | |
655 | |
656 if (rep->smfd < 0) { /* session does not exist */ | |
657 EMSG("Session does not exist."); | |
658 return FALSE; | |
659 } | |
660 | |
27 | 661 cmd = make_cmd(REPCMD_CLOSE, sn->sid, rep->eid, rep->seqno, 0, 0, ""); |
662 forwardCommand(rep,cmd); | |
663 free_cmd(cmd); | |
8 | 664 |
665 return TRUE; | |
666 } | |
667 | |
668 | |
669 | |
670 /* Session End */ | |
671 | |
672 static void | |
673 rep_free(obj) | |
674 void *obj; | |
675 { | |
27 | 676 if (obj) vim_free(obj); |
8 | 677 return; |
678 } | |
679 | |
680 | |
681 static int | |
682 writen(sock, pkt, len) | |
683 int sock; | |
684 char *pkt; | |
685 unsigned int len; | |
686 { | |
687 int offset; | |
688 int written; | |
689 | |
690 if (len == 0) return 0; | |
691 | |
692 for (offset=0, written=0; offset<len; offset += written) { | |
693 if ((written = write(sock, pkt + offset, len - offset)) < 0) { | |
694 puts_sys_err(); | |
695 return written; | |
696 } | |
697 } | |
698 return offset; | |
699 } | |
700 | |
701 static int | |
702 readn(sock, pkt, len) | |
703 int sock; | |
704 char *pkt; | |
705 unsigned int len; | |
706 { | |
707 unsigned int r; | |
708 unsigned int offset; | |
709 | |
710 if (len == 0) return 0; | |
711 | |
712 for (offset=0, r=0; offset<len; offset += r) { | |
713 if ((r = read(sock, pkt + offset, len - offset)) < 0) { | |
714 puts_sys_err(); | |
715 return r; | |
29 | 716 } else if (r==0) return 0; |
8 | 717 } |
718 return offset; | |
719 } | |
720 | |
721 | |
27 | 722 static void |
723 make_packet(command, cmd, sid, eid, seq, lnum, len, text) | |
724 rep_cmd *command; | |
8 | 725 unsigned int cmd; |
726 unsigned int sid; | |
727 unsigned int eid; | |
728 unsigned int seq; | |
729 unsigned int lnum; | |
27 | 730 unsigned int len; |
8 | 731 char * text; |
732 { | |
27 | 733 char *packet = &command->pkt[0]; |
734 set_header(cmd, packet, REP_CMD_OFFSET); | |
735 set_header(sid, packet, REP_SID_OFFSET); | |
736 set_header(eid, packet, REP_EID_OFFSET); | |
737 set_header(seq, packet, REP_SEQNUM_OFFSET); | |
738 set_header(lnum, packet, REP_LNUM_OFFSET); | |
739 set_header(len, packet, REP_T_SIZE_OFFSET); | |
8 | 740 |
27 | 741 if (text && len>0) { |
8 | 742 memcpy(packet+REP_TEXT_OFFSET, text, len); |
743 } | |
27 | 744 return; |
8 | 745 } |
746 | |
747 | |
748 static rep_cmd* | |
27 | 749 make_cmd(cmd, sid, eid, seq, lnum, length, text) |
8 | 750 unsigned int cmd; |
751 unsigned int sid; | |
752 unsigned int eid; | |
753 unsigned int seq; | |
754 unsigned int lnum; | |
27 | 755 unsigned int length; |
8 | 756 char *text; |
757 { | |
758 rep_cmd *cmd_p; | |
27 | 759 cmd_p = (rep_cmd*)malloc(sizeof(rep_cmd)+REP_HEADER_SIZE+length); |
760 if (cmd_p == NULL) return(NULL); | |
8 | 761 cmd_p->next = NULL; |
762 cmd_p->cmd = cmd; | |
763 cmd_p->sid = sid; | |
764 cmd_p->eid = eid; | |
765 cmd_p->seq = seq; | |
766 cmd_p->len = length; | |
767 cmd_p->lnum = lnum; | |
27 | 768 make_packet(cmd_p, cmd, sid, eid, seq, lnum, length, text); |
769 return(cmd_p); | |
770 } | |
8 | 771 |
27 | 772 static void |
773 set_cmd_seq(cmd_p,cmd,seq) | |
774 rep_cmd *cmd_p; | |
775 unsigned int cmd; | |
776 unsigned int seq; | |
777 { | |
778 char *packet = &cmd_p->pkt[0]; | |
779 cmd_p->seq = seq; | |
780 cmd_p->cmd = cmd; | |
781 set_header(cmd, packet, REP_CMD_OFFSET); | |
782 set_header(seq, packet, REP_SEQNUM_OFFSET); | |
8 | 783 } |
784 | |
785 static int | |
786 free_cmd(cmd) | |
787 rep_cmd *cmd; | |
788 { | |
789 if (cmd == NULL) return(FALSE); | |
790 rep_free(cmd); | |
791 return(TRUE); | |
792 } | |
793 | |
794 static int | |
795 free_cmdlist(cmdlist) | |
796 rep_cmdlist *cmdlist; | |
797 { | |
798 rep_cmd *cur; | |
799 rep_cmd *next; | |
800 | |
801 if (cmdlist->head==NULL) return(FALSE); | |
802 for (cur=cmdlist->head; cur; cur=next) { | |
803 next=cur->next; | |
804 free_cmd(cur); | |
805 } | |
806 cmdlist->head = NULL; | |
807 cmdlist->num = 0; | |
808 return(TRUE); | |
809 } | |
810 | |
811 static void | |
812 add_cmd_to_list(cmdlist, cmd) | |
813 rep_cmdlist *cmdlist; | |
814 rep_cmd *cmd; | |
815 { | |
816 rep_cmd *p; | |
817 int count = 0; | |
818 | |
819 for (p=cmd; p; p=p->next) count++; | |
820 | |
821 if (cmdlist->head) { | |
822 for (p = cmdlist->head; p->next; p = p->next); | |
823 p->next = cmd; | |
824 } else { | |
825 cmdlist->head = cmd; | |
826 } | |
827 cmdlist->num += count; | |
828 return; | |
829 } | |
830 | |
831 | |
19 | 832 /* |
833 Before any line changes, keep the lines as DELETE_LINE_CMD. | |
834 | |
835 xtr==0 ml_replace | |
836 xtr==1 ml_append | |
837 xtr==-1 ml_delete | |
838 */ | |
8 | 839 void |
19 | 840 rep_prevline_flush(int lnum, int xtr) |
8 | 841 { |
842 BUFTYPE *cbuf; | |
843 Session *cursn; | |
844 rep_cmd *cmd; | |
845 rep_T *rep = get_rep(); | |
15 | 846 |
8 | 847 cursn = rep->cursession; |
848 | |
28 | 849 if (cursn == NULL) |
19 | 850 return; |
8 | 851 |
852 // バッファが変更された場合には rep->cursession も合わす | |
853 if ((cbuf = get_curbuf_wrp()) != cursn->buf) { | |
854 cursn = find_session_by_buf(cbuf); | |
855 if (cursn == NULL) | |
856 return; | |
857 rep->cursession = cursn; | |
858 } | |
859 | |
19 | 860 if(cursn->prevline!=lnum&&xtr!=0) { |
861 if (cursn->del_cmd) { | |
862 // Cancel delete cmd | |
863 rep_free(cursn->del_cmd); | |
864 cursn->del_cmd = 0; | |
865 } | |
8 | 866 } |
19 | 867 cursn->prevline=lnum; |
868 if (xtr<0) { | |
869 // ml_delete case | |
27 | 870 char *text = get_memline_wrp(cursn->buf, lnum); |
871 unsigned int length = strlen(text); | |
872 cmd = make_cmd(REPCMD_DELETE, cursn->sid, rep->eid, rep->seqno++, | |
28 | 873 cursn->prevline-1, length, text); |
19 | 874 rep_send_cmd(rep->smfd,cmd); |
875 rep_free(cmd); | |
28 | 876 if (cursn->del_cmd) { |
877 // Cancel delete cmd | |
878 rep_free(cursn->del_cmd); | |
879 cursn->del_cmd = 0; | |
880 } | |
19 | 881 } else if (xtr==0) { |
882 // ml_replace case | |
883 if (cursn->del_cmd) | |
884 return; // already line saved do nothing | |
27 | 885 char *text = get_memline_wrp(cursn->buf, lnum); |
886 unsigned int length = strlen(text); | |
887 cursn->del_cmd = make_cmd(REPCMD_DELETE, cursn->sid, rep->eid, | |
28 | 888 rep->seqno++, cursn->prevline-1, length, text); |
19 | 889 |
890 } else { | |
891 // ml_append case | |
892 // do nothing | |
893 } | |
8 | 894 } |
895 | |
28 | 896 /* |
897 * channged_common から呼ばれて、変更をREP commandに直して | |
898 * 送信する。 | |
899 */ | |
19 | 900 void |
8 | 901 rep_register(lnum, lnume, xtra) |
902 unsigned int lnum; | |
903 unsigned int lnume; | |
904 int xtra; | |
905 { | |
906 int i; | |
907 BUFTYPE *cbuf; | |
908 Session *cursn; | |
909 rep_cmd *cmd; | |
910 rep_T *rep = get_rep(); | |
911 | |
19 | 912 if ((cursn = rep->cursession) == NULL) return ; |
8 | 913 |
914 // バッファが変更された場合には rep->cursession も合わす | |
915 if ((cbuf = get_curbuf_wrp()) != cursn->buf) { | |
916 cursn = find_session_by_buf(cbuf); | |
917 if (cursn == NULL) | |
19 | 918 return ; |
8 | 919 rep->cursession = cursn; |
920 } | |
19 | 921 if (xtra<0) { |
922 // delete case, the command was sent, do nothing | |
24 | 923 cursn->prevline=-1; |
19 | 924 } else if (xtra>0) { |
925 // append case | |
926 | |
29 | 927 for(i=lnum;i<lnum+xtra;i++) { |
928 char *text = get_memline_wrp(cursn->buf, i); | |
27 | 929 unsigned int length = strlen(text); |
19 | 930 // make INSERT_CMD for insert or changed lines if any |
27 | 931 cmd = make_cmd(REPCMD_INSERT, cursn->sid, rep->eid, rep->seqno++, |
29 | 932 i-1, length, text); |
27 | 933 rep_send_cmd(rep->smfd,cmd); |
934 free_cmd(cmd); | |
19 | 935 } |
24 | 936 cursn->prevline=-1; |
19 | 937 } else if (xtra==0) { |
938 // replace case | |
15 | 939 |
19 | 940 // send saved DELETE command |
20 | 941 if (cursn->del_cmd!=0) { |
942 cmd = cursn->del_cmd; | |
943 rep_send_cmd(rep->smfd,cmd); | |
27 | 944 rep_free(cmd); cmd=0; |
20 | 945 cursn->del_cmd = 0; |
946 } else { | |
947 // first insert case? | |
948 } | |
24 | 949 cursn->prevline = lnum; |
19 | 950 |
951 // send saved new line as INSERT command | |
27 | 952 char *text = get_memline_wrp(cursn->buf, lnum); |
953 unsigned int length = strlen(text); | |
954 cmd = make_cmd(REPCMD_INSERT, cursn->sid, rep->eid, rep->seqno++, | |
28 | 955 cursn->prevline-1, length,text); |
19 | 956 rep_send_cmd(rep->smfd,cmd); |
27 | 957 // reuse cmd |
19 | 958 // save current line for next replace |
27 | 959 set_cmd_seq(cmd,REPCMD_DELETE,rep->seqno++); |
960 cursn->del_cmd = cmd; | |
8 | 961 } |
962 | |
963 } | |
964 | |
31 | 965 static int |
966 rep_sync() | |
967 { | |
968 Session *cursn; | |
969 rep_T *rep = get_rep(); | |
970 if ((cursn = rep->cursession) == NULL) return 0; | |
971 if (rep->syncMode!=0) { | |
972 char *text = get_memline_wrp(cursn->buf, rep->syncMode); | |
973 unsigned int length = strlen(text); | |
974 rep_cmd *cmd = make_cmd(REPCMD_DELETE, cursn->sid, rep->eid, | |
975 rep->seqno++, | |
976 rep->syncMode, length,text); | |
977 rep_send_cmd(rep->smfd,cmd); | |
978 // reuse cmd | |
979 // save current line for next replace | |
980 set_cmd_seq(cmd,REPCMD_INSERT,rep->seqno++); | |
981 rep_send_cmd(rep->smfd,cmd); | |
982 free_cmd(cmd); | |
983 if (rep->syncMode < get_bufmaxline_wrp(cursn->buf)) { | |
984 rep->syncMode++; | |
985 } else { | |
986 rep->syncMode=0; | |
987 } | |
988 return 1; | |
989 } | |
990 return 0; | |
991 } | |
8 | 992 |
993 static int | |
994 set_header(data, pkt, offset) | |
995 unsigned int data; | |
996 char *pkt; | |
997 int offset; | |
998 { | |
999 int *ipkt; | |
1000 int ndata = htonl(data); | |
1001 | |
1002 ipkt = (int*)pkt; | |
1003 ipkt[offset/4] = ndata; | |
1004 | |
1005 return(TRUE); | |
1006 } | |
1007 | |
1008 static unsigned int | |
1009 get_header(pkt, offset) | |
1010 char *pkt; | |
1011 int offset; | |
1012 { | |
1013 int *ipkt; | |
1014 int data; | |
1015 unsigned int header; | |
1016 | |
1017 ipkt = (int *)pkt; | |
1018 data = ipkt[offset/4]; | |
1019 header = (unsigned int)ntohl(data); | |
1020 | |
1021 return(header); | |
1022 } | |
1023 | |
25 | 1024 /* |
1025 REP command packet flow | |
1026 | |
1027 Own change | |
1028 | |
1029 CMD ------> session manager | |
1030 session manager <--- CMD command return | |
1031 <------ MERGE_START (block user input) | |
1032 <------ Merge fix from session manager | |
1033 CMD ------> session manager return same command as ack | |
1034 <------ MERGE_END command return | |
1035 (enable user input) | |
1036 | |
1037 session manager <--- CMD incomming external command | |
1038 NOP ------> session manager if we have sent any command | |
1039 CMD ------> session manager return same command as ack | |
1040 | |
1041 */ | |
1042 | |
1043 static void | |
1044 forwardCommand(rep_T *rep, rep_cmd *command) | |
1045 { | |
1046 int fd = rep->smfd; | |
1047 writen(fd,command->pkt,command->len+REP_HEADER_SIZE); | |
1048 } | |
1049 | |
1050 static void | |
1051 incrementSeq(rep_T *rep) | |
1052 { | |
1053 rep->seqno++; | |
1054 } | |
1055 | |
1056 static void | |
28 | 1057 addNop(int sid, rep_T *rep) |
25 | 1058 { |
1059 int fd = rep->smfd; | |
28 | 1060 char *packet = &rep->nop->pkt[0]; |
25 | 1061 |
1062 if (rep->prevSeq==rep->seqno) { | |
28 | 1063 set_header(sid, packet, REP_SID_OFFSET); |
25 | 1064 set_header(rep->eid, packet, REP_EID_OFFSET); |
1065 set_header(rep->seqno, packet, REP_SEQNUM_OFFSET); | |
1066 rep->prevSeq = rep->seqno; | |
1067 incrementSeq(rep); | |
1068 writen(fd,rep->nop->pkt,rep->nop->len+REP_HEADER_SIZE); | |
1069 } | |
1070 } | |
8 | 1071 |
1072 static int | |
27 | 1073 rep_exe_cmd(command) |
25 | 1074 rep_cmd *command; |
8 | 1075 { |
27 | 1076 char *text = command->pkt+REP_TEXT_OFFSET; |
1077 int eid = command->eid; | |
8 | 1078 rep_T *rep = get_rep(); |
1079 Session *session; | |
1080 | |
27 | 1081 session = find_session_by_id(command->sid); |
8 | 1082 |
27 | 1083 switch (command->cmd) { |
25 | 1084 case SMCMD_JOIN_ACK: |
27 | 1085 { |
1086 session = get_waiting_session(command->sid,text); | |
26 | 1087 set_cursession(session); |
15 | 1088 rep_start_create_cmds(); |
27 | 1089 rep->eid = command->eid; |
1090 | |
1091 char *msg = alloca(150); | |
1092 sprintf(msg,"joined eid=%d sid=%d",rep->eid,session->sid); | |
1093 e_msg_wrp(msg); | |
28 | 1094 |
1095 rep->prevSeq = rep->seqno; | |
27 | 1096 } |
1097 | |
8 | 1098 break; |
26 | 1099 |
25 | 1100 case SMCMD_PUT_ACK: |
27 | 1101 { |
8 | 1102 /* Enter Session */ |
27 | 1103 session = get_waiting_session(command->sid,text); |
8 | 1104 /* set session to cursession */ |
1105 set_cursession(session); | |
1106 rep_start_create_cmds(); | |
27 | 1107 rep->eid = command->eid; |
1108 | |
1109 char *msg = alloca(150); | |
1110 sprintf(msg,"put eid=%d sid=%d",rep->eid,session->sid); | |
1111 e_msg_wrp(msg); | |
28 | 1112 |
1113 rep->prevSeq = rep->seqno; | |
27 | 1114 } |
1115 | |
8 | 1116 break; |
25 | 1117 case REPCMD_INSERT: |
27 | 1118 append_memline_wrp(command->lnum, text); |
28 | 1119 if (eid!=MERGE_EID) addNop(command->sid, rep); |
25 | 1120 forwardCommand(rep,command); |
26 | 1121 if (eid!=MERGE_EID) update_screen_now_wrp(); |
8 | 1122 break; |
25 | 1123 case REPCMD_DELETE: |
27 | 1124 delete_memline_wrp(command->lnum); |
26 | 1125 if (eid!=MERGE_EID) update_screen_now_wrp(); |
25 | 1126 case REPCMD_NOP: |
28 | 1127 if (eid!=MERGE_EID) addNop(command->sid, rep); |
25 | 1128 forwardCommand(rep,command); |
8 | 1129 break; |
25 | 1130 case SMCMD_SYNC: |
34
e170173ecb68
before ack base protocol.
Shinji KONO <kono@ie.u-ryukyu.ac.jp>
parents:
31
diff
changeset
|
1131 // rep->syncMode = 1; |
27 | 1132 set_cmd_seq(command,SMCMD_SYNC_ACK,rep->seqno++); |
1133 forwardCommand(rep,command); | |
25 | 1134 break; |
1135 case SMCMD_QUIT: | |
1136 forwardCommand(rep,command); | |
1137 break; | |
1138 case SMCMD_START_MERGE: | |
28 | 1139 lock_editor = 1; |
1140 set_cmd_seq(command,SMCMD_START_MERGE_ACK,rep->seqno++); | |
1141 forwardCommand(rep,command); | |
25 | 1142 break; |
1143 case SMCMD_END_MERGE: | |
28 | 1144 lock_editor = 0; |
25 | 1145 rep->prevSeq = rep->seqno; |
26 | 1146 update_screen_now_wrp(); |
8 | 1147 default: |
1148 break; | |
1149 } | |
27 | 1150 free_cmd(command); |
8 | 1151 return(TRUE); |
1152 } | |
1153 | |
1154 | |
1155 /* execute command list based cmd packet */ | |
1156 static int | |
1157 rep_exe_pktlist(cmdlist) | |
1158 rep_cmdlist *cmdlist; | |
1159 { | |
1160 rep_cmd *repcmd; | |
1161 | |
1162 if ((cmdlist == NULL) || (cmdlist->head == NULL)) { | |
1163 return(FALSE); | |
1164 } | |
1165 | |
1166 for (repcmd = cmdlist->head; repcmd; repcmd = repcmd->next) { | |
27 | 1167 rep_exe_cmd(repcmd); |
8 | 1168 } |
1169 | |
1170 return(TRUE); | |
1171 } | |
1172 | |
1173 | |
1174 | |
1175 static int | |
26 | 1176 rep_recv_cmds(fd, txtcmdlist) |
8 | 1177 int fd; |
1178 rep_cmdlist *txtcmdlist; | |
1179 { | |
1180 unsigned int cmd; | |
1181 unsigned int sid; | |
1182 unsigned int eid; | |
1183 unsigned int seq; | |
1184 unsigned int lnum; | |
1185 unsigned int textsize; | |
27 | 1186 rep_cmd *cmd_p ; |
1187 char *text; | |
1188 char *header; | |
8 | 1189 |
1190 if (fd < 0) { | |
1191 return(FALSE); | |
1192 } | |
27 | 1193 if ((cmd_p = (rep_cmd *)malloc(sizeof(rep_cmd)+128)) == NULL) |
1194 return FALSE; | |
1195 | |
1196 text = &cmd_p->pkt[REP_TEXT_OFFSET]; | |
1197 header = &cmd_p->pkt[0]; | |
8 | 1198 |
1199 /* read header part */ | |
29 | 1200 if (readn(fd, header, REP_HEADER_SIZE) <= 0) { |
8 | 1201 puts_sys_err(); |
1202 return(FALSE); | |
1203 } | |
1204 | |
1205 cmd = get_header(header, REP_CMD_OFFSET); | |
1206 sid = get_header(header, REP_SID_OFFSET); | |
1207 eid = get_header(header, REP_EID_OFFSET); | |
1208 seq = get_header(header, REP_SEQNUM_OFFSET); | |
1209 lnum = get_header(header, REP_LNUM_OFFSET); | |
1210 textsize = get_header(header, REP_T_SIZE_OFFSET); | |
27 | 1211 if ((cmd_p = (rep_cmd *)realloc(cmd_p,sizeof(rep_cmd)+textsize)) == NULL) |
1212 return FALSE; | |
8 | 1213 |
1214 if (textsize > 0) { | |
1215 /* read text part */ | |
29 | 1216 if (readn(fd, text, textsize) <= 0) { |
8 | 1217 puts_sys_err(); |
27 | 1218 rep_free(cmd_p); |
8 | 1219 return(FALSE); |
1220 } | |
21 | 1221 text[textsize] = 0; |
8 | 1222 } |
27 | 1223 cmd_p->next = NULL; |
1224 cmd_p->cmd = cmd; | |
1225 cmd_p->sid = sid; | |
1226 cmd_p->eid = eid; | |
1227 cmd_p->seq = seq; | |
1228 cmd_p->len = textsize; | |
1229 cmd_p->lnum = lnum; | |
8 | 1230 |
27 | 1231 add_cmd_to_list(txtcmdlist, cmd_p); |
8 | 1232 return(TRUE); |
1233 } | |
1234 | |
1235 void | |
1236 rep_send_cur_cmdlist() | |
1237 { | |
1238 rep_T *rep_p = get_rep(); | |
1239 | |
1240 rep_send_cmds(rep_p->smfd,&(rep_p->cursession->new_cmdlist)); | |
1241 | |
1242 free_cmdlist(&rep_p->cursession->sent_cmdlist); | |
1243 | |
1244 rep_p->cursession->sent_cmdlist.head = rep_p->cursession->new_cmdlist.head; | |
1245 rep_p->cursession->sent_cmdlist.num = rep_p->cursession->new_cmdlist.num; | |
1246 | |
1247 rep_p->cursession->new_cmdlist.head = NULL; | |
1248 rep_p->cursession->new_cmdlist.num = 0; | |
1249 | |
1250 return; | |
1251 } | |
1252 | |
1253 static int | |
19 | 1254 rep_send_cmd(fd,cur) |
1255 int fd; | |
1256 rep_cmd *cur; | |
1257 { | |
20 | 1258 return writen(fd,cur->pkt,cur->len+REP_HEADER_SIZE ); |
19 | 1259 } |
1260 | |
1261 static int | |
8 | 1262 rep_send_cmds(fd,cmdlist) |
1263 int fd; | |
1264 rep_cmdlist *cmdlist; | |
1265 { | |
1266 rep_cmd *cur; | |
1267 | |
1268 if ((fd<0) || (cmdlist == NULL)) { | |
1269 return(FALSE); | |
1270 } | |
1271 | |
1272 if ((cmdlist->head == NULL) || (cmdlist->num == 0)) { | |
1273 return(TRUE); | |
1274 } | |
1275 | |
1276 for (cur = cmdlist->head; cur; cur = cur->next) { | |
20 | 1277 if (writen(fd,cur->pkt,cur->len+REP_HEADER_SIZE)==FALSE) { |
8 | 1278 return(FALSE); |
1279 } | |
1280 } | |
1281 return(TRUE); | |
1282 } | |
1283 | |
1284 int | |
1285 rep_fd_check(fd, rfds_p, efds_p) | |
1286 int fd; // input from keyboard or something... | |
1287 fd_set *rfds_p; // readable fds | |
1288 fd_set *efds_p; // include a error fd | |
1289 { | |
1290 rep_T *rep_p; | |
1291 rep_cmdlist txtcmdlist = {NULL,0}; | |
1292 | |
1293 rep_p = get_rep(); | |
31 | 1294 rep_sync(); |
8 | 1295 if ((rep_p->smfd > 0) && (FD_ISSET(rep_p->smfd, rfds_p))) { |
26 | 1296 if (rep_recv_cmds(rep_p->smfd, &(txtcmdlist)) == FALSE) { |
8 | 1297 close(rep_p->smfd); |
1298 rep_p->smfd = -1; | |
25 | 1299 } else { |
1300 rep_exe_pktlist(&txtcmdlist); | |
8 | 1301 } |
25 | 1302 } |
8 | 1303 |
25 | 1304 if (FD_ISSET(fd, rfds_p) || FD_ISSET(fd, efds_p)) { |
1305 return(TRUE); | |
8 | 1306 } |
25 | 1307 return FALSE; |
8 | 1308 } |
1309 | |
1310 | |
1311 | |
1312 int | |
1313 rep_fd_set(rfds_p, efds_p, max_fds) | |
1314 fd_set *rfds_p; | |
1315 fd_set *efds_p; | |
1316 int max_fds; | |
1317 { | |
1318 rep_T *rep_p; | |
1319 | |
1320 rep_p = get_rep(); | |
1321 | |
1322 if (rep_p->smfd > 0) { | |
1323 FD_SET(rep_p->smfd,rfds_p); | |
1324 FD_SET(rep_p->smfd,efds_p); | |
1325 if(max_fds < rep_p->smfd){ | |
1326 max_fds = rep_p->smfd; | |
1327 } | |
1328 } | |
1329 | |
1330 return(max_fds); | |
1331 } | |
1332 | |
26 | 1333 void |
1334 rep_close(int i) | |
1335 { | |
1336 rep_T *rep_p; | |
1337 | |
1338 rep_p = get_rep(); | |
27 | 1339 // What should I do? |
1340 rep_end(); | |
26 | 1341 |
1342 } | |
8 | 1343 |
1344 /* | |
1345 * read などで待つ場合に、この関数で REP 関連のデータをチェックする | |
1346 * 指定した fd ( read で読みこむ) から入力があるとぬける。 | |
1347 */ | |
1348 int | |
1349 rep_select(fd) | |
1350 int fd; | |
1351 { | |
1352 fd_set rfds_p; | |
1353 fd_set efds_p; | |
1354 int sk; | |
1355 int max_fds = MAX_FDS; | |
1356 | |
23 | 1357 struct timeval zerotime; |
1358 zerotime.tv_sec = 0; | |
1359 zerotime.tv_usec = 0; | |
31 | 1360 struct timeval *timeout; |
8 | 1361 |
26 | 1362 if (fd < 0) return FALSE; |
1363 | |
27 | 1364 for(;;) { |
1365 /* select の中で modify されてるので、初期化 */ | |
1366 // struct timeval tv; | |
1367 // tv.tv_sec = 0; | |
1368 // tv.tv_usec = 100000; | |
1369 FD_ZERO(&rfds_p); | |
1370 FD_ZERO(&efds_p); | |
26 | 1371 |
27 | 1372 FD_SET(fd,&rfds_p); |
26 | 1373 |
31 | 1374 if (rep_sync()) { |
1375 timeout = &zerotime; | |
1376 } else { | |
1377 timeout = 0; | |
1378 } | |
27 | 1379 max_fds = rep_fd_set(&rfds_p, &efds_p, max_fds); |
8 | 1380 |
31 | 1381 if ((sk = select(max_fds+1, &rfds_p, NULL, &efds_p, timeout)) < 0) { |
27 | 1382 if (errno == EBADF){ |
1383 int i; | |
1384 for(i = 0;i < max_fds;i++){ | |
1385 fd_set suspect; | |
1386 FD_ZERO(&suspect); | |
1387 if (FD_ISSET(i, &rfds_p)){ | |
1388 FD_SET(i, &suspect); | |
1389 if (select(max_fds, &suspect, NULL, NULL, &zerotime) == FAIL){ | |
1390 FD_CLR(i, &rfds_p); | |
1391 rep_close(i); | |
1392 // we have to something to prevent to write to this | |
1393 // port... | |
1394 return(TRUE); | |
1395 } | |
1396 FD_CLR(i, &suspect); | |
26 | 1397 } |
1398 } | |
27 | 1399 } else { |
1400 e_msg_wrp("rep_select(): ERROR"); | |
1401 return(FALSE); | |
26 | 1402 } |
27 | 1403 |
26 | 1404 } |
27 | 1405 if ( rep_fd_check(fd, &rfds_p, &efds_p)) |
1406 return TRUE; // fd に入力があったので抜ける | |
26 | 1407 } |
8 | 1408 } |
1409 | |
1410 void | |
1411 rep_end() | |
1412 { | |
1413 rep_T *rep_p; | |
1414 rep_p = get_rep(); | |
1415 | |
1416 if (rep_p->shead) free_session_list(rep_p->shead); // cursession is freed | |
1417 if (rep_p->servername) free_wrp(rep_p->servername); | |
1418 if (rep_p->smfd > 0) close(rep_p->smfd); | |
1419 | |
1420 set_curbuf_wrp(rep_p->scratch_buf); | |
1421 | |
1422 rep_init(); | |
1423 } | |
1424 | |
1425 | |
1426 | |
24 | 1427 extern void |
1428 pcmd(cmd_p) | |
1429 rep_cmd *cmd_p; | |
1430 { | |
1431 int i; | |
1432 fprintf(stderr,"cmd=%04x",cmd_p->cmd ); | |
1433 fprintf(stderr,"sid=%08x", cmd_p->sid); | |
1434 fprintf(stderr,"eid=%08x", cmd_p->eid); | |
1435 fprintf(stderr,"seq=%08x", cmd_p->seq); | |
1436 fprintf(stderr,"lineno=%08x", cmd_p->lnum); | |
1437 fprintf(stderr,"sz=%08x", cmd_p->len); | |
1438 | |
1439 fprintf(stderr,"\n"); | |
1440 for(i=0;i<cmd_p->len+REP_HEADER_SIZE;i++) { | |
1441 fprintf(stderr,"%02x ", cmd_p->pkt[i]); | |
1442 } | |
1443 fprintf(stderr,"\n"); | |
1444 } | |
1445 | |
27 | 1446 /* end */ |