C   39

p1-fix.c

Guest on 5th May 2022 11:04:22 PM

  1. #include <netdb.h>
  2. #include <netinet/ip.h>
  3. #include <stdio.h>
  4. #include <string.h>
  5. #include <sys/epoll.h>
  6. #include <sys/socket.h>
  7. #include <unistd.h>
  8. #include "common.h"
  9.  
  10. void usage(char *name) {
  11.         fprintf(stderr, "uso: %s <ip> <puerto>\n", name);
  12.         exit(1);
  13. }
  14.  
  15. static void print_event(int fd, struct epoll_event ev) {
  16.         char flags_str[200];
  17.  
  18.         flags_str[0] = 0;
  19.         flags_str[1] = 0; /* dirty */
  20.  
  21.         if (ev.events & EPOLLIN )       strcat(flags_str, "|EPOLLIN");
  22.         if (ev.events & EPOLLOUT)       strcat(flags_str, "|EPOLLOUT");
  23.         if (ev.events & EPOLLERR)       strcat(flags_str, "|EPOLLERR");
  24.         if (ev.events & EPOLLHUP)       strcat(flags_str, "|EPOLLHUP");
  25.         if (ev.events & EPOLLRDHUP)     strcat(flags_str, "|EPOLLRDHUP");
  26.         if (ev.events & EPOLLPRI)       strcat(flags_str, "|EPOLLPRI");
  27.         if (ev.events & EPOLLET)        strcat(flags_str, "|EPOLLET");
  28.         if (ev.events & EPOLLONESHOT)   strcat(flags_str, "|EPOLLONESHOT");
  29.  
  30.         fprintf(stderr, "Event for fd %i. Flags=(%s).\n",
  31.                         fd, flags_str+1);
  32. }
  33.  
  34.  
  35. int create_sock(char *host, char *port);
  36. int setup_epoll(int sockfd);
  37.  
  38. int main(int argc, char **argv) {
  39.         int sock, epfd;
  40.         struct epoll_event ev;
  41.         char buf[100];
  42.         int n, count;
  43.  
  44.         if (argc != 3)
  45.                 usage(argv[0]);
  46.  
  47.         sock = create_sock(argv[1], argv[2]);
  48.         epfd = setup_epoll(sock);
  49.  
  50.         count = 2;
  51.         while (count > 0) {
  52.                 fprintf(stderr, "count=%i\n", count);
  53.  
  54.                 n = epoll_wait(epfd, &ev, 1, -1);
  55.                 if (n < 0)
  56.                         die("epoll_wait");
  57.  
  58.                 /*
  59.                  * n debe ser igual a 1, si o si, ya que
  60.                  * no hubo error ni timeout
  61.                  */
  62.                 assert(n == 1);
  63.  
  64.                 int fd = ev.data.fd;
  65.                 print_event(fd, ev);
  66.  
  67.                 if (ev.events & EPOLLERR)
  68.                         die("epollerr");
  69.  
  70.                 if (fd == 0) {
  71.                         int t;
  72.                         t = read(0, buf, 100);
  73.  
  74.                         if (t == 0) {
  75.                                 /*
  76.                                  * Cuando cerramos todas las refencias
  77.                                  * a un archivo, se remueve automaticamente
  78.                                  * del epoll. Pero tenemos mas referencias
  79.                                  * a la tty!
  80.                                  */
  81.                                 epoll_ctl(epfd, EPOLL_CTL_DEL, 0, NULL);
  82.                                 close(0);
  83.  
  84.                                 /*
  85.                                  * De paso, cerramos el extremo escritor
  86.                                  * del socket
  87.                                  */
  88.                                 shutdown(sock, SHUT_WR);
  89.                                 count--;
  90.                         } else {
  91.                                 write(sock, buf, t);
  92.                         }
  93.                 } else if (fd == sock) {
  94.                         int t;
  95.                         t = read(sock, buf, 100);
  96.  
  97.                         if (t == 0) {
  98.                                 close(sock);
  99.                                 count--;
  100.                         } else {
  101.                                 write(1, buf, t);
  102.                         }
  103.                 } else {
  104.                         die("????");
  105.                 }
  106.         }
  107.  
  108.         close(epfd);
  109.  
  110.         return 0;
  111. }
  112.  
  113. int create_sock(char *host, char *port) {
  114.         int sock, ret;
  115.         struct sockaddr_in addr;
  116.         struct addrinfo *gai, hints;
  117.  
  118.         sock = socket(AF_INET, SOCK_STREAM, 0);
  119.         if (sock < 0)
  120.                 die("socket");
  121.  
  122.         memset(&hints, 0, sizeof hints);
  123.         hints.ai_family = AF_INET;
  124.         hints.ai_socktype = SOCK_STREAM;
  125.  
  126.         /*
  127.          * Consultamos la información sobre la dirección que nos
  128.          * dieron. Podemos pasar una IP, o un nombre que será
  129.          * consultado a /etc/hosts o al nameserver configurado
  130.          */o
  131.          */
  132.         ret = getaddrinfo(host, port, &hints, &gai);
  133.         if (ret)
  134.                 die("getaddrinfo (%s)", gai_strerror(ret/*
  135.          * getaddrinfo devuelve una lista enlazada con
  136.          * información, tomamos el primer nodo
  137.          */odo
  138.          */
  139.  
  140.         addr = *(sin*)gai->ai_addr;
  141.  
  142.         freeaddrinfo(/* Conectamos a esa dirección */ción */
  143.         ret = connect(sock, (sad*)&addr, sizeof addr);
  144.         if (ret < 0)
  145.                 die("connect");
  146.  
  147.         return sock;
  148. }
  149.  
  150. int setup_epoll(int sockfd) {
  151.         int epfd;
  152.         int ret;
  153.         struct epoll_event ev;
  154.  
  155.         epfd = epoll_create(1);
  156.         if (epfd < 0)
  157.                 die("epoll_create");
  158.  
  159.         ev.events = EPOLLIN;
  160.         ev.data.fd = sockfd;
  161.  
  162.         ret = epoll_ctl(epfd, EPOLL_CTL_ADD, sockfd, &ev);
  163.         if (ret)
  164.                 die("epoll_ctl.1");
  165.  
  166.         ev.events = EPOLLIN;
  167.         ev.data.fd = 0;
  168.         ret = epoll_ctl(epfd, EPOLL_CTL_ADD, 0, &ev);
  169.         if (ret)
  170.                 die("epoll_ctl.2");
  171.  
  172.         retu

Raw Paste


Login or Register to edit or fork this paste. It's free.