aboutsummaryrefslogtreecommitdiffstats
path: root/src/process.c
diff options
context:
space:
mode:
authorLars Ingebrigtsen2016-01-28 23:50:47 +0100
committerLars Ingebrigtsen2016-01-28 23:50:47 +0100
commite09c0972c350e9411683b509414fc598cbf387d3 (patch)
tree2472742ab64bf82da9c4011f0adee5d56cb57af6 /src/process.c
parent6d25cbeaaf93615b8d7f26024ba014104eb5d4f2 (diff)
downloademacs-e09c0972c350e9411683b509414fc598cbf387d3.tar.gz
emacs-e09c0972c350e9411683b509414fc598cbf387d3.zip
Refactor make_network_process
* src/process.c (set_network_socket_coding_system) (connect_network_socket): Refactor out of make_network_process to allow calling connect_network_socket asynchronously. (Fmake_network_process): Do nothing but parsing the parameters and name resolution, leaving the connection to connect_network_socket.
Diffstat (limited to 'src/process.c')
-rw-r--r--src/process.c877
1 files changed, 449 insertions, 428 deletions
diff --git a/src/process.c b/src/process.c
index e1ebdff7430..1329d968e28 100644
--- a/src/process.c
+++ b/src/process.c
@@ -2904,6 +2904,403 @@ usage: (make-serial-process &rest ARGS) */)
2904 return proc; 2904 return proc;
2905} 2905}
2906 2906
2907void set_network_socket_coding_system (Lisp_Object proc) {
2908 Lisp_Object tem;
2909 struct Lisp_Process *p = XPROCESS (proc);
2910 Lisp_Object contact = p->childp;
2911 Lisp_Object service, host, name;
2912
2913 service = Fplist_get (contact, QCservice);
2914 host = Fplist_get (contact, QChost);
2915 name = Fplist_get (contact, QCname);
2916
2917 tem = Fplist_member (contact, QCcoding);
2918 if (!NILP (tem) && (!CONSP (tem) || !CONSP (XCDR (tem))))
2919 tem = Qnil; /* No error message (too late!). */
2920
2921 {
2922 /* Setup coding systems for communicating with the network stream. */
2923 /* Qt denotes we have not yet called Ffind_operation_coding_system. */
2924 Lisp_Object coding_systems = Qt;
2925 Lisp_Object val;
2926
2927 if (!NILP (tem))
2928 {
2929 val = XCAR (XCDR (tem));
2930 if (CONSP (val))
2931 val = XCAR (val);
2932 }
2933 else if (!NILP (Vcoding_system_for_read))
2934 val = Vcoding_system_for_read;
2935 else if ((!NILP (p->buffer) &&
2936 NILP (BVAR (XBUFFER (p->buffer), enable_multibyte_characters)))
2937 || (NILP (p->buffer) && NILP (BVAR (&buffer_defaults, enable_multibyte_characters))))
2938 /* We dare not decode end-of-line format by setting VAL to
2939 Qraw_text, because the existing Emacs Lisp libraries
2940 assume that they receive bare code including a sequence of
2941 CR LF. */
2942 val = Qnil;
2943 else
2944 {
2945 if (NILP (host) || NILP (service))
2946 coding_systems = Qnil;
2947 else
2948 coding_systems = CALLN (Ffind_operation_coding_system,
2949 Qopen_network_stream, name, p->buffer,
2950 host, service);
2951 if (CONSP (coding_systems))
2952 val = XCAR (coding_systems);
2953 else if (CONSP (Vdefault_process_coding_system))
2954 val = XCAR (Vdefault_process_coding_system);
2955 else
2956 val = Qnil;
2957 }
2958 pset_decode_coding_system (p, val);
2959
2960 if (!NILP (tem))
2961 {
2962 val = XCAR (XCDR (tem));
2963 if (CONSP (val))
2964 val = XCDR (val);
2965 }
2966 else if (!NILP (Vcoding_system_for_write))
2967 val = Vcoding_system_for_write;
2968 else if (NILP (BVAR (current_buffer, enable_multibyte_characters)))
2969 val = Qnil;
2970 else
2971 {
2972 if (EQ (coding_systems, Qt))
2973 {
2974 if (NILP (host) || NILP (service))
2975 coding_systems = Qnil;
2976 else
2977 coding_systems = CALLN (Ffind_operation_coding_system,
2978 Qopen_network_stream, name, p->buffer,
2979 host, service);
2980 }
2981 if (CONSP (coding_systems))
2982 val = XCDR (coding_systems);
2983 else if (CONSP (Vdefault_process_coding_system))
2984 val = XCDR (Vdefault_process_coding_system);
2985 else
2986 val = Qnil;
2987 }
2988 pset_encode_coding_system (p, val);
2989 }
2990 setup_process_coding_systems (proc);
2991
2992 pset_decoding_buf (p, empty_unibyte_string);
2993 p->decoding_carryover = 0;
2994 pset_encoding_buf (p, empty_unibyte_string);
2995
2996 p->inherit_coding_system_flag
2997 = !(!NILP (tem) || NILP (p->buffer) || !inherit_process_coding_system);
2998}
2999
3000void connect_network_socket (Lisp_Object proc, Lisp_Object ip_addresses) {
3001 ptrdiff_t count = SPECPDL_INDEX ();
3002 ptrdiff_t count1;
3003 int s = -1, outch, inch;
3004 int xerrno = 0;
3005 Lisp_Object ip_address;
3006 int family;
3007 struct sockaddr *sa;
3008 int ret;
3009 int addrlen;
3010 struct Lisp_Process *p = XPROCESS (proc);
3011 Lisp_Object contact = p->childp;
3012 int optbits = 0;
3013
3014 /* Do this in case we never enter the for-loop below. */
3015 count1 = SPECPDL_INDEX ();
3016 s = -1;
3017
3018 while (!NILP (ip_addresses))
3019 {
3020 ip_address = Fcar (ip_addresses);
3021 ip_addresses = Fcdr (ip_addresses);
3022
3023#ifdef WINDOWSNT
3024 retry_connect:
3025#endif
3026
3027 addrlen = get_lisp_to_sockaddr_size (ip_address, &family);
3028 sa = alloca (addrlen);
3029 conv_lisp_to_sockaddr (family, ip_address, sa, addrlen);
3030
3031 s = socket (family, p->socktype | SOCK_CLOEXEC, p->ai_protocol);
3032 if (s < 0)
3033 {
3034 xerrno = errno;
3035 continue;
3036 }
3037
3038#ifdef DATAGRAM_SOCKETS
3039 if (!p->is_server && p->socktype == SOCK_DGRAM)
3040 break;
3041#endif /* DATAGRAM_SOCKETS */
3042
3043#ifdef NON_BLOCKING_CONNECT
3044 if (p->is_non_blocking_client)
3045 {
3046 ret = fcntl (s, F_SETFL, O_NONBLOCK);
3047 if (ret < 0)
3048 {
3049 xerrno = errno;
3050 emacs_close (s);
3051 s = -1;
3052 continue;
3053 }
3054 }
3055#endif
3056
3057 /* Make us close S if quit. */
3058 record_unwind_protect_int (close_file_unwind, s);
3059
3060 /* Parse network options in the arg list. We simply ignore anything
3061 which isn't a known option (including other keywords). An error
3062 is signaled if setting a known option fails. */
3063 {
3064 Lisp_Object params = contact, key, val;
3065
3066 while (!NILP (params)) {
3067 key = Fcar (params);
3068 params = Fcdr (params);
3069 val = Fcar (params);
3070 params = Fcdr (params);
3071 optbits |= set_socket_option (s, key, val);
3072 }
3073 }
3074
3075 if (p->is_server)
3076 {
3077 /* Configure as a server socket. */
3078
3079 /* SO_REUSEADDR = 1 is default for server sockets; must specify
3080 explicit :reuseaddr key to override this. */
3081#ifdef HAVE_LOCAL_SOCKETS
3082 if (family != AF_LOCAL)
3083#endif
3084 if (!(optbits & (1 << OPIX_REUSEADDR)))
3085 {
3086 int optval = 1;
3087 if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval))
3088 report_file_error ("Cannot set reuse option on server socket", Qnil);
3089 }
3090
3091 if (bind (s, sa, addrlen))
3092 report_file_error ("Cannot bind server socket", Qnil);
3093
3094#ifdef HAVE_GETSOCKNAME
3095 if (p->port == 0)
3096 {
3097 struct sockaddr_in sa1;
3098 socklen_t len1 = sizeof (sa1);
3099 if (getsockname (s, (struct sockaddr *)&sa1, &len1) == 0)
3100 {
3101 Lisp_Object service;
3102 service = make_number (ntohs (sa1.sin_port));
3103 contact = Fplist_put (contact, QCservice, service);
3104 }
3105 }
3106#endif
3107
3108 if (p->socktype != SOCK_DGRAM && listen (s, p->backlog))
3109 report_file_error ("Cannot listen on server socket", Qnil);
3110
3111 break;
3112 }
3113
3114 immediate_quit = 1;
3115 QUIT;
3116
3117 ret = connect (s, sa, addrlen);
3118 xerrno = errno;
3119
3120 if (ret == 0 || xerrno == EISCONN)
3121 {
3122 /* The unwind-protect will be discarded afterwards.
3123 Likewise for immediate_quit. */
3124 break;
3125 }
3126
3127#ifdef NON_BLOCKING_CONNECT
3128#ifdef EINPROGRESS
3129 if (p->is_non_blocking_client && xerrno == EINPROGRESS)
3130 break;
3131#else
3132#ifdef EWOULDBLOCK
3133 if (p->is_non_blocking_client && xerrno == EWOULDBLOCK)
3134 break;
3135#endif
3136#endif
3137#endif
3138
3139#ifndef WINDOWSNT
3140 if (xerrno == EINTR)
3141 {
3142 /* Unlike most other syscalls connect() cannot be called
3143 again. (That would return EALREADY.) The proper way to
3144 wait for completion is pselect(). */
3145 int sc;
3146 socklen_t len;
3147 fd_set fdset;
3148 retry_select:
3149 FD_ZERO (&fdset);
3150 FD_SET (s, &fdset);
3151 QUIT;
3152 sc = pselect (s + 1, NULL, &fdset, NULL, NULL, NULL);
3153 if (sc == -1)
3154 {
3155 if (errno == EINTR)
3156 goto retry_select;
3157 else
3158 report_file_error ("Failed select", Qnil);
3159 }
3160 eassert (sc > 0);
3161
3162 len = sizeof xerrno;
3163 eassert (FD_ISSET (s, &fdset));
3164 if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0)
3165 report_file_error ("Failed getsockopt", Qnil);
3166 if (xerrno)
3167 report_file_errno ("Failed connect", Qnil, xerrno);
3168 break;
3169 }
3170#endif /* !WINDOWSNT */
3171
3172 immediate_quit = 0;
3173
3174 /* Discard the unwind protect closing S. */
3175 specpdl_ptr = specpdl + count1;
3176 emacs_close (s);
3177 s = -1;
3178
3179#ifdef WINDOWSNT
3180 if (xerrno == EINTR)
3181 goto retry_connect;
3182#endif
3183 }
3184
3185 if (s >= 0)
3186 {
3187#ifdef DATAGRAM_SOCKETS
3188 if (p->socktype == SOCK_DGRAM)
3189 {
3190 if (datagram_address[s].sa)
3191 emacs_abort ();
3192
3193 datagram_address[s].sa = xmalloc (addrlen);
3194 datagram_address[s].len = addrlen;
3195 if (p->is_server)
3196 {
3197 Lisp_Object remote;
3198 memset (datagram_address[s].sa, 0, addrlen);
3199 if (remote = Fplist_get (contact, QCremote), !NILP (remote))
3200 {
3201 int rfamily, rlen;
3202 rlen = get_lisp_to_sockaddr_size (remote, &rfamily);
3203 if (rlen != 0 && rfamily == family
3204 && rlen == addrlen)
3205 conv_lisp_to_sockaddr (rfamily, remote,
3206 datagram_address[s].sa, rlen);
3207 }
3208 }
3209 else
3210 memcpy (datagram_address[s].sa, sa, addrlen);
3211 }
3212#endif
3213
3214 contact = Fplist_put (contact, p->is_server? QCremote: QClocal,
3215 conv_sockaddr_to_lisp (sa, addrlen));
3216#ifdef HAVE_GETSOCKNAME
3217 if (!p->is_server)
3218 {
3219 struct sockaddr_in sa1;
3220 socklen_t len1 = sizeof (sa1);
3221 if (getsockname (s, (struct sockaddr *)&sa1, &len1) == 0)
3222 contact = Fplist_put (contact, QClocal,
3223 conv_sockaddr_to_lisp ((struct sockaddr *)&sa1, len1));
3224 }
3225#endif
3226 }
3227
3228 immediate_quit = 0;
3229
3230 if (s < 0)
3231 {
3232 /* If non-blocking got this far - and failed - assume non-blocking is
3233 not supported after all. This is probably a wrong assumption, but
3234 the normal blocking calls to open-network-stream handles this error
3235 better. */
3236 if (p->is_non_blocking_client)
3237 return;
3238
3239 report_file_errno ((p->is_server
3240 ? "make server process failed"
3241 : "make client process failed"),
3242 contact, xerrno);
3243 }
3244
3245 inch = s;
3246 outch = s;
3247
3248 chan_process[inch] = proc;
3249
3250 fcntl (inch, F_SETFL, O_NONBLOCK);
3251
3252 p = XPROCESS (proc);
3253 p->open_fd[SUBPROCESS_STDIN] = inch;
3254 p->infd = inch;
3255 p->outfd = outch;
3256
3257 /* Discard the unwind protect for closing S, if any. */
3258 specpdl_ptr = specpdl + count1;
3259
3260 /* Unwind bind_polling_period and request_sigio. */
3261 unbind_to (count, Qnil);
3262
3263 if (p->is_server && p->socktype != SOCK_DGRAM)
3264 pset_status (p, Qlisten);
3265
3266 /* Make the process marker point into the process buffer (if any). */
3267 if (BUFFERP (p->buffer))
3268 set_marker_both (p->mark, p->buffer,
3269 BUF_ZV (XBUFFER (p->buffer)),
3270 BUF_ZV_BYTE (XBUFFER (p->buffer)));
3271
3272#ifdef NON_BLOCKING_CONNECT
3273 if (p->is_non_blocking_client)
3274 {
3275 /* We may get here if connect did succeed immediately. However,
3276 in that case, we still need to signal this like a non-blocking
3277 connection. */
3278 pset_status (p, Qconnect);
3279 if (!FD_ISSET (inch, &connect_wait_mask))
3280 {
3281 FD_SET (inch, &connect_wait_mask);
3282 FD_SET (inch, &write_mask);
3283 num_pending_connects++;
3284 }
3285 }
3286 else
3287#endif
3288 /* A server may have a client filter setting of Qt, but it must
3289 still listen for incoming connects unless it is stopped. */
3290 if ((!EQ (p->filter, Qt) && !EQ (p->command, Qt))
3291 || (EQ (p->status, Qlisten) && NILP (p->command)))
3292 {
3293 FD_SET (inch, &input_wait_mask);
3294 FD_SET (inch, &non_keyboard_wait_mask);
3295 }
3296
3297 if (inch > max_process_desc)
3298 max_process_desc = inch;
3299
3300 set_network_socket_coding_system (proc);
3301}
3302
3303
2907/* Create a network stream/datagram client/server process. Treated 3304/* Create a network stream/datagram client/server process. Treated
2908 exactly like a normal process when reading and writing. Primary 3305 exactly like a normal process when reading and writing. Primary
2909 differences are in status display and process deletion. A network 3306 differences are in status display and process deletion. A network
@@ -3072,36 +3469,20 @@ usage: (make-network-process &rest ARGS) */)
3072 struct addrinfo hints; 3469 struct addrinfo hints;
3073 const char *portstring; 3470 const char *portstring;
3074 char portbuf[128]; 3471 char portbuf[128];
3075#else /* HAVE_GETADDRINFO */
3076 struct _emacs_addrinfo
3077 {
3078 int ai_family;
3079 int ai_socktype;
3080 int ai_protocol;
3081 int ai_addrlen;
3082 struct sockaddr *ai_addr;
3083 struct _emacs_addrinfo *ai_next;
3084 } ai, *res, *lres;
3085#endif /* HAVE_GETADDRINFO */ 3472#endif /* HAVE_GETADDRINFO */
3086 struct sockaddr_in address_in;
3087#ifdef HAVE_LOCAL_SOCKETS 3473#ifdef HAVE_LOCAL_SOCKETS
3088 struct sockaddr_un address_un; 3474 struct sockaddr_un address_un;
3089#endif 3475#endif
3090 int port; 3476 int port = 0;
3091 int ret = 0; 3477 int ret = 0;
3092 int xerrno = 0;
3093 int s = -1, outch, inch;
3094 ptrdiff_t count = SPECPDL_INDEX ();
3095 ptrdiff_t count1;
3096 Lisp_Object colon_address; /* Either QClocal or QCremote. */
3097 Lisp_Object tem; 3478 Lisp_Object tem;
3098 Lisp_Object name, buffer, host, service, address; 3479 Lisp_Object name, buffer, host, service, address;
3099 Lisp_Object filter, sentinel; 3480 Lisp_Object filter, sentinel;
3100 bool is_non_blocking_client = 0; 3481 Lisp_Object ip_addresses = Qnil;
3101 bool is_server = 0;
3102 int backlog = 5;
3103 int socktype; 3482 int socktype;
3104 int family = -1; 3483 int family = -1;
3484 int ai_protocol = 0;
3485 ptrdiff_t count = SPECPDL_INDEX ();
3105 3486
3106 if (nargs == 0) 3487 if (nargs == 0)
3107 return Qnil; 3488 return Qnil;
@@ -3129,31 +3510,6 @@ usage: (make-network-process &rest ARGS) */)
3129 else 3510 else
3130 error ("Unsupported connection type"); 3511 error ("Unsupported connection type");
3131 3512
3132 /* :server BOOL */
3133 tem = Fplist_get (contact, QCserver);
3134 if (!NILP (tem))
3135 {
3136 /* Don't support network sockets when non-blocking mode is
3137 not available, since a blocked Emacs is not useful. */
3138 is_server = 1;
3139 if (TYPE_RANGED_INTEGERP (int, tem))
3140 backlog = XINT (tem);
3141 }
3142
3143 /* Make colon_address an alias for :local (server) or :remote (client). */
3144 colon_address = is_server ? QClocal : QCremote;
3145
3146 /* :nowait BOOL */
3147 if (!is_server && socktype != SOCK_DGRAM
3148 && (tem = Fplist_get (contact, QCnowait), !NILP (tem)))
3149 {
3150#ifndef NON_BLOCKING_CONNECT
3151 error ("Non-blocking connect not supported");
3152#else
3153 is_non_blocking_client = 1;
3154#endif
3155 }
3156
3157 name = Fplist_get (contact, QCname); 3513 name = Fplist_get (contact, QCname);
3158 buffer = Fplist_get (contact, QCbuffer); 3514 buffer = Fplist_get (contact, QCbuffer);
3159 filter = Fplist_get (contact, QCfilter); 3515 filter = Fplist_get (contact, QCfilter);
@@ -3168,16 +3524,19 @@ usage: (make-network-process &rest ARGS) */)
3168 res = &ai; 3524 res = &ai;
3169 3525
3170 /* :local ADDRESS or :remote ADDRESS */ 3526 /* :local ADDRESS or :remote ADDRESS */
3171 address = Fplist_get (contact, colon_address); 3527 tem = Fplist_get (contact, QCserver);
3528 if (!NILP (tem))
3529 address = Fplist_get (contact, QCremote);
3530 else
3531 address = Fplist_get (contact, QClocal);
3172 if (!NILP (address)) 3532 if (!NILP (address))
3173 { 3533 {
3174 host = service = Qnil; 3534 host = service = Qnil;
3175 3535
3176 if (!(ai.ai_addrlen = get_lisp_to_sockaddr_size (address, &family))) 3536 if (!get_lisp_to_sockaddr_size (address, &family))
3177 error ("Malformed :address"); 3537 error ("Malformed :address");
3178 ai.ai_family = family; 3538
3179 ai.ai_addr = alloca (ai.ai_addrlen); 3539 ip_addresses = Fcons (address, Qnil);
3180 conv_lisp_to_sockaddr (family, address, ai.ai_addr, ai.ai_addrlen);
3181 goto open_socket; 3540 goto open_socket;
3182 } 3541 }
3183 3542
@@ -3206,8 +3565,6 @@ usage: (make-network-process &rest ARGS) */)
3206 else 3565 else
3207 error ("Unknown address family"); 3566 error ("Unknown address family");
3208 3567
3209 ai.ai_family = family;
3210
3211 /* :service SERVICE -- string, integer (port number), or t (random port). */ 3568 /* :service SERVICE -- string, integer (port number), or t (random port). */
3212 service = Fplist_get (contact, QCservice); 3569 service = Fplist_get (contact, QCservice);
3213 3570
@@ -3232,13 +3589,9 @@ usage: (make-network-process &rest ARGS) */)
3232 host = Qnil; 3589 host = Qnil;
3233 } 3590 }
3234 CHECK_STRING (service); 3591 CHECK_STRING (service);
3235 memset (&address_un, 0, sizeof address_un);
3236 address_un.sun_family = AF_LOCAL;
3237 if (sizeof address_un.sun_path <= SBYTES (service)) 3592 if (sizeof address_un.sun_path <= SBYTES (service))
3238 error ("Service name too long"); 3593 error ("Service name too long");
3239 lispstpcpy (address_un.sun_path, service); 3594 ip_addresses = Fcons (service, Qnil);
3240 ai.ai_addr = (struct sockaddr *) &address_un;
3241 ai.ai_addrlen = sizeof address_un;
3242 goto open_socket; 3595 goto open_socket;
3243 } 3596 }
3244#endif 3597#endif
@@ -3257,6 +3610,7 @@ usage: (make-network-process &rest ARGS) */)
3257#ifdef HAVE_GETADDRINFO 3610#ifdef HAVE_GETADDRINFO
3258 /* If we have a host, use getaddrinfo to resolve both host and service. 3611 /* If we have a host, use getaddrinfo to resolve both host and service.
3259 Otherwise, use getservbyname to lookup the service. */ 3612 Otherwise, use getservbyname to lookup the service. */
3613
3260 if (!NILP (host)) 3614 if (!NILP (host))
3261 { 3615 {
3262 3616
@@ -3296,6 +3650,15 @@ usage: (make-network-process &rest ARGS) */)
3296#endif 3650#endif
3297 immediate_quit = 0; 3651 immediate_quit = 0;
3298 3652
3653 for (lres = res; lres; lres = lres->ai_next)
3654 {
3655 ip_addresses = Fcons (conv_sockaddr_to_lisp
3656 (lres->ai_addr, lres->ai_addrlen),
3657 ip_addresses);
3658 ai_protocol = lres->ai_protocol;
3659 family = lres->ai_family;
3660 }
3661
3299 goto open_socket; 3662 goto open_socket;
3300 } 3663 }
3301#endif /* HAVE_GETADDRINFO */ 3664#endif /* HAVE_GETADDRINFO */
@@ -3318,11 +3681,6 @@ usage: (make-network-process &rest ARGS) */)
3318 port = svc_info->s_port; 3681 port = svc_info->s_port;
3319 } 3682 }
3320 3683
3321 memset (&address_in, 0, sizeof address_in);
3322 address_in.sin_family = family;
3323 address_in.sin_addr.s_addr = INADDR_ANY;
3324 address_in.sin_port = port;
3325
3326#ifndef HAVE_GETADDRINFO 3684#ifndef HAVE_GETADDRINFO
3327 if (!NILP (host)) 3685 if (!NILP (host))
3328 { 3686 {
@@ -3342,10 +3700,10 @@ usage: (make-network-process &rest ARGS) */)
3342 3700
3343 if (host_info_ptr) 3701 if (host_info_ptr)
3344 { 3702 {
3345 memcpy (&address_in.sin_addr, host_info_ptr->h_addr, 3703 ip_addresses = Ncons (make_number (host_info_ptr->h_addr,
3346 host_info_ptr->h_length); 3704 host_info_ptr->h_length),
3705 Qnil);
3347 family = host_info_ptr->h_addrtype; 3706 family = host_info_ptr->h_addrtype;
3348 address_in.sin_family = family;
3349 } 3707 }
3350 else 3708 else
3351 /* Attempt to interpret host as numeric inet address. */ 3709 /* Attempt to interpret host as numeric inet address. */
@@ -3355,258 +3713,18 @@ usage: (make-network-process &rest ARGS) */)
3355 if (numeric_addr == -1) 3713 if (numeric_addr == -1)
3356 error ("Unknown host \"%s\"", SDATA (host)); 3714 error ("Unknown host \"%s\"", SDATA (host));
3357 3715
3358 memcpy (&address_in.sin_addr, &numeric_addr, 3716 ip_addresses = Ncons (make_number (numeric_addr), Qnil);
3359 sizeof (address_in.sin_addr));
3360 } 3717 }
3361 3718
3362 } 3719 }
3363#endif /* not HAVE_GETADDRINFO */ 3720#endif /* not HAVE_GETADDRINFO */
3364 3721
3365 ai.ai_family = family;
3366 ai.ai_addr = (struct sockaddr *) &address_in;
3367 ai.ai_addrlen = sizeof address_in;
3368
3369 open_socket: 3722 open_socket:
3370 3723
3371 /* Do this in case we never enter the for-loop below. */
3372 count1 = SPECPDL_INDEX ();
3373 s = -1;
3374
3375 for (lres = res; lres; lres = lres->ai_next)
3376 {
3377 ptrdiff_t optn;
3378 int optbits;
3379
3380#ifdef WINDOWSNT
3381 retry_connect:
3382#endif
3383
3384 s = socket (lres->ai_family, lres->ai_socktype | SOCK_CLOEXEC,
3385 lres->ai_protocol);
3386 if (s < 0)
3387 {
3388 xerrno = errno;
3389 continue;
3390 }
3391
3392#ifdef DATAGRAM_SOCKETS
3393 if (!is_server && socktype == SOCK_DGRAM)
3394 break;
3395#endif /* DATAGRAM_SOCKETS */
3396
3397#ifdef NON_BLOCKING_CONNECT
3398 if (is_non_blocking_client)
3399 {
3400 ret = fcntl (s, F_SETFL, O_NONBLOCK);
3401 if (ret < 0)
3402 {
3403 xerrno = errno;
3404 emacs_close (s);
3405 s = -1;
3406 continue;
3407 }
3408 }
3409#endif
3410
3411 /* Make us close S if quit. */
3412 record_unwind_protect_int (close_file_unwind, s);
3413
3414 /* Parse network options in the arg list.
3415 We simply ignore anything which isn't a known option (including other keywords).
3416 An error is signaled if setting a known option fails. */
3417 for (optn = optbits = 0; optn < nargs - 1; optn += 2)
3418 optbits |= set_socket_option (s, args[optn], args[optn + 1]);
3419
3420 if (is_server)
3421 {
3422 /* Configure as a server socket. */
3423
3424 /* SO_REUSEADDR = 1 is default for server sockets; must specify
3425 explicit :reuseaddr key to override this. */
3426#ifdef HAVE_LOCAL_SOCKETS
3427 if (family != AF_LOCAL)
3428#endif
3429 if (!(optbits & (1 << OPIX_REUSEADDR)))
3430 {
3431 int optval = 1;
3432 if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &optval, sizeof optval))
3433 report_file_error ("Cannot set reuse option on server socket", Qnil);
3434 }
3435
3436 if (bind (s, lres->ai_addr, lres->ai_addrlen))
3437 report_file_error ("Cannot bind server socket", Qnil);
3438
3439#ifdef HAVE_GETSOCKNAME
3440 if (EQ (service, Qt))
3441 {
3442 struct sockaddr_in sa1;
3443 socklen_t len1 = sizeof (sa1);
3444 if (getsockname (s, (struct sockaddr *)&sa1, &len1) == 0)
3445 {
3446 ((struct sockaddr_in *)(lres->ai_addr))->sin_port = sa1.sin_port;
3447 service = make_number (ntohs (sa1.sin_port));
3448 contact = Fplist_put (contact, QCservice, service);
3449 }
3450 }
3451#endif
3452
3453 if (socktype != SOCK_DGRAM && listen (s, backlog))
3454 report_file_error ("Cannot listen on server socket", Qnil);
3455
3456 break;
3457 }
3458
3459 immediate_quit = 1;
3460 QUIT;
3461
3462 ret = connect (s, lres->ai_addr, lres->ai_addrlen);
3463 xerrno = errno;
3464
3465 if (ret == 0 || xerrno == EISCONN)
3466 {
3467 /* The unwind-protect will be discarded afterwards.
3468 Likewise for immediate_quit. */
3469 break;
3470 }
3471
3472#ifdef NON_BLOCKING_CONNECT
3473#ifdef EINPROGRESS
3474 if (is_non_blocking_client && xerrno == EINPROGRESS)
3475 break;
3476#else
3477#ifdef EWOULDBLOCK
3478 if (is_non_blocking_client && xerrno == EWOULDBLOCK)
3479 break;
3480#endif
3481#endif
3482#endif
3483
3484#ifndef WINDOWSNT
3485 if (xerrno == EINTR)
3486 {
3487 /* Unlike most other syscalls connect() cannot be called
3488 again. (That would return EALREADY.) The proper way to
3489 wait for completion is pselect(). */
3490 int sc;
3491 socklen_t len;
3492 fd_set fdset;
3493 retry_select:
3494 FD_ZERO (&fdset);
3495 FD_SET (s, &fdset);
3496 QUIT;
3497 sc = pselect (s + 1, NULL, &fdset, NULL, NULL, NULL);
3498 if (sc == -1)
3499 {
3500 if (errno == EINTR)
3501 goto retry_select;
3502 else
3503 report_file_error ("Failed select", Qnil);
3504 }
3505 eassert (sc > 0);
3506
3507 len = sizeof xerrno;
3508 eassert (FD_ISSET (s, &fdset));
3509 if (getsockopt (s, SOL_SOCKET, SO_ERROR, &xerrno, &len) < 0)
3510 report_file_error ("Failed getsockopt", Qnil);
3511 if (xerrno)
3512 report_file_errno ("Failed connect", Qnil, xerrno);
3513 break;
3514 }
3515#endif /* !WINDOWSNT */
3516
3517 immediate_quit = 0;
3518
3519 /* Discard the unwind protect closing S. */
3520 specpdl_ptr = specpdl + count1;
3521 emacs_close (s);
3522 s = -1;
3523
3524#ifdef WINDOWSNT
3525 if (xerrno == EINTR)
3526 goto retry_connect;
3527#endif
3528 }
3529
3530 if (s >= 0)
3531 {
3532#ifdef DATAGRAM_SOCKETS
3533 if (socktype == SOCK_DGRAM)
3534 {
3535 if (datagram_address[s].sa)
3536 emacs_abort ();
3537 datagram_address[s].sa = xmalloc (lres->ai_addrlen);
3538 datagram_address[s].len = lres->ai_addrlen;
3539 if (is_server)
3540 {
3541 Lisp_Object remote;
3542 memset (datagram_address[s].sa, 0, lres->ai_addrlen);
3543 if (remote = Fplist_get (contact, QCremote), !NILP (remote))
3544 {
3545 int rfamily, rlen;
3546 rlen = get_lisp_to_sockaddr_size (remote, &rfamily);
3547 if (rlen != 0 && rfamily == lres->ai_family
3548 && rlen == lres->ai_addrlen)
3549 conv_lisp_to_sockaddr (rfamily, remote,
3550 datagram_address[s].sa, rlen);
3551 }
3552 }
3553 else
3554 memcpy (datagram_address[s].sa, lres->ai_addr, lres->ai_addrlen);
3555 }
3556#endif
3557 contact = Fplist_put (contact, colon_address,
3558 conv_sockaddr_to_lisp (lres->ai_addr, lres->ai_addrlen));
3559#ifdef HAVE_GETSOCKNAME
3560 if (!is_server)
3561 {
3562 struct sockaddr_in sa1;
3563 socklen_t len1 = sizeof (sa1);
3564 if (getsockname (s, (struct sockaddr *)&sa1, &len1) == 0)
3565 contact = Fplist_put (contact, QClocal,
3566 conv_sockaddr_to_lisp ((struct sockaddr *)&sa1, len1));
3567 }
3568#endif
3569 }
3570
3571 immediate_quit = 0;
3572
3573#ifdef HAVE_GETADDRINFO
3574 if (res != &ai)
3575 {
3576 block_input ();
3577 freeaddrinfo (res);
3578 unblock_input ();
3579 }
3580#endif
3581
3582 if (s < 0)
3583 {
3584 /* If non-blocking got this far - and failed - assume non-blocking is
3585 not supported after all. This is probably a wrong assumption, but
3586 the normal blocking calls to open-network-stream handles this error
3587 better. */
3588 if (is_non_blocking_client)
3589 return Qnil;
3590
3591 report_file_errno ((is_server
3592 ? "make server process failed"
3593 : "make client process failed"),
3594 contact, xerrno);
3595 }
3596
3597 inch = s;
3598 outch = s;
3599
3600 if (!NILP (buffer)) 3724 if (!NILP (buffer))
3601 buffer = Fget_buffer_create (buffer); 3725 buffer = Fget_buffer_create (buffer);
3602 proc = make_process (name); 3726 proc = make_process (name);
3603
3604 chan_process[inch] = proc;
3605
3606 fcntl (inch, F_SETFL, O_NONBLOCK);
3607
3608 p = XPROCESS (proc); 3727 p = XPROCESS (proc);
3609
3610 pset_childp (p, contact); 3728 pset_childp (p, contact);
3611 pset_plist (p, Fcopy_sequence (Fplist_get (contact, QCplist))); 3729 pset_plist (p, Fcopy_sequence (Fplist_get (contact, QCplist)));
3612 pset_type (p, Qnetwork); 3730 pset_type (p, Qnetwork);
@@ -3620,135 +3738,38 @@ usage: (make-network-process &rest ARGS) */)
3620 if ((tem = Fplist_get (contact, QCstop), !NILP (tem))) 3738 if ((tem = Fplist_get (contact, QCstop), !NILP (tem)))
3621 pset_command (p, Qt); 3739 pset_command (p, Qt);
3622 p->pid = 0; 3740 p->pid = 0;
3741 p->backlog = 5;
3742 p->is_non_blocking_client = 0;
3743 p->is_server = 0;
3744 p->port = port;
3745 p->socktype = socktype;
3746 p->ai_protocol = ai_protocol;
3623 3747
3624 p->open_fd[SUBPROCESS_STDIN] = inch;
3625 p->infd = inch;
3626 p->outfd = outch;
3627
3628 /* Discard the unwind protect for closing S, if any. */
3629 specpdl_ptr = specpdl + count1;
3630
3631 /* Unwind bind_polling_period and request_sigio. */
3632 unbind_to (count, Qnil); 3748 unbind_to (count, Qnil);
3633 3749
3634 if (is_server && socktype != SOCK_DGRAM) 3750 /* :server BOOL */
3635 pset_status (p, Qlisten); 3751 tem = Fplist_get (contact, QCserver);
3636 3752 if (!NILP (tem))
3637 /* Make the process marker point into the process buffer (if any). */
3638 if (BUFFERP (buffer))
3639 set_marker_both (p->mark, buffer,
3640 BUF_ZV (XBUFFER (buffer)),
3641 BUF_ZV_BYTE (XBUFFER (buffer)));
3642
3643#ifdef NON_BLOCKING_CONNECT
3644 if (is_non_blocking_client)
3645 { 3753 {
3646 /* We may get here if connect did succeed immediately. However, 3754 /* Don't support network sockets when non-blocking mode is
3647 in that case, we still need to signal this like a non-blocking 3755 not available, since a blocked Emacs is not useful. */
3648 connection. */ 3756 p->is_server = 1;
3649 pset_status (p, Qconnect); 3757 if (TYPE_RANGED_INTEGERP (int, tem))
3650 if (!FD_ISSET (inch, &connect_wait_mask)) 3758 p->backlog = XINT (tem);
3651 {
3652 FD_SET (inch, &connect_wait_mask);
3653 FD_SET (inch, &write_mask);
3654 num_pending_connects++;
3655 }
3656 } 3759 }
3657 else
3658#endif
3659 /* A server may have a client filter setting of Qt, but it must
3660 still listen for incoming connects unless it is stopped. */
3661 if ((!EQ (p->filter, Qt) && !EQ (p->command, Qt))
3662 || (EQ (p->status, Qlisten) && NILP (p->command)))
3663 {
3664 FD_SET (inch, &input_wait_mask);
3665 FD_SET (inch, &non_keyboard_wait_mask);
3666 }
3667
3668 if (inch > max_process_desc)
3669 max_process_desc = inch;
3670
3671 tem = Fplist_member (contact, QCcoding);
3672 if (!NILP (tem) && (!CONSP (tem) || !CONSP (XCDR (tem))))
3673 tem = Qnil; /* No error message (too late!). */
3674
3675 {
3676 /* Setup coding systems for communicating with the network stream. */
3677 /* Qt denotes we have not yet called Ffind_operation_coding_system. */
3678 Lisp_Object coding_systems = Qt;
3679 Lisp_Object val;
3680
3681 if (!NILP (tem))
3682 {
3683 val = XCAR (XCDR (tem));
3684 if (CONSP (val))
3685 val = XCAR (val);
3686 }
3687 else if (!NILP (Vcoding_system_for_read))
3688 val = Vcoding_system_for_read;
3689 else if ((!NILP (buffer) && NILP (BVAR (XBUFFER (buffer), enable_multibyte_characters)))
3690 || (NILP (buffer) && NILP (BVAR (&buffer_defaults, enable_multibyte_characters))))
3691 /* We dare not decode end-of-line format by setting VAL to
3692 Qraw_text, because the existing Emacs Lisp libraries
3693 assume that they receive bare code including a sequence of
3694 CR LF. */
3695 val = Qnil;
3696 else
3697 {
3698 if (NILP (host) || NILP (service))
3699 coding_systems = Qnil;
3700 else
3701 coding_systems = CALLN (Ffind_operation_coding_system,
3702 Qopen_network_stream, name, buffer,
3703 host, service);
3704 if (CONSP (coding_systems))
3705 val = XCAR (coding_systems);
3706 else if (CONSP (Vdefault_process_coding_system))
3707 val = XCAR (Vdefault_process_coding_system);
3708 else
3709 val = Qnil;
3710 }
3711 pset_decode_coding_system (p, val);
3712 3760
3713 if (!NILP (tem)) 3761 /* :nowait BOOL */
3714 { 3762 if (!p->is_server && socktype != SOCK_DGRAM
3715 val = XCAR (XCDR (tem)); 3763 && (tem = Fplist_get (contact, QCnowait), !NILP (tem)))
3716 if (CONSP (val)) 3764 {
3717 val = XCDR (val); 3765#ifndef NON_BLOCKING_CONNECT
3718 } 3766 error ("Non-blocking connect not supported");
3719 else if (!NILP (Vcoding_system_for_write)) 3767#else
3720 val = Vcoding_system_for_write; 3768 p->is_non_blocking_client = 1;
3721 else if (NILP (BVAR (current_buffer, enable_multibyte_characters))) 3769#endif
3722 val = Qnil; 3770 }
3723 else
3724 {
3725 if (EQ (coding_systems, Qt))
3726 {
3727 if (NILP (host) || NILP (service))
3728 coding_systems = Qnil;
3729 else
3730 coding_systems = CALLN (Ffind_operation_coding_system,
3731 Qopen_network_stream, name, buffer,
3732 host, service);
3733 }
3734 if (CONSP (coding_systems))
3735 val = XCDR (coding_systems);
3736 else if (CONSP (Vdefault_process_coding_system))
3737 val = XCDR (Vdefault_process_coding_system);
3738 else
3739 val = Qnil;
3740 }
3741 pset_encode_coding_system (p, val);
3742 }
3743 setup_process_coding_systems (proc);
3744
3745 pset_decoding_buf (p, empty_unibyte_string);
3746 p->decoding_carryover = 0;
3747 pset_encoding_buf (p, empty_unibyte_string);
3748
3749 p->inherit_coding_system_flag
3750 = !(!NILP (tem) || NILP (buffer) || !inherit_process_coding_system);
3751 3771
3772 connect_network_socket (proc, ip_addresses);
3752 return proc; 3773 return proc;
3753} 3774}
3754 3775