akaros/tests/listen1.c
<<
>>
Prefs
   1/* 
   2 * This file is part of the UCB release of Plan 9. It is subject to the license
   3 * terms in the LICENSE file found in the top-level directory of this
   4 * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No
   5 * part of the UCB release of Plan 9, including this file, may be copied,
   6 * modified, propagated, or distributed except according to the terms contained
   7 * in the LICENSE file.
   8 */
   9
  10#include <stdlib.h>
  11#include <stdio.h>
  12#include <parlib/parlib.h>
  13#include <unistd.h>
  14#include <signal.h>
  15#include <iplib/iplib.h>
  16#include <iplib/icmp.h>
  17#include <ctype.h>
  18#include <pthread.h>
  19#include <parlib/spinlock.h>
  20#include <parlib/timing.h>
  21#include <parlib/tsc-compat.h>
  22#include <parlib/printf-ext.h>
  23#include <parlib/alarm.h>
  24#include <ndblib/ndb.h>
  25#include <fcntl.h>
  26
  27#include <sys/types.h>
  28#include <sys/wait.h>
  29
  30int verbose;
  31
  32void
  33usage(void)
  34{
  35        fprintf(stderr, "usage: listen1 [-tv] address cmd args...\n");
  36        fprintf(stderr, "usage");
  37        exit(1);
  38}
  39
  40char*
  41remoteaddr(char *dir)
  42{
  43        static char buf[128];
  44        char *p;
  45        int n, fd;
  46
  47        snprintf(buf, sizeof buf, "%s/remote", dir);
  48        fd = open(buf, O_RDONLY);
  49        if(fd < 0)
  50                return "";
  51        n = read(fd, buf, sizeof(buf));
  52        close(fd);
  53        if(n > 0){
  54                buf[n] = 0;
  55                p = strchr(buf, '!');
  56                if(p)
  57                        *p = 0;
  58                return buf;
  59        }
  60        return "";
  61}
  62
  63void
  64main(int argc, char **argv)
  65{
  66        static char data[1024], dir[1024], ndir[1024];
  67        int ctl, nctl, fd;
  68
  69        verbose = 1;
  70
  71        if(!verbose){
  72                close(1);
  73                fd = open("/dev/null", O_WRONLY);
  74                if(fd != 1){
  75                        dup2(fd, 1);
  76                        close(fd);
  77                }
  78        }
  79
  80        argc--, argv++;
  81        printf("listen started\n");
  82        ctl = announce9(argv[0], dir, 0);
  83        if(ctl < 0){
  84                fprintf(stderr, "announce %s: %r", argv[0]);
  85                exit(1);
  86        }
  87
  88        for(;;){
  89                nctl = listen9(dir, ndir, 0);
  90                if(nctl < 0){
  91                        fprintf(stderr, "listen %s: %r", argv[0]);
  92                        exit(1);
  93                }
  94
  95                //switch(rfork(RFFDG|RFPROC|RFNOWAIT|RFENVG|RFNAMEG|RFNOTEG)){
  96                switch(fork()){
  97                case -1:
  98                        reject9(nctl, ndir, "host overloaded");
  99                        close(nctl);
 100                        continue;
 101                case 0:
 102                        fd = accept9(nctl, ndir);
 103                        if(fd < 0){
 104                                fprintf(stderr,
 105                                        "accept %s: can't open  %s/data: %r\n",
 106                                        argv[0], ndir);
 107                                exit(1);
 108                        }
 109                        printf("incoming call for %s from %s in %s\n", argv[0],
 110                                remoteaddr(ndir), ndir);
 111                        //fprintf(nctl, "keepalive");
 112                        close(ctl);
 113                        close(nctl);
 114                        //putenv("net", ndir);
 115                        /* this is for children that open /dev/cons. Too bad. 
 116                        snprintf(data, sizeof data, "%s/data", ndir);
 117                        bind(data, "/dev/cons", MREPL);
 118                        */
 119                        dup2(fd, 0);
 120                        dup2(fd, 1);
 121                        dup2(fd, 2);
 122                        close(fd);
 123                        execv(argv[1], argv+1);
 124//                      if(argv[1][0] != '/')
 125//                              exec(smprintf("%s", argv[1]), argv+1);
 126                        fprintf(stderr, "exec: %r\n");
 127                        exit(1);
 128                default:
 129                        /* reap any available children */
 130                        while (waitpid(-1, 0, WNOHANG) > 0)
 131                                ;
 132                        close(nctl);
 133                        break;
 134                }
 135        }
 136}
 137