github.com/wasilibs/wazerox@v0.0.0-20240124024944-4923be63ab5f/imports/wasi_snapshot_preview1/testdata/zig-cc/wasi.c (about)

     1  #include <dirent.h>
     2  #include <errno.h>
     3  #include <fcntl.h>
     4  #include <stdio.h>
     5  #include <string.h>
     6  #include <unistd.h>
     7  #include <stdbool.h>
     8  #include <sys/select.h>
     9  #include <sys/socket.h>
    10  #include <sys/types.h>
    11  #include <stdlib.h>
    12  #include <time.h>
    13  
    14  #define formatBool(b) ((b) ? "true" : "false")
    15  
    16  void main_ls(char *dir_name, bool repeat) {
    17    DIR *d;
    18    struct dirent *dir;
    19    d = opendir(dir_name);
    20    if (d) {
    21      while ((dir = readdir(d)) != NULL) {
    22        printf("./%s\n", dir->d_name);
    23      }
    24      if (repeat) {
    25        rewinddir(d);
    26        while ((dir = readdir(d)) != NULL) {
    27          printf("./%s\n", dir->d_name);
    28        }
    29      }
    30      closedir(d);
    31    } else if (errno == ENOTDIR) {
    32      printf("ENOTDIR\n");
    33    } else {
    34      printf("%s\n", strerror(errno));
    35    }
    36  }
    37  
    38  void main_stat() {
    39    printf("stdin isatty: %s\n", formatBool(isatty(0)));
    40    printf("stdout isatty: %s\n", formatBool(isatty(1)));
    41    printf("stderr isatty: %s\n", formatBool(isatty(2)));
    42    printf("/ isatty: %s\n", formatBool(isatty(3)));
    43  }
    44  
    45  void main_poll(int timeout, int millis) {
    46    int ret = 0;
    47    fd_set rfds;
    48    struct timeval tv;
    49  
    50    FD_ZERO(&rfds);
    51    FD_SET(0, &rfds);
    52  
    53    tv.tv_sec = timeout;
    54    tv.tv_usec = millis*1000;
    55    ret = select(1, &rfds, NULL, NULL, &tv);
    56    if ((ret > 0) && FD_ISSET(0, &rfds)) {
    57      printf("STDIN\n");
    58    } else {
    59      printf("NOINPUT\n");
    60    }
    61  }
    62  
    63  void main_sleepmillis(int millis) {
    64     struct timespec tim, tim2;
    65     tim.tv_sec = 0;
    66     tim.tv_nsec = millis * 1000000;
    67  
    68     if(nanosleep(&tim , &tim2) < 0 ) {
    69        printf("ERR\n");
    70        return;
    71     }
    72  
    73     printf("OK\n");
    74  }
    75  
    76  void main_open_rdonly() {
    77    const char *path = "zig-cc.rdonly.test";
    78    int fd;
    79    char buf[32];
    80  
    81    fd = open(path, O_CREAT|O_TRUNC|O_RDONLY, 0644);
    82    if (fd < 0) {
    83      perror("ERR: open");
    84      goto cleanup;
    85    }
    86    if (write(fd, "hello world\n", 12) >= 0) {
    87      perror("ERR: write");
    88      goto cleanup;
    89    }
    90    if (read(fd, buf, sizeof(buf)) != 0) {
    91      perror("ERR: read");
    92      goto cleanup;
    93    }
    94    puts("OK");
    95   cleanup:
    96    close(fd);
    97    unlink(path);
    98  }
    99  
   100  void main_open_wronly() {
   101    const char *path = "zig-cc.wronly.test";
   102    int fd;
   103    char buf[32];
   104  
   105    fd = open(path, O_CREAT|O_TRUNC|O_WRONLY, 0644);
   106    if (fd < 0) {
   107      perror("ERR: open");
   108      goto cleanup;
   109    }
   110    if (write(fd, "hello world\n", 12) != 12) {
   111      perror("ERR: write");
   112      goto cleanup;
   113    }
   114    if (read(fd, buf, sizeof(buf)) >= 0) {
   115      perror("ERR: read");
   116      goto cleanup;
   117    }
   118    puts("OK");
   119   cleanup:
   120    close(fd);
   121    unlink(path);
   122  }
   123  
   124  void main_sock() {
   125    // Get a listener from the pre-opened file descriptor.
   126    // The listener is the first pre-open, with a file-descriptor of 3.
   127    int listener_fd = 3;
   128  
   129    int nfd = -1;
   130    // Some runtimes set the fd to NONBLOCK
   131    // so we loop until we no longer get EAGAIN.
   132    while (true) {
   133      nfd = accept(listener_fd, NULL, NULL);
   134      if (nfd >= 0) {
   135        break;
   136      }
   137      if (errno == EAGAIN) {
   138        sleep(1);
   139        continue;
   140      } else {
   141        perror("ERR: accept");
   142        return;
   143      }
   144    }
   145  
   146    // Wait data to be available on nfd for 1 sec.
   147    char buf[32];
   148    struct timeval tv = {1, 0};
   149    fd_set set;
   150    FD_ZERO(&set);
   151    FD_SET(nfd, &set);
   152    int ret = select(nfd+1, &set, NULL, NULL, &tv);
   153  
   154    // If some data is available, read it.
   155    if (ret) {
   156      // Assume no error: we are about to quit
   157      // and we will check `buf` anyway.
   158      recv(nfd, buf, sizeof(buf), 0);
   159      printf("%s\n", buf);
   160    } else {
   161      puts("ERR: failed to read data");
   162    }
   163  }
   164  
   165  void main_nonblock(char* fpath) {
   166    struct timespec tim, tim2;
   167    tim.tv_sec = 0;
   168    tim.tv_nsec = 100 * 1000000; // 100 msec
   169    int fd = open(fpath, O_RDONLY | O_NONBLOCK);
   170    char buf[32];
   171    ssize_t newLen = 0;
   172    while (newLen == 0) {
   173      newLen = read(fd, buf, sizeof(buf));
   174      if (errno == EAGAIN || newLen == 0) {
   175        printf(".");
   176        nanosleep(&tim , &tim2) ;
   177        continue;
   178      }
   179    }
   180    printf("\n%s\n", buf);
   181    close(fd);
   182  }
   183  
   184  int main(int argc, char** argv) {
   185    if (strcmp(argv[1],"ls")==0) {
   186      bool repeat = false;
   187      if (argc > 3) {
   188        repeat = strcmp(argv[3],"repeat")==0;
   189      }
   190      main_ls(argv[2], repeat);
   191    } else if (strcmp(argv[1],"stat")==0) {
   192      main_stat();
   193    } else if (strcmp(argv[1],"poll")==0) {
   194      int timeout = 0;
   195      int usec = 0;
   196      if (argc > 2) {
   197          timeout = atoi(argv[2]);
   198      }
   199      if (argc > 3) {
   200          usec = atoi(argv[3]);
   201      }
   202      main_poll(timeout, usec);
   203    } else if (strcmp(argv[1],"sleepmillis")==0) {
   204      int timeout = 0;
   205      if (argc > 2) {
   206          timeout = atoi(argv[2]);
   207      }
   208      main_sleepmillis(timeout);
   209    } else if (strcmp(argv[1],"open-rdonly")==0) {
   210      main_open_rdonly();
   211    } else if (strcmp(argv[1],"open-wronly")==0) {
   212      main_open_wronly();
   213    } else if (strcmp(argv[1],"sock")==0) {
   214      main_sock();
   215    } else if (strcmp(argv[1],"nonblock")==0) {
   216      main_nonblock(argv[2]);
   217    } else {
   218      fprintf(stderr, "unknown command: %s\n", argv[1]);
   219      return 1;
   220    }
   221    return 0;
   222  }