diff options
| author | Paul Eggert | 2013-07-19 11:09:23 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-07-19 11:09:23 -0700 |
| commit | 3f5bef16fab0ba83cb2298f8137fec831af1aec4 (patch) | |
| tree | 8f825fe5834080db213452ee3bb1b291f1923a6d /src/process.c | |
| parent | 4195afc389bb0e5ed5aa749e7606a710e07a72d1 (diff) | |
| download | emacs-3f5bef16fab0ba83cb2298f8137fec831af1aec4.tar.gz emacs-3f5bef16fab0ba83cb2298f8137fec831af1aec4.zip | |
Fix some minor file descriptor leaks and related glitches.
* filelock.c (create_lock_file) [!O_CLOEXEC]: Use fcntl with FD_CLOEXEC.
(create_lock_file): Use write, not emacs_write.
* image.c (slurp_file, png_load_body):
* process.c (Fnetwork_interface_list, Fnetwork_interface_info)
(server_accept_connection):
Don't leak an fd on memory allocation failure.
* image.c (slurp_file): Add a cheap heuristic for growing files.
* xfaces.c (Fx_load_color_file): Block input around the fopen too,
as that's what the other routines do. Maybe input need not be
blocked at all, but it's better to be consistent.
Avoid undefined behavior when strlen is zero.
Diffstat (limited to 'src/process.c')
| -rw-r--r-- | src/process.c | 22 |
1 files changed, 16 insertions, 6 deletions
diff --git a/src/process.c b/src/process.c index 7c63964aee6..f4ae662468b 100644 --- a/src/process.c +++ b/src/process.c | |||
| @@ -3526,10 +3526,13 @@ format; see the description of ADDRESS in `make-network-process'. */) | |||
| 3526 | ptrdiff_t buf_size = 512; | 3526 | ptrdiff_t buf_size = 512; |
| 3527 | int s; | 3527 | int s; |
| 3528 | Lisp_Object res; | 3528 | Lisp_Object res; |
| 3529 | ptrdiff_t count; | ||
| 3529 | 3530 | ||
| 3530 | s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); | 3531 | s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); |
| 3531 | if (s < 0) | 3532 | if (s < 0) |
| 3532 | return Qnil; | 3533 | return Qnil; |
| 3534 | count = SPECPDL_INDEX (); | ||
| 3535 | record_unwind_protect_int (close_file_unwind, s); | ||
| 3533 | 3536 | ||
| 3534 | do | 3537 | do |
| 3535 | { | 3538 | { |
| @@ -3545,9 +3548,7 @@ format; see the description of ADDRESS in `make-network-process'. */) | |||
| 3545 | } | 3548 | } |
| 3546 | while (ifconf.ifc_len == buf_size); | 3549 | while (ifconf.ifc_len == buf_size); |
| 3547 | 3550 | ||
| 3548 | emacs_close (s); | 3551 | res = unbind_to (count, Qnil); |
| 3549 | |||
| 3550 | res = Qnil; | ||
| 3551 | ifreq = ifconf.ifc_req; | 3552 | ifreq = ifconf.ifc_req; |
| 3552 | while ((char *) ifreq < (char *) ifconf.ifc_req + ifconf.ifc_len) | 3553 | while ((char *) ifreq < (char *) ifconf.ifc_req + ifconf.ifc_len) |
| 3553 | { | 3554 | { |
| @@ -3672,6 +3673,7 @@ FLAGS is the current flags of the interface. */) | |||
| 3672 | Lisp_Object elt; | 3673 | Lisp_Object elt; |
| 3673 | int s; | 3674 | int s; |
| 3674 | bool any = 0; | 3675 | bool any = 0; |
| 3676 | ptrdiff_t count; | ||
| 3675 | #if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \ | 3677 | #if (! (defined SIOCGIFHWADDR && defined HAVE_STRUCT_IFREQ_IFR_HWADDR) \ |
| 3676 | && defined HAVE_GETIFADDRS && defined LLADDR) | 3678 | && defined HAVE_GETIFADDRS && defined LLADDR) |
| 3677 | struct ifaddrs *ifap; | 3679 | struct ifaddrs *ifap; |
| @@ -3686,6 +3688,8 @@ FLAGS is the current flags of the interface. */) | |||
| 3686 | s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); | 3688 | s = socket (AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); |
| 3687 | if (s < 0) | 3689 | if (s < 0) |
| 3688 | return Qnil; | 3690 | return Qnil; |
| 3691 | count = SPECPDL_INDEX (); | ||
| 3692 | record_unwind_protect_int (close_file_unwind, s); | ||
| 3689 | 3693 | ||
| 3690 | elt = Qnil; | 3694 | elt = Qnil; |
| 3691 | #if defined (SIOCGIFFLAGS) && defined (HAVE_STRUCT_IFREQ_IFR_FLAGS) | 3695 | #if defined (SIOCGIFFLAGS) && defined (HAVE_STRUCT_IFREQ_IFR_FLAGS) |
| @@ -3802,9 +3806,7 @@ FLAGS is the current flags of the interface. */) | |||
| 3802 | #endif | 3806 | #endif |
| 3803 | res = Fcons (elt, res); | 3807 | res = Fcons (elt, res); |
| 3804 | 3808 | ||
| 3805 | emacs_close (s); | 3809 | return unbind_to (count, any ? res : Qnil); |
| 3806 | |||
| 3807 | return any ? res : Qnil; | ||
| 3808 | } | 3810 | } |
| 3809 | #endif | 3811 | #endif |
| 3810 | #endif /* defined (HAVE_NET_IF_H) */ | 3812 | #endif /* defined (HAVE_NET_IF_H) */ |
| @@ -3978,6 +3980,7 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 3978 | #endif | 3980 | #endif |
| 3979 | } saddr; | 3981 | } saddr; |
| 3980 | socklen_t len = sizeof saddr; | 3982 | socklen_t len = sizeof saddr; |
| 3983 | ptrdiff_t count; | ||
| 3981 | 3984 | ||
| 3982 | s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC); | 3985 | s = accept4 (channel, &saddr.sa, &len, SOCK_CLOEXEC); |
| 3983 | 3986 | ||
| @@ -4000,6 +4003,9 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 4000 | return; | 4003 | return; |
| 4001 | } | 4004 | } |
| 4002 | 4005 | ||
| 4006 | count = SPECPDL_INDEX (); | ||
| 4007 | record_unwind_protect_int (close_file_unwind, s); | ||
| 4008 | |||
| 4003 | connect_counter++; | 4009 | connect_counter++; |
| 4004 | 4010 | ||
| 4005 | /* Setup a new process to handle the connection. */ | 4011 | /* Setup a new process to handle the connection. */ |
| @@ -4116,6 +4122,10 @@ server_accept_connection (Lisp_Object server, int channel) | |||
| 4116 | pset_filter (p, ps->filter); | 4122 | pset_filter (p, ps->filter); |
| 4117 | pset_command (p, Qnil); | 4123 | pset_command (p, Qnil); |
| 4118 | p->pid = 0; | 4124 | p->pid = 0; |
| 4125 | |||
| 4126 | /* Discard the unwind protect for closing S. */ | ||
| 4127 | specpdl_ptr = specpdl + count; | ||
| 4128 | |||
| 4119 | p->infd = s; | 4129 | p->infd = s; |
| 4120 | p->outfd = s; | 4130 | p->outfd = s; |
| 4121 | pset_status (p, Qrun); | 4131 | pset_status (p, Qrun); |