aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorVincent Belaïche2016-07-28 18:12:50 +0200
committerVincent Belaïche2016-07-28 18:12:50 +0200
commit90ab699c4f281d0c9a9b71f3eb4c8493d00fcf4f (patch)
treedf3235d89ee8e4d32571b8a8521f75f7576913c2 /src/process.c
parent41b28dea8587c13b0bc59c1ec70b65afab3aeeca (diff)
parentec359399a47f852b4d022a30245449438e349193 (diff)
downloademacs-90ab699c4f281d0c9a9b71f3eb4c8493d00fcf4f.tar.gz
emacs-90ab699c4f281d0c9a9b71f3eb4c8493d00fcf4f.zip
Merge branch 'master' of git.sv.gnu.org:/srv/git/emacs
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c110
1 files changed, 72 insertions, 38 deletions
diff --git a/src/process.c b/src/process.c
index 9ca3e594355..bc2ac451c9d 100644
--- a/src/process.c
+++ b/src/process.c
@@ -130,10 +130,10 @@ extern int sys_select (int, fd_set *, fd_set *, fd_set *,
130 struct timespec *, void *); 130 struct timespec *, void *);
131#endif 131#endif
132 132
133/* Work around GCC 4.7.0 bug with strict overflow checking; see 133/* Work around GCC 4.3.0 bug with strict overflow checking; see
134 <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>. 134 <http://gcc.gnu.org/bugzilla/show_bug.cgi?id=52904>.
135 This bug appears to be fixed in GCC 5.1, so don't work around it there. */ 135 This bug appears to be fixed in GCC 5.1, so don't work around it there. */
136#if __GNUC__ == 4 && __GNUC_MINOR__ >= 3 136#if GNUC_PREREQ (4, 3, 0) && ! GNUC_PREREQ (5, 1, 0)
137# pragma GCC diagnostic ignored "-Wstrict-overflow" 137# pragma GCC diagnostic ignored "-Wstrict-overflow"
138#endif 138#endif
139 139
@@ -533,25 +533,37 @@ status_convert (int w)
533 return Qrun; 533 return Qrun;
534} 534}
535 535
536/* True if STATUS is that of a process attempting connection. */
537
538static bool
539connecting_status (Lisp_Object status)
540{
541 return CONSP (status) && EQ (XCAR (status), Qconnect);
542}
543
536/* Given a status-list, extract the three pieces of information 544/* Given a status-list, extract the three pieces of information
537 and store them individually through the three pointers. */ 545 and store them individually through the three pointers. */
538 546
539static void 547static void
540decode_status (Lisp_Object l, Lisp_Object *symbol, int *code, bool *coredump) 548decode_status (Lisp_Object l, Lisp_Object *symbol, Lisp_Object *code,
549 bool *coredump)
541{ 550{
542 Lisp_Object tem; 551 Lisp_Object tem;
543 552
553 if (connecting_status (l))
554 l = XCAR (l);
555
544 if (SYMBOLP (l)) 556 if (SYMBOLP (l))
545 { 557 {
546 *symbol = l; 558 *symbol = l;
547 *code = 0; 559 *code = make_number (0);
548 *coredump = 0; 560 *coredump = 0;
549 } 561 }
550 else 562 else
551 { 563 {
552 *symbol = XCAR (l); 564 *symbol = XCAR (l);
553 tem = XCDR (l); 565 tem = XCDR (l);
554 *code = XFASTINT (XCAR (tem)); 566 *code = XCAR (tem);
555 tem = XCDR (tem); 567 tem = XCDR (tem);
556 *coredump = !NILP (tem); 568 *coredump = !NILP (tem);
557 } 569 }
@@ -563,8 +575,7 @@ static Lisp_Object
563status_message (struct Lisp_Process *p) 575status_message (struct Lisp_Process *p)
564{ 576{
565 Lisp_Object status = p->status; 577 Lisp_Object status = p->status;
566 Lisp_Object symbol; 578 Lisp_Object symbol, code;
567 int code;
568 bool coredump; 579 bool coredump;
569 Lisp_Object string; 580 Lisp_Object string;
570 581
@@ -574,7 +585,7 @@ status_message (struct Lisp_Process *p)
574 { 585 {
575 char const *signame; 586 char const *signame;
576 synchronize_system_messages_locale (); 587 synchronize_system_messages_locale ();
577 signame = strsignal (code); 588 signame = strsignal (XFASTINT (code));
578 if (signame == 0) 589 if (signame == 0)
579 string = build_string ("unknown"); 590 string = build_string ("unknown");
580 else 591 else
@@ -596,20 +607,20 @@ status_message (struct Lisp_Process *p)
596 else if (EQ (symbol, Qexit)) 607 else if (EQ (symbol, Qexit))
597 { 608 {
598 if (NETCONN1_P (p)) 609 if (NETCONN1_P (p))
599 return build_string (code == 0 ? "deleted\n" : "connection broken by remote peer\n"); 610 return build_string (XFASTINT (code) == 0
600 if (code == 0) 611 ? "deleted\n"
612 : "connection broken by remote peer\n");
613 if (XFASTINT (code) == 0)
601 return build_string ("finished\n"); 614 return build_string ("finished\n");
602 AUTO_STRING (prefix, "exited abnormally with code "); 615 AUTO_STRING (prefix, "exited abnormally with code ");
603 string = Fnumber_to_string (make_number (code)); 616 string = Fnumber_to_string (code);
604 AUTO_STRING (suffix, coredump ? " (core dumped)\n" : "\n"); 617 AUTO_STRING (suffix, coredump ? " (core dumped)\n" : "\n");
605 return concat3 (prefix, string, suffix); 618 return concat3 (prefix, string, suffix);
606 } 619 }
607 else if (EQ (symbol, Qfailed)) 620 else if (EQ (symbol, Qfailed))
608 { 621 {
609 AUTO_STRING (prefix, "failed with code "); 622 AUTO_STRING (format, "failed with code %s\n");
610 string = Fnumber_to_string (make_number (code)); 623 return CALLN (Fformat, format, code);
611 AUTO_STRING (suffix, "\n");
612 return concat3 (prefix, string, suffix);
613 } 624 }
614 else 625 else
615 return Fcopy_sequence (Fsymbol_name (symbol)); 626 return Fcopy_sequence (Fsymbol_name (symbol));
@@ -3174,6 +3185,8 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos,
3174 xerrno = errno; 3185 xerrno = errno;
3175 emacs_close (s); 3186 emacs_close (s);
3176 s = -1; 3187 s = -1;
3188 if (socket_to_use < 0)
3189 break;
3177 continue; 3190 continue;
3178 } 3191 }
3179 } 3192 }
@@ -3288,9 +3301,10 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos,
3288 eassert (FD_ISSET (s, &fdset)); 3301 eassert (FD_ISSET (s, &fdset));
3289 if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0) 3302 if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0)
3290 report_file_error ("Failed getsockopt", Qnil); 3303 report_file_error ("Failed getsockopt", Qnil);
3291 if (xerrno) 3304 if (xerrno == 0)
3305 break;
3306 if (NILP (addrinfos))
3292 report_file_errno ("Failed connect", Qnil, xerrno); 3307 report_file_errno ("Failed connect", Qnil, xerrno);
3293 break;
3294 } 3308 }
3295#endif /* !WINDOWSNT */ 3309#endif /* !WINDOWSNT */
3296 3310
@@ -3300,6 +3314,8 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos,
3300 specpdl_ptr = specpdl + count1; 3314 specpdl_ptr = specpdl + count1;
3301 emacs_close (s); 3315 emacs_close (s);
3302 s = -1; 3316 s = -1;
3317 if (socket_to_use < 0)
3318 break;
3303 3319
3304#ifdef WINDOWSNT 3320#ifdef WINDOWSNT
3305 if (xerrno == EINTR) 3321 if (xerrno == EINTR)
@@ -3399,7 +3415,9 @@ connect_network_socket (Lisp_Object proc, Lisp_Object addrinfos,
3399 /* We may get here if connect did succeed immediately. However, 3415 /* We may get here if connect did succeed immediately. However,
3400 in that case, we still need to signal this like a non-blocking 3416 in that case, we still need to signal this like a non-blocking
3401 connection. */ 3417 connection. */
3402 pset_status (p, Qconnect); 3418 if (! (connecting_status (p->status)
3419 && EQ (XCDR (p->status), addrinfos)))
3420 pset_status (p, Fcons (Qconnect, addrinfos));
3403 if (!FD_ISSET (inch, &connect_wait_mask)) 3421 if (!FD_ISSET (inch, &connect_wait_mask))
3404 { 3422 {
3405 FD_SET (inch, &connect_wait_mask); 3423 FD_SET (inch, &connect_wait_mask);
@@ -3960,7 +3978,7 @@ usage: (make-network-process &rest ARGS) */)
3960 if (!p->is_server && NILP (addrinfos)) 3978 if (!p->is_server && NILP (addrinfos))
3961 { 3979 {
3962 p->dns_request = dns_request; 3980 p->dns_request = dns_request;
3963 p->status = Qconnect; 3981 p->status = list1 (Qconnect);
3964 return proc; 3982 return proc;
3965 } 3983 }
3966#endif 3984#endif
@@ -4673,7 +4691,7 @@ check_for_dns (Lisp_Object proc)
4673 addrinfos = Fnreverse (addrinfos); 4691 addrinfos = Fnreverse (addrinfos);
4674 } 4692 }
4675 /* The DNS lookup failed. */ 4693 /* The DNS lookup failed. */
4676 else if (EQ (p->status, Qconnect)) 4694 else if (connecting_status (p->status))
4677 { 4695 {
4678 deactivate_process (proc); 4696 deactivate_process (proc);
4679 pset_status (p, (list2 4697 pset_status (p, (list2
@@ -4686,7 +4704,7 @@ check_for_dns (Lisp_Object proc)
4686 free_dns_request (proc); 4704 free_dns_request (proc);
4687 4705
4688 /* This process should not already be connected (or killed). */ 4706 /* This process should not already be connected (or killed). */
4689 if (!EQ (p->status, Qconnect)) 4707 if (! connecting_status (p->status))
4690 return Qnil; 4708 return Qnil;
4691 4709
4692 return addrinfos; 4710 return addrinfos;
@@ -4698,7 +4716,7 @@ static void
4698wait_for_socket_fds (Lisp_Object process, char const *name) 4716wait_for_socket_fds (Lisp_Object process, char const *name)
4699{ 4717{
4700 while (XPROCESS (process)->infd < 0 4718 while (XPROCESS (process)->infd < 0
4701 && EQ (XPROCESS (process)->status, Qconnect)) 4719 && connecting_status (XPROCESS (process)->status))
4702 { 4720 {
4703 add_to_log ("Waiting for socket from %s...", build_string (name)); 4721 add_to_log ("Waiting for socket from %s...", build_string (name));
4704 wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0); 4722 wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0);
@@ -4708,7 +4726,7 @@ wait_for_socket_fds (Lisp_Object process, char const *name)
4708static void 4726static void
4709wait_while_connecting (Lisp_Object process) 4727wait_while_connecting (Lisp_Object process)
4710{ 4728{
4711 while (EQ (XPROCESS (process)->status, Qconnect)) 4729 while (connecting_status (XPROCESS (process)->status))
4712 { 4730 {
4713 add_to_log ("Waiting for connection..."); 4731 add_to_log ("Waiting for connection...");
4714 wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0); 4732 wait_reading_process_output (0, 20 * 1000 * 1000, 0, 0, Qnil, NULL, 0);
@@ -5010,7 +5028,7 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5010 update_status (wait_proc); 5028 update_status (wait_proc);
5011 if (wait_proc 5029 if (wait_proc
5012 && ! EQ (wait_proc->status, Qrun) 5030 && ! EQ (wait_proc->status, Qrun)
5013 && ! EQ (wait_proc->status, Qconnect)) 5031 && ! connecting_status (wait_proc->status))
5014 { 5032 {
5015 bool read_some_bytes = false; 5033 bool read_some_bytes = false;
5016 5034
@@ -5255,16 +5273,22 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5255 haven't lowered our timeout due to timers or SIGIO and 5273 haven't lowered our timeout due to timers or SIGIO and
5256 have waited a long amount of time due to repeated 5274 have waited a long amount of time due to repeated
5257 timers. */ 5275 timers. */
5276 struct timespec huge_timespec
5277 = make_timespec (TYPE_MAXIMUM (time_t), 2 * TIMESPEC_RESOLUTION);
5278 struct timespec cmp_time = huge_timespec;
5258 if (wait < TIMEOUT) 5279 if (wait < TIMEOUT)
5259 break; 5280 break;
5260 struct timespec cmp_time 5281 if (wait == TIMEOUT)
5261 = (wait == TIMEOUT 5282 cmp_time = end_time;
5262 ? end_time 5283 if (!process_skipped && got_some_output > 0
5263 : (!process_skipped && got_some_output > 0 5284 && (timeout.tv_sec > 0 || timeout.tv_nsec > 0))
5264 && (timeout.tv_sec > 0 || timeout.tv_nsec > 0)) 5285 {
5265 ? got_output_end_time 5286 if (!timespec_valid_p (got_output_end_time))
5266 : invalid_timespec ()); 5287 break;
5267 if (timespec_valid_p (cmp_time)) 5288 if (timespec_cmp (got_output_end_time, cmp_time) < 0)
5289 cmp_time = got_output_end_time;
5290 }
5291 if (timespec_cmp (cmp_time, huge_timespec) < 0)
5268 { 5292 {
5269 now = current_timespec (); 5293 now = current_timespec ();
5270 if (timespec_cmp (cmp_time, now) <= 0) 5294 if (timespec_cmp (cmp_time, now) <= 0)
@@ -5492,15 +5516,16 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5492 5516
5493 p = XPROCESS (proc); 5517 p = XPROCESS (proc);
5494 5518
5495#ifdef GNU_LINUX 5519#ifndef WINDOWSNT
5496 /* getsockopt(,,SO_ERROR,,) is said to hang on some systems.
5497 So only use it on systems where it is known to work. */
5498 { 5520 {
5499 socklen_t xlen = sizeof (xerrno); 5521 socklen_t xlen = sizeof (xerrno);
5500 if (getsockopt (channel, SOL_SOCKET, SO_ERROR, &xerrno, &xlen)) 5522 if (getsockopt (channel, SOL_SOCKET, SO_ERROR, &xerrno, &xlen))
5501 xerrno = errno; 5523 xerrno = errno;
5502 } 5524 }
5503#else 5525#else
5526 /* On MS-Windows, getsockopt clears the error for the
5527 entire process, which may not be the right thing; see
5528 w32.c. Use getpeername instead. */
5504 { 5529 {
5505 struct sockaddr pname; 5530 struct sockaddr pname;
5506 socklen_t pnamelen = sizeof (pname); 5531 socklen_t pnamelen = sizeof (pname);
@@ -5519,9 +5544,18 @@ wait_reading_process_output (intmax_t time_limit, int nsecs, int read_kbd,
5519#endif 5544#endif
5520 if (xerrno) 5545 if (xerrno)
5521 { 5546 {
5522 p->tick = ++process_tick; 5547 Lisp_Object addrinfos
5523 pset_status (p, list2 (Qfailed, make_number (xerrno))); 5548 = connecting_status (p->status) ? XCDR (p->status) : Qnil;
5549 if (!NILP (addrinfos))
5550 XSETCDR (p->status, XCDR (addrinfos));
5551 else
5552 {
5553 p->tick = ++process_tick;
5554 pset_status (p, list2 (Qfailed, make_number (xerrno)));
5555 }
5524 deactivate_process (proc); 5556 deactivate_process (proc);
5557 if (!NILP (addrinfos))
5558 connect_network_socket (proc, addrinfos, Qnil);
5525 } 5559 }
5526 else 5560 else
5527 { 5561 {
@@ -6998,7 +7032,7 @@ status_notify (struct Lisp_Process *deleting_process,
6998 7032
6999 /* If process is still active, read any output that remains. */ 7033 /* If process is still active, read any output that remains. */
7000 while (! EQ (p->filter, Qt) 7034 while (! EQ (p->filter, Qt)
7001 && ! EQ (p->status, Qconnect) 7035 && ! connecting_status (p->status)
7002 && ! EQ (p->status, Qlisten) 7036 && ! EQ (p->status, Qlisten)
7003 /* Network or serial process not stopped: */ 7037 /* Network or serial process not stopped: */
7004 && ! EQ (p->command, Qt) 7038 && ! EQ (p->command, Qt)