This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
Revert two commits that fix a VOL declaration.
[perl5.git] / mpeix / mpeix.c
CommitLineData
feb33499
JH
1
2/*
3 * gcc long pointer support code for HPPA.
4 * Copyright 1998, DIS International, Ltd.
c72515e3
JH
5 * This code is free software; you may redistribute it and/or modify
6 * it under the same terms as Perl itself. (Relicensed for Perl in
7 * in April 2002 by Mark Klein.)
feb33499
JH
8 */
9typedef struct {
10 int spaceid;
11 unsigned int offset;
12 } LONGPOINTER, longpointer;
13
14/*
15 * gcc long pointer support code for HPPA.
16 * Copyright 1998, DIS International, Ltd.
c72515e3
JH
17 * This code is free software; you may redistribute it and/or modify
18 * it under the same terms as Perl itself. (Relicensed for Perl in
19 * in April 2002 by Mark Klein.)
feb33499
JH
20 */
21
22int __perl_mpe_getspaceid(void *source)
23 {
24 int val;
25 /*
26 * Given the short pointer, determine it's space ID.
27 */
28
29 /*
30 * The colons separate output from input parameters. In this case,
31 * the output of the instruction (output indicated by the "=" in the
32 * constraint) is to a memory location (indicated by the "m"). The
33 * input constraint indicates that the source to the instruction
34 * is a register reference (indicated by the "r").
35 * The general format is:
36 * asm("<instruction template>" : <output> : <input> : <clobbers>);
37 * where <output> and <input> are:
38 * "<constraint>" (<token>)
39 * <instruction template> is the PA-RISC instruction in template fmt.
40 * <clobbers> indicates those registers clobbered by the instruction
41 * and provides hints to the optimizer.
42 *
eb863851 43 * Refer to the gcc documentation
feb33499 44 */
4cbfc073
JH
45 __asm__ __volatile__ (
46 " comiclr,= 0,%1,%%r28\n"
47 "\t ldsid (%%r0,%1),%%r28\n"
48 "\t stw %%r28, %0"
feb33499
JH
49 : "=m" (val) // Output to val
50 : "r" (source) // Source must be gen reg
51 : "%r28"); // Clobbers %r28
52 return (val);
53 };
54
55LONGPOINTER __perl_mpe_longaddr(void *source)
56 {
57 LONGPOINTER lptr;
58 /*
59 * Return the long pointer for the address in sr5 space.
60 */
61
4cbfc073
JH
62 __asm__ __volatile__ (
63 " comiclr,= 0,%2,%%r28\n"
64 "\t ldsid (%%r0,%2),%%r28\n"
65 "\t stw %%r28, %0\n"
66 "\t stw %2, %1"
feb33499
JH
67 : "=m" (lptr.spaceid),
68 "=m" (lptr.offset) // Store to lptr
69 : "r" (source) // Source must be gen reg
70 : "%r28"); // Clobbers %r28
71 return (lptr);
72 };
73
74LONGPOINTER __perl_mpe_addtopointer(LONGPOINTER source, // %r26 == source offset
75 // %r25 == source space
76 int len) // %r24 == length in bytes
77 {
78 /*
79 * Increment a longpointer.
80 */
81
4cbfc073
JH
82 __asm__ __volatile__ (
83 " copy %0,%%r28\n" // copy space to r28
84 "\t add %1,%2,%%r29" // Increment the pointer
feb33499
JH
85 : // No output
86 : "r" (source.spaceid), // Source address
87 "r" (source.offset),
88 "r" (len) // Length
89 : "%r28", // Clobbers
90 "%r29");
91 };
92
93void __perl_mpe_longmove(int len, // %r26 == byte length
94 LONGPOINTER source, // %r23 == source space, %r24 == off
95 LONGPOINTER target) // sp-#56 == target space, sp-#52== off
96 {
97 /*
98 * Move data between two buffers in long pointer space.
99 */
100
4cbfc073
JH
101 __asm__ __volatile__ (
102 " .import $$lr_unk_unk_long,MILLICODE\n"
103 "\t mtsp %0,%%sr1\n" // copy source space to sr1
104 "\t copy %1,%%r26\n" // load source offset to r26
105 "\t copy %4,%%r24\n" // load length to r24
106 "\t copy %3,%%r25\n" // load target offset to r25
107 "\t bl $$lr_unk_unk_long,%%r31\n" // start branch to millicode
108 "\t mtsp %2,%%sr2" // copy target space to sr2
feb33499
JH
109 : // No output
110 : "r" (source.spaceid), // Source address
111 "r" (source.offset),
112 "r" (target.spaceid), // Target address
113 "r" (target.offset),
114 "r" (len) // Byte length
115 : "%r1", // Clobbers
116 "%r24",
117 "%r25",
118 "%r26",
119 "%r31");
120 };
121
122int __perl_mpe_longpeek(LONGPOINTER source)
123 {
124 /*
125 * Fetch the int in long pointer space.
126 */
127 unsigned int val;
128
4cbfc073
JH
129 __asm__ __volatile__ (
130 " mtsp %1, %%sr1\n"
131 "\t copy %2, %%r28\n"
132 "\t ldw 0(%%sr1, %%r28), %%r28\n"
133 "\t stw %%r28, %0"
feb33499
JH
134 : "=m" (val) // Output val
135 : "r" (source.spaceid), // Source space ID
136 "r" (source.offset) // Source offset
137 : "%r28"); // Clobbers %r28
138
139 return (val);
140 };
141
142void __perl_mpe_longpoke(LONGPOINTER target, // %r25 == spaceid, %r26 == offset
143 unsigned int val) // %r24 == value
144 {
145 /*
146 * Store the val into long pointer space.
147 */
4cbfc073
JH
148 __asm__ __volatile__ (
149 " mtsp %0,%%sr1\n"
150 "\t copy %1, %%r28\n"
151 "\t stw %2, 0(%%sr1, %%r28)"
feb33499
JH
152 : // No output
153 : "r" (target.spaceid), // Target space ID
154 "r" (target.offset), // Target offset
155 "r" (val) // Value to store
156 : "%r28" // Clobbers %r28
157 ); // Copy space to %sr1
158 };
159
160void __perl_mpe_move_fast(int len, // %r26 == byte length
161 void *source, // %r25 == source addr
162 void *target) // %r24 == target addr
163 {
164 /*
165 * Move using short pointers.
166 */
4cbfc073
JH
167 __asm__ __volatile__ (
168 " .import $$lr_unk_unk,MILLICODE\n"
169 "\t copy %1, %%r26\n" // Move source addr into pos
170 "\t copy %2, %%r25\n" // Move target addr into pos
171 "\t bl $$lr_unk_unk,%%r31\n" // Start branch to millicode
172 "\t copy %0, %%r24" // Move length into position
feb33499
JH
173 : // No output
174 : "r" (len), // Byte length
175 "r" (source), // Source address
176 "r" (target) // Target address
177 : "%r24", // Clobbers
178 "%r25",
179 "%r26",
180 "%r31");
181 };
182
183/*
184 * ftruncate - set file size, BSD Style
185 *
186 * shortens or enlarges the file as neeeded
187 * uses some undocumented locking call. It is known to work on SCO unix,
188 * other vendors should try.
189 * The #error directive prevents unsupported OSes
c72515e3
JH
190 *
191 * ftruncate/truncate code by Mark Bixby.
192 * This code is free software; you may redistribute it and/or modify
193 * it under the same terms as Perl itself.
194 *
feb33499
JH
195 */
196
f382e41b
KH
197#ifndef _POSIX_SOURCE
198# define _POSIX_SOURCE
199#endif
200#ifndef _SOCKET_SOURCE
201# define _SOCKET_SOURCE
202#endif
feb33499
JH
203#include <unistd.h>
204#include <errno.h>
205#include <fcntl.h>
206#include <stdio.h>
f382e41b
KH
207#include <string.h>
208#include <sys/socket.h>
209#include <limits.h>
feb33499
JH
210#include <mpe.h>
211
212extern void FCONTROL(short, short, longpointer);
213extern void PRINTFILEINFO(int);
214
215int ftruncate(int fd, long wantsize);
216
f382e41b
KH
217int
218ftruncate(int fd, long wantsize)
219{
220 int ccode_return,dummy=0;
feb33499 221
f382e41b
KH
222 if (lseek(fd, wantsize, SEEK_SET) < 0)
223 {
224 return (-1);
225 }
feb33499 226
f382e41b
KH
227 FCONTROL(_mpe_fileno(fd),6,__perl_mpe_longaddr(&dummy)); /* Write new EOF */
228 if ((ccode_return=ccode()) != CCE)
229 {
230 fprintf(stderr,
231 "MPE ftruncate failed, ccode=%d, wantsize=%ld\n",
232 ccode_return, wantsize);
233 PRINTFILEINFO(_mpe_fileno(fd));
234 errno = ESYSERR;
235 return (-1);
236 }
237
238 return (0);
feb33499
JH
239}
240
241/*
242 wrapper for truncate():
243
244 truncate() is UNIX, not POSIX.
245
246 This function requires ftruncate().
247
248
249
250 NAME
251 truncate -
252
253 SYNOPSIS
254 #include <unistd.h>
255
256 int truncate(const char *pathname, off_t length);
257
258 Returns: 0 if OK, -1 on error
259
260 from: Stevens' Advanced Programming in the UNIX Environment, p. 92
261
262
263
264 ERRORS
265 EACCES
266 EBADF
267 EDQUOT (not POSIX) <- not implemented here
268 EFAULT
269 EINVAL
270 EISDIR
271 ELOOP (not POSIX) <- not implemented here
272 ENAMETOOLONG
273 ENOTDIR
274 EROFS
275 ETXTBSY (not POSIX) <- not implemented here
276
277 from: HP-UX man page
278
279
280
281 Compile directives:
282 PRINT_ERROR - make this function print an error message to stderr
283*/
284
feb33499 285
f382e41b
KH
286#include <sys/types.h> /* off_t, required by open() */
287#include <sys/stat.h> /* required by open() */
288#include <fcntl.h> /* open() */
289#include <unistd.h> /* close() */
290#include <stdio.h> /* perror(), sprintf() */
feb33499
JH
291
292
293
294int
295truncate(const char *pathname, off_t length)
296{
f382e41b 297 int fd;
feb33499 298#ifdef PRINT_ERROR
f382e41b 299 char error_msg[80+1];
feb33499
JH
300#endif
301
f382e41b
KH
302 if (length == 0)
303 {
304 if ( (fd = open(pathname, O_WRONLY | O_TRUNC)) < 0)
305 {
306 /* errno already set */
feb33499 307#ifdef PRINT_ERROR
f382e41b
KH
308 sprintf(error_msg,
309 "truncate(): open(%s, O_WRONLY | OTRUNC)\0",
310 pathname);
311 perror(error_msg);
feb33499 312#endif
f382e41b
KH
313 return -1;
314 }
315 }
316 else
317 {
318 if ( (fd = open(pathname, O_WRONLY)) < 0)
319 {
320 /* errno already set */
feb33499 321#ifdef PRINT_ERROR
f382e41b
KH
322 sprintf(error_msg,
323 "truncate(): open(%s, O_WRONLY)\0",
324 pathname);
325 perror(error_msg);
feb33499 326#endif
f382e41b
KH
327 return -1;
328 }
feb33499 329
f382e41b
KH
330 if (ftruncate(fd, length) < 0)
331 {
332 /* errno already set */
feb33499 333#ifdef PRINT_ERROR
f382e41b 334 perror("truncate(): ftruncate()");
feb33499 335#endif
f382e41b
KH
336 return -1;
337 }
338 }
feb33499 339
f382e41b
KH
340 if (close(fd) < 0)
341 {
342 /* errno already set */
feb33499 343#ifdef PRINT_ERROR
f382e41b 344 perror("truncate(): close()");
feb33499 345#endif
f382e41b
KH
346 return -1;
347 }
feb33499 348
f382e41b 349 return 0;
feb33499
JH
350} /* truncate() */
351
352/*
353 wrapper for gettimeofday():
354 gettimeofday() is UNIX, not POSIX.
355 gettimeofday() is a BSD function.
356
feb33499
JH
357 NAME
358 gettimeofday -
359
360 SYNOPSIS
361 #include <sys/time.h>
362
363 int gettimeofday(struct timeval *tp, struct timezone *tzp);
364
365 DESCRIPTION
366 This function returns seconds and microseconds since midnight
367 January 1, 1970. The microseconds is actually only accurate to
368 the millisecond.
369
370 Note: To pick up the definitions of structs timeval and timezone
371 from the <time.h> include file, the directive
372 _SOCKET_SOURCE must be used.
373
374 RETURN VALUE
375 A 0 return value indicates that the call succeeded. A -1 return
376 value indicates an error occurred; errno is set to indicate the
377 error.
378
379 ERRORS
380 EFAULT not implemented
381
382 Changes:
383 2-91 DR. Created.
384*/
385
386
387/* need _SOCKET_SOURCE to pick up structs timeval and timezone in time.h */
388#ifndef _SOCKET_SOURCE
389# define _SOCKET_SOURCE
390#endif
391
f382e41b
KH
392#include <time.h> /* structs timeval & timezone,
393 difftime(), localtime(), mktime(), time() */
feb33499
JH
394
395extern int TIMER();
396
c72515e3
JH
397/*
398 * gettimeofday code by Mark Bixby.
399 * This code is free software; you may redistribute it and/or modify
400 * it under the same terms as Perl itself.
401 */
feb33499
JH
402
403#ifdef __STDC__
404int gettimeofday( struct timeval *tp, struct timezone *tpz )
405#else
406int gettimeofday( tp, tpz )
407struct timeval *tp;
408struct timezone *tpz;
409#endif
410{
411 static unsigned long basetime = 0;
412 static int dsttime = 0;
413 static int minuteswest = 0;
414 static int oldtime = 0;
415 register int newtime;
416
417
418 /*-------------------------------------------------------------------*/
419 /* Setup a base from which all future time will be computed. */
420 /*-------------------------------------------------------------------*/
421 if ( basetime == 0 )
422 {
423 time_t gmt_time;
424 time_t loc_time;
425 struct tm *loc_time_tm;
426
427 gmt_time = time( NULL );
428 loc_time_tm = localtime( &gmt_time ) ;
429 loc_time = mktime( loc_time_tm );
430
431 oldtime = TIMER();
432 basetime = (unsigned long) ( loc_time - (oldtime/1000) );
433
434 /*----------------------------------------------------------------*/
435 /* The calling process must be restarted if timezone or dst */
436 /* changes. */
437 /*----------------------------------------------------------------*/
438 minuteswest = (int) (difftime( loc_time, gmt_time ) / 60);
439 dsttime = loc_time_tm->tm_isdst;
440 }
441
442 /*-------------------------------------------------------------------*/
443 /* Get the new time value. The timer value rolls over every 24 days, */
444 /* so if the delta is negative, the basetime value is adjusted. */
445 /*-------------------------------------------------------------------*/
446 newtime = TIMER();
447 if ( newtime < oldtime ) basetime += 2073600;
448 oldtime = newtime;
449
450 /*-------------------------------------------------------------------*/
451 /* Return the timestamp info. */
452 /*-------------------------------------------------------------------*/
453 tp->tv_sec = basetime + newtime/1000;
454 tp->tv_usec = (newtime%1000) * 1000; /* only accurate to milli */
455 if (tpz)
456 {
457 tpz->tz_minuteswest = minuteswest;
458 tpz->tz_dsttime = dsttime;
459 }
460
461 return 0;
462
463} /* gettimeofday() */
b606c525
JH
464
465/*
466** MPE_FCNTL -- shadow function for fcntl()
467**
f382e41b
KH
468** MPE requires sfcntl() for sockets, and fcntl() for everything
469** else. This shadow routine determines the descriptor type and
470** makes the appropriate call.
b606c525 471**
f382e41b
KH
472** Parameters:
473** same as fcntl().
b606c525 474**
f382e41b
KH
475** Returns:
476** same as fcntl().
b606c525
JH
477*/
478
479#include <stdarg.h>
480#include <sys/socket.h>
481
482int
483mpe_fcntl(int fildes, int cmd, ...)
484{
f382e41b
KH
485 int len, result;
486 struct sockaddr sa;
487
488 void *arg;
489 va_list ap;
490
491 va_start(ap, cmd);
492 arg = va_arg(ap, void *);
493 va_end(ap);
494
495 len = sizeof sa;
496 if (getsockname(fildes, &sa, &len) == -1)
497 {
498 if (errno == EAFNOSUPPORT)
499 /* AF_UNIX socket */
500 return sfcntl(fildes, cmd, arg);
501
502 if (errno == ENOTSOCK)
503 /* file or pipe */
504 return fcntl(fildes, cmd, arg);
505
506 /* unknown getsockname() failure */
507 return (-1);
508 }
509 else
510 {
511 /* AF_INET socket */
512 if ((result = sfcntl(fildes, cmd, arg)) != -1 && cmd == F_GETFL)
513 result |= O_RDWR; /* fill in some missing flags */
514 return result;
515 }
516}
517
518
519
520/*
521 * Stuff from here on down is written by Ken Hirsch
522 * and you may use it for any purpose.
523 * No warranty, express or implied.
524 */
525
526#include <stddef.h>
527#include <sys/ioctl.h>
528#include <netinet/in.h>
529
530#ifndef _SOCKLEN_T
531typedef unsigned int socklen_t;
532#define _SOCKLEN_T
533#endif
534
535static int max_io_size(int filedes);
536
537ssize_t
538mpe_read(int filedes, void *buffer, size_t len)
539{
540 int maxio;
541 if (len > 4096 && (len > (maxio = max_io_size(filedes))))
542 len = maxio;
543
544 return read(filedes, buffer, len);
545}
546
547ssize_t
548mpe_write(int filedes, const void *buffer, size_t len)
549{
550 int written = 0;
551 int orig_len = len;
552 int maxio = (len>4096)?max_io_size(filedes):INT_MAX;
553 const char *buf = (const char *)buffer;
554
555 do {
556 written = write(filedes, buf, len>maxio?maxio:len);
557 if (written < 0)
558 break;
559 len -= written;
560 buf += written;
561 } while (len > 0);
562
563 if (written < 0 && len == orig_len)
564 return -1;
565 else
566 return orig_len - len;
567}
568
569
570ssize_t
571mpe_send(int socket, const void *buffer, size_t len, int flags)
572{
573 int written = 0;
574 int orig_len = len;
575 int maxio = (len>4096)?max_io_size(socket):INT_MAX;
576 const char *buf = (const char *)buffer;
577
578 do {
579 written = send(socket, buf, len>maxio?maxio:len, flags);
580 if (written < 0)
581 break;
582 len -= written;
583 buf += written;
584 } while (len > 0);
585
586 if (written < 0 && len == orig_len)
587 return -1;
588 else
589 return orig_len - len;
590}
591
592ssize_t
593mpe_sendto(int socket, const void *buffer, size_t len,
594 int flags, const struct sockaddr *dest_addr,
595 socklen_t dest_len)
596{
597 int written = 0;
598 int orig_len = len;
599 int maxio = (len>4096)?max_io_size(socket):INT_MAX;
600 const char *buf = (const char *)buffer;
601
602 do {
603 written =
604 sendto(socket, buf, len>maxio?maxio:len, flags, dest_addr, dest_len);
605 if (written < 0)
606 break;
607 len -= written;
608 buf += written;
609 } while (len > 0);
610
611 if (written < 0 && len == orig_len)
612 return -1;
613 else
614 return orig_len - len;
615}
616
617
618ssize_t
619mpe_recv(int socket, void *buffer, size_t len, int flags)
620{
621 int maxio;
622 if (len > 4096 && (len > (maxio = max_io_size(socket))))
623 len = maxio;
624 return recv(socket, buffer, len, flags);
625}
626
627ssize_t
628mpe_recvfrom(int socket, void *buffer, size_t len,
629 int flags, struct sockaddr *address,
630 socklen_t *address_len)
631{
632 int maxio;
633 if (len > 4096 && (len > (maxio = max_io_size(socket))))
634 len = maxio;
635 return recvfrom(socket, buffer, len, flags, address, address_len);
636}
637
638/*
639 I didn't do thse two:
640ssize_t mpe_recvmsg(int, struct msghdr *, int);
641ssize_t mpe_sendmsg(int, const struct msghdr *, int);
642*/
643
644/*
645 * On MPE/iX (at least version 6.0), a getsockname()
646 * performed on a socket that is listening
647 * will return INADDR_ANY, even if you used
648 * bind to bind it to a particular IP address.
649 *
650 * (In fact, it appears that the socket always acts as
651 * if you used INADDR_ANY.)
652 *
653 * Here I save the IP address used in bind
654 * So I can get it in getsockname()
655 *
656 */
657
658/* I just save 40. Usually one or two should be enough
659 */
660
661int
662mpe_connect(int socket,
663 const struct sockaddr *address,
664 socklen_t address_len)
665{
666 int ret = connect(socket, address, address_len);
667 if (ret < 0 && errno == EINPROGRESS)
668 {
669 /* Need to call getsockopt to clear socket error */
670 int socket_error;
671 socklen_t err_size = sizeof(socket_error);
672 (void)getsockopt(socket, SOL_SOCKET, SO_ERROR,
673 &socket_error, &err_size);
674 errno = EINPROGRESS;
675 }
676 return ret;
677}
678
679static struct {
680 int fd;
681 struct in_addr holdaddr;
682} holdbind[40];
683#define HOLDBINDLAST ((sizeof(holdbind))/(sizeof(holdbind[0])))
684static int nextbind;
685
686/*
687 * Fix peculiarities of bind() on MPE
688 * 1. call GETPRIVMODE to bind to ports < 1024
689 * 2. save IP address for future calls to getsockname
690 * 3. set IP address to 0 (INADDR_ANY)
691 */
692
693int
694mpe_bind(int socket, const struct sockaddr *address, socklen_t address_len)
695{
696 int i;
697 int result;
698 int mpeprivmode=0;
699 extern void GETPRIVMODE(void);
700 extern void GETUSERMODE(void);
701
702 for (i = 0; i<HOLDBINDLAST; i++) {
703 if (holdbind[i].fd == socket)
704 break;
705 }
706 /* If we didn't find previously used slot, use next */
707 if (i == HOLDBINDLAST)
708 i = nextbind;
709
710 holdbind[i].fd = socket;
711
712 memset(&holdbind[i].holdaddr, '\0', sizeof(holdbind[i].holdaddr));
713 if (address->sa_family == AF_INET
714 && address_len >= offsetof(struct sockaddr_in, sin_addr)
715 +sizeof(struct in_addr)) {
716 holdbind[i].holdaddr = ((struct sockaddr_in *)address)->sin_addr;
717 }
718 if (i == nextbind)
719 {
720 if (++nextbind >= HOLDBINDLAST)
721 nextbind = 0;
722 }
723
724 if (address->sa_family == AF_INET)
725 {
726 /* The address *MUST* stupidly be zero. */
727 ((struct sockaddr_in *)address)->sin_addr.s_addr = INADDR_ANY;
728 /* PRIV mode is required to bind() to ports < 1024. */
729 if (((struct sockaddr_in *)address)->sin_port < 1024 &&
730 ((struct sockaddr_in *)address)->sin_port > 0) {
731 GETPRIVMODE(); /* If this fails, we are aborted by MPE/iX. */
732 mpeprivmode = 1;
733 }
734 }
735 result = bind(socket, address, address_len);
736 if (mpeprivmode)
737 {
738 GETUSERMODE();
739 }
740 return result;
741
742}
743
744int
745mpe_getsockname(int socket, struct sockaddr *address, socklen_t *address_len)
746{
747 int ret;
748 ret = getsockname(socket, address, address_len);
749 if (ret == 0
750 && address->sa_family == AF_INET
751 && *address_len >= offsetof(struct sockaddr_in, sin_addr)
752 +sizeof(struct in_addr)
753 && ((struct sockaddr_in *)address)->sin_addr.s_addr == INADDR_ANY) {
754 int i;
755 for (i=0; i<HOLDBINDLAST; i++) {
756 if (holdbind[i].fd == socket)
757 {
758 ((struct sockaddr_in *)address)->sin_addr.s_addr
759 = holdbind[i].holdaddr.s_addr;
760 break;
761 }
762 }
763 }
764 return ret;
765}
766
767int
768mpe_getpeername(int socket, struct sockaddr *address, socklen_t *address_len)
769{
770 int ret;
771 ret = getpeername(socket, address, address_len);
772 if (ret == 0)
773 {
774 /* Try a zero-length write to see if socket really connected */
775 int written = write(socket, "", 0);
776 if (written < 0)
777 ret = -1;
778 }
779 return ret;
780}
781
782
783static int
784max_io_size(int filedes)
785{
786 int save_errno;
787 struct sockaddr sa;
788 int len;
789 int result = INT_MAX; /* all other files */
790
791 save_errno = errno;
792 len = sizeof sa;
793 if (getsockname(filedes, &sa, &len) == -1)
794 {
795 if (errno == EAFNOSUPPORT) /* AF_UNIX socket */
796 result = 4096;
797 errno = save_errno;
798 } else {
799 result = 30000; /* AF_INET sock max */
800 }
801 return result;
b606c525 802}