"Fossies" - the Fresh Open Source Software Archive

Member "links-1.03/beos.c" (15 Nov 2011, 5184 Bytes) of archive /linux/www/links-1.03.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "beos.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.8_vs_1.03.

    1 /* beos.c
    2  * (c) 2002 Mikulas Patocka
    3  * This file is a part of the Links program, released under GPL
    4  */
    5 
    6 #if defined(__BEOS__) || defined(__HAIKU__)
    7 
    8 #include <stdio.h>
    9 #include <stdlib.h>
   10 #include <unistd.h>
   11 #include <fcntl.h>
   12 #include <sys/types.h>
   13 #include <sys/socket.h>
   14 #include <sys/time.h>
   15 #include <netinet/in.h>
   16 #include <be/kernel/OS.h>
   17 
   18 #define SHS 128
   19 
   20 #ifndef MAXINT
   21 #define MAXINT 0x7fffffff
   22 #endif
   23 
   24 #ifdef __HAIKU__
   25 int closesocket(int);
   26 #endif
   27 
   28 int be_read(int s, void *ptr, int len)
   29 {
   30     if (s >= SHS) return recv(s - SHS, ptr, len, 0);
   31     return read(s, ptr, len);
   32 }
   33 
   34 int be_write(int s, void *ptr, int len)
   35 {
   36     if (s >= SHS) return send(s - SHS, ptr, len, 0);
   37     return write(s, ptr, len);
   38 }
   39 
   40 int be_close(int s)
   41 {
   42     if (s >= SHS) return closesocket(s - SHS);
   43     return close(s);
   44 }
   45 
   46 int be_socket(int af, int sock, int prot)
   47 {
   48     int h = socket(af, sock, prot);
   49     if (h < 0) return h;
   50     return h + SHS;
   51 }
   52 
   53 int be_connect(int s, struct sockaddr *sa, int sal)
   54 {
   55     return connect(s - SHS, sa, sal);
   56 }
   57 
   58 int be_getpeername(int s, struct sockaddr *sa, int *sal)
   59 {
   60     return getpeername(s - SHS, sa, sal);
   61 }
   62 
   63 int be_getsockname(int s, struct sockaddr *sa, int *sal)
   64 {
   65     return getsockname(s - SHS, sa, sal);
   66 }
   67 
   68 int be_listen(int s, int c)
   69 {
   70     return listen(s - SHS, c);
   71 }
   72 
   73 int be_accept(int s, struct sockaddr *sa, int *sal)
   74 {
   75     int a = accept(s - SHS, sa, sal);
   76     if (a < 0) return -1;
   77     return a + SHS;
   78 }
   79 
   80 int be_bind(int s, struct sockaddr *sa, int sal)
   81 {
   82     /*struct sockaddr_in *sin = (struct sockaddr_in *)sa;
   83     if (!sin->sin_port) {
   84         int i;
   85         for (i = 16384; i < 49152; i++) {
   86             sin->sin_port = i;
   87             if (!be_bind(s, sa, sal)) return 0;
   88         }
   89         return -1;
   90     }*/
   91     if (bind(s - SHS, sa, sal)) return -1;
   92     getsockname(s - SHS, sa, &sal);
   93     return 0;
   94 }
   95 
   96 #define PIPE_RETRIES    10
   97 
   98 int be_pipe(int *fd)
   99 {
  100     int s1, s2, s3, l;
  101     struct sockaddr_in sa1, sa2;
  102     int retry_count = 0;
  103     again:
  104     if ((s1 = be_socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
  105         /*perror("socket1");*/
  106         goto fatal_retry;
  107     }
  108     if ((s2 = be_socket(PF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0) {
  109         /*perror("socket2");*/
  110         be_close(s1);
  111         goto fatal_retry;
  112     }
  113     memset(&sa1, 0, sizeof(sa1));
  114     sa1.sin_family = AF_INET;
  115     sa1.sin_port = 0;
  116     sa1.sin_addr.s_addr = INADDR_ANY;
  117     if (be_bind(s1, (struct sockaddr *)&sa1, sizeof(sa1))) {
  118         /*perror("bind");*/
  119         clo:
  120         be_close(s1);
  121         be_close(s2);
  122         goto fatal_retry;
  123     }
  124     if (be_listen(s1, 1)) {
  125         /*perror("listen");*/
  126         goto clo;
  127     }
  128     if (be_connect(s2, (struct sockaddr *)&sa1, sizeof(sa1))) {
  129         /*perror("connect");*/
  130         goto clo;
  131     }
  132     l = sizeof(sa2);
  133     if ((s3 = be_accept(s1, (struct sockaddr *)&sa2, &l)) < 0) {
  134         /*perror("accept");*/
  135         goto clo;
  136     }
  137     be_getsockname(s3, (struct sockaddr *)&sa1, &l);
  138     if (sa1.sin_addr.s_addr != sa2.sin_addr.s_addr) {
  139         be_close(s3);
  140         goto clo;
  141     }
  142     be_close(s1);
  143     fd[0] = s2;
  144     fd[1] = s3;
  145     return 0;
  146 
  147     fatal_retry:
  148     if (++retry_count > PIPE_RETRIES) return -1;
  149     sleep(1);
  150     goto again;
  151 }
  152 
  153 int be_select(int n, struct fd_set *rd, struct fd_set *wr, struct fd_set *exc, struct timeval *tm)
  154 {
  155     int i, s;
  156     struct fd_set d, rrd;
  157     FD_ZERO(&d);
  158     if (!rd) rd = &d;
  159     if (!wr) wr = &d;
  160     if (!exc) exc = &d;
  161     if (n >= FD_SETSIZE) n = FD_SETSIZE;
  162     FD_ZERO(exc);
  163     for (i = 0; i < n; i++) if ((i < SHS && FD_ISSET(i, rd)) || FD_ISSET(i, wr)) {
  164         for (i = SHS; i < n; i++) FD_CLR(i, rd);
  165         return MAXINT;
  166     }
  167     FD_ZERO(&rrd);
  168     for (i = SHS; i < n; i++) if (FD_ISSET(i, rd)) FD_SET(i - SHS, &rrd);
  169     if ((s = select(FD_SETSIZE, &rrd, &d, &d, tm)) < 0) {
  170         FD_ZERO(rd);
  171         return 0;
  172     }
  173     FD_ZERO(rd);
  174     for (i = SHS; i < n; i++) if (FD_ISSET(i - SHS, &rrd)) FD_SET(i, rd);
  175     return s;
  176 }
  177 
  178 #ifndef SO_ERROR
  179 #define SO_ERROR    10001
  180 #endif
  181 
  182 int be_getsockopt(int s, int level, int optname, void *optval, int *optlen)
  183 {
  184     if (optname == SO_ERROR && *optlen >= sizeof(int)) {
  185         *(int *)optval = 0;
  186         *optlen = sizeof(int);
  187         return 0;
  188     }
  189     return -1;
  190 }
  191 
  192 int start_thr(void (*)(void *), void *, unsigned char *);
  193 
  194 int ihpipe[2];
  195 
  196 int inth;
  197 
  198 #include <errno.h>
  199 
  200 void input_handle_th(void *p)
  201 {
  202     char c;
  203     int b = 0;
  204     setsockopt(ihpipe[1], SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
  205     while (1) if (read(0, &c, 1) == 1) be_write(ihpipe[1], &c, 1);
  206 }
  207 
  208 int get_input_handle()
  209 {
  210     static int h = -1;
  211     if (h >= 0) return h;
  212     if (be_pipe(ihpipe) < 0) return -1;
  213     if ((inth = start_thr(input_handle_th, NULL, "input_thread")) < 0) {
  214         closesocket(ihpipe[0]);
  215         closesocket(ihpipe[1]);
  216         fprintf(stderr, "Can't spawn input thread");
  217         exit(4);
  218     }
  219     return h = ihpipe[0];
  220 }
  221 
  222 void block_stdin()
  223 {
  224     suspend_thread(inth);
  225 }
  226 
  227 void unblock_stdin()
  228 {
  229     resume_thread(inth);
  230 }
  231 
  232 /*int ohpipe[2];
  233 
  234 #define O_BUF   16384
  235 
  236 void output_handle_th(void *p)
  237 {
  238     char *c = malloc(O_BUF);
  239     int r, b = 0;
  240     if (!c) return;
  241     setsockopt(ohpipe[1], SOL_SOCKET, SO_NONBLOCK, &b, sizeof(b));
  242     while ((r = be_read(ohpipe[0], c, O_BUF)) > 0) write(1, c, r);
  243     free(c);
  244 }
  245 
  246 int get_output_handle()
  247 {
  248     static int h = -1;
  249     if (h >= 0) return h;
  250     if (be_pipe(ohpipe) < 0) return -1;
  251     if (start_thr(output_handle_th, NULL, "output_thread") < 0) {
  252         closesocket(ohpipe[0]);
  253         closesocket(ohpipe[1]);
  254         fprintf(stderr, "Can't spawn output thread");
  255         exit(4);
  256     }
  257     return h = ohpipe[1];
  258 }*/
  259 
  260 #else
  261 
  262 typedef int beos_c_no_empty_unit;
  263 
  264 #endif