Advertisement
Guest User

csapp.c

a guest
Apr 29th, 2017
77
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 18.10 KB | None | 0 0
  1. /* $begin csapp.c */
  2. #include "csapp.h"
  3.  
  4. /**************************
  5.  * Error-handling functions
  6.  **************************/
  7. /* $begin errorfuns */
  8. /* $begin unixerror */
  9. void unix_error(char *msg) /* unix-style error */
  10. {
  11.     fprintf(stderr, "%s: %s\n", msg, strerror(errno));
  12.     //exit(0);
  13. }
  14. /* $end unixerror */
  15.  
  16. void posix_error(int code, char *msg) /* posix-style error */
  17. {
  18.     fprintf(stderr, "%s: %s\n", msg, strerror(code));
  19.     exit(0);
  20. }
  21.  
  22. void dns_error(char *msg) /* dns-style error */
  23. {
  24.     fprintf(stderr, "%s: DNS error %d\n", msg, h_errno);
  25.     exit(0);
  26. }
  27.  
  28. void app_error(char *msg) /* application error */
  29. {
  30.     fprintf(stderr, "%s\n", msg);
  31.     exit(0);
  32. }
  33. /* $end errorfuns */
  34.  
  35. /*********************************************
  36.  * Wrappers for Unix process control functions
  37.  ********************************************/
  38.  
  39. /* $begin forkwrapper */
  40. pid_t Fork(void)
  41. {
  42.     pid_t pid;
  43.  
  44.     if ((pid = fork()) < 0)
  45.     unix_error("Fork error");
  46.     return pid;
  47. }
  48. /* $end forkwrapper */
  49.  
  50. void Execve(const char *filename, char *const argv[], char *const envp[])
  51. {
  52.     if (execve(filename, argv, envp) < 0)
  53.     unix_error("Execve error");
  54. }
  55.  
  56. /* $begin wait */
  57. pid_t Wait(int *status)
  58. {
  59.     pid_t pid;
  60.  
  61.     if ((pid  = wait(status)) < 0)
  62.     unix_error("Wait error");
  63.     return pid;
  64. }
  65. /* $end wait */
  66.  
  67. pid_t Waitpid(pid_t pid, int *iptr, int options)
  68. {
  69.     pid_t retpid;
  70.  
  71.     if ((retpid  = waitpid(pid, iptr, options)) < 0)
  72.     unix_error("Waitpid error");
  73.     return(retpid);
  74. }
  75.  
  76. /* $begin kill */
  77. void Kill(pid_t pid, int signum)
  78. {
  79.     int rc;
  80.  
  81.     if ((rc = kill(pid, signum)) < 0)
  82.     unix_error("Kill error");
  83. }
  84. /* $end kill */
  85.  
  86. void Pause()
  87. {
  88.     (void)pause();
  89.     return;
  90. }
  91.  
  92. unsigned int Sleep(unsigned int secs)
  93. {
  94.     unsigned int rc;
  95.  
  96.     if ((rc = sleep(secs)) < 0)
  97.     unix_error("Sleep error");
  98.     return rc;
  99. }
  100.  
  101. unsigned int Alarm(unsigned int seconds) {
  102.     return alarm(seconds);
  103. }
  104.  
  105. void Setpgid(pid_t pid, pid_t pgid) {
  106.     int rc;
  107.  
  108.     if ((rc = setpgid(pid, pgid)) < 0)
  109.     unix_error("Setpgid error");
  110.     return;
  111. }
  112.  
  113. pid_t Getpgrp(void) {
  114.     return getpgrp();
  115. }
  116.  
  117. /************************************
  118.  * Wrappers for Unix signal functions
  119.  ***********************************/
  120.  
  121. /* $begin sigaction */
  122. handler_t *Signal(int signum, handler_t *handler)
  123. {
  124.     struct sigaction action, old_action;
  125.  
  126.     action.sa_handler = handler;  
  127.     sigemptyset(&action.sa_mask); /* block sigs of type being handled */
  128.     action.sa_flags = SA_RESTART; /* restart syscalls if possible */
  129.  
  130.     if (sigaction(signum, &action, &old_action) < 0)
  131.     unix_error("Signal error");
  132.     return (old_action.sa_handler);
  133. }
  134. /* $end sigaction */
  135.  
  136. void Sigprocmask(int how, const sigset_t *set, sigset_t *oldset)
  137. {
  138.     if (sigprocmask(how, set, oldset) < 0)
  139.     unix_error("Sigprocmask error");
  140.     return;
  141. }
  142.  
  143. void Sigemptyset(sigset_t *set)
  144. {
  145.     if (sigemptyset(set) < 0)
  146.     unix_error("Sigemptyset error");
  147.     return;
  148. }
  149.  
  150. void Sigfillset(sigset_t *set)
  151. {
  152.     if (sigfillset(set) < 0)
  153.     unix_error("Sigfillset error");
  154.     return;
  155. }
  156.  
  157. void Sigaddset(sigset_t *set, int signum)
  158. {
  159.     if (sigaddset(set, signum) < 0)
  160.     unix_error("Sigaddset error");
  161.     return;
  162. }
  163.  
  164. void Sigdelset(sigset_t *set, int signum)
  165. {
  166.     if (sigdelset(set, signum) < 0)
  167.     unix_error("Sigdelset error");
  168.     return;
  169. }
  170.  
  171. int Sigismember(const sigset_t *set, int signum)
  172. {
  173.     int rc;
  174.     if ((rc = sigismember(set, signum)) < 0)
  175.     unix_error("Sigismember error");
  176.     return rc;
  177. }
  178.  
  179.  
  180. /********************************
  181.  * Wrappers for Unix I/O routines
  182.  ********************************/
  183.  
  184. int Open(const char *pathname, int flags, mode_t mode)
  185. {
  186.     int rc;
  187.  
  188.     if ((rc = open(pathname, flags, mode))  < 0)
  189.     unix_error("Open error");
  190.     return rc;
  191. }
  192.  
  193. ssize_t Read(int fd, void *buf, size_t count)
  194. {
  195.     ssize_t rc;
  196.  
  197.     if ((rc = read(fd, buf, count)) < 0)
  198.     unix_error("Read error");
  199.     return rc;
  200. }
  201.  
  202. ssize_t Write(int fd, const void *buf, size_t count)
  203. {
  204.     ssize_t rc;
  205.  
  206.     if ((rc = write(fd, buf, count)) < 0)
  207.     unix_error("Write error");
  208.     return rc;
  209. }
  210.  
  211. off_t Lseek(int fildes, off_t offset, int whence)
  212. {
  213.     off_t rc;
  214.  
  215.     if ((rc = lseek(fildes, offset, whence)) < 0)
  216.     unix_error("Lseek error");
  217.     return rc;
  218. }
  219.  
  220. void Close(int fd)
  221. {
  222.     int rc;
  223.  
  224.     if ((rc = close(fd)) < 0)
  225.     unix_error("Close error");
  226. }
  227.  
  228. int Select(int  n, fd_set *readfds, fd_set *writefds,
  229.        fd_set *exceptfds, struct timeval *timeout)
  230. {
  231.     int rc;
  232.  
  233.     if ((rc = select(n, readfds, writefds, exceptfds, timeout)) < 0)
  234.     unix_error("Select error");
  235.     return rc;
  236. }
  237.  
  238. int Dup2(int fd1, int fd2)
  239. {
  240.     int rc;
  241.  
  242.     if ((rc = dup2(fd1, fd2)) < 0)
  243.     unix_error("Dup2 error");
  244.     return rc;
  245. }
  246.  
  247. void Stat(const char *filename, struct stat *buf)
  248. {
  249.     if (stat(filename, buf) < 0)
  250.     unix_error("Stat error");
  251. }
  252.  
  253. void Fstat(int fd, struct stat *buf)
  254. {
  255.     if (fstat(fd, buf) < 0)
  256.     unix_error("Fstat error");
  257. }
  258.  
  259. /***************************************
  260.  * Wrappers for memory mapping functions
  261.  ***************************************/
  262. void *Mmap(void *addr, size_t len, int prot, int flags, int fd, off_t offset)
  263. {
  264.     void *ptr;
  265.  
  266.     if ((ptr = mmap(addr, len, prot, flags, fd, offset)) == ((void *) -1))
  267.     unix_error("mmap error");
  268.     return(ptr);
  269. }
  270.  
  271. void Munmap(void *start, size_t length)
  272. {
  273.     if (munmap(start, length) < 0)
  274.     unix_error("munmap error");
  275. }
  276.  
  277. /***************************************************
  278.  * Wrappers for dynamic storage allocation functions
  279.  ***************************************************/
  280.  
  281. void *Malloc(size_t size)
  282. {
  283.     void *p;
  284.  
  285.     if ((p  = malloc(size)) == NULL)
  286.     unix_error("Malloc error");
  287.     return p;
  288. }
  289.  
  290. void *Realloc(void *ptr, size_t size)
  291. {
  292.     void *p;
  293.  
  294.     if ((p  = realloc(ptr, size)) == NULL)
  295.     unix_error("Realloc error");
  296.     return p;
  297. }
  298.  
  299. void *Calloc(size_t nmemb, size_t size)
  300. {
  301.     void *p;
  302.  
  303.     if ((p = calloc(nmemb, size)) == NULL)
  304.     unix_error("Calloc error");
  305.     return p;
  306. }
  307.  
  308. void Free(void *ptr)
  309. {
  310.     free(ptr);
  311. }
  312.  
  313. /******************************************
  314.  * Wrappers for the Standard I/O functions.
  315.  ******************************************/
  316. void Fclose(FILE *fp)
  317. {
  318.     if (fclose(fp) != 0)
  319.     unix_error("Fclose error");
  320. }
  321.  
  322. FILE *Fdopen(int fd, const char *type)
  323. {
  324.     FILE *fp;
  325.  
  326.     if ((fp = fdopen(fd, type)) == NULL)
  327.     unix_error("Fdopen error");
  328.  
  329.     return fp;
  330. }
  331.  
  332. char *Fgets(char *ptr, int n, FILE *stream)
  333. {
  334.     char *rptr;
  335.  
  336.     if (((rptr = fgets(ptr, n, stream)) == NULL) && ferror(stream))
  337.     app_error("Fgets error");
  338.  
  339.     return rptr;
  340. }
  341.  
  342. FILE *Fopen(const char *filename, const char *mode)
  343. {
  344.     FILE *fp;
  345.  
  346.     if ((fp = fopen(filename, mode)) == NULL)
  347.     unix_error("Fopen error");
  348.  
  349.     return fp;
  350. }
  351.  
  352. void Fputs(const char *ptr, FILE *stream)
  353. {
  354.     if (fputs(ptr, stream) == EOF)
  355.     unix_error("Fputs error");
  356. }
  357.  
  358. size_t Fread(void *ptr, size_t size, size_t nmemb, FILE *stream)
  359. {
  360.     size_t n;
  361.  
  362.     if (((n = fread(ptr, size, nmemb, stream)) < nmemb) && ferror(stream))
  363.     unix_error("Fread error");
  364.     return n;
  365. }
  366.  
  367. void Fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)
  368. {
  369.     if (fwrite(ptr, size, nmemb, stream) < nmemb)
  370.     unix_error("Fwrite error");
  371. }
  372.  
  373.  
  374. /****************************
  375.  * Sockets interface wrappers
  376.  ****************************/
  377.  
  378. int Socket(int domain, int type, int protocol)
  379. {
  380.     int rc;
  381.  
  382.     if ((rc = socket(domain, type, protocol)) < 0)
  383.     unix_error("Socket error");
  384.     return rc;
  385. }
  386.  
  387. void Setsockopt(int s, int level, int optname, const void *optval, int optlen)
  388. {
  389.     int rc;
  390.  
  391.     if ((rc = setsockopt(s, level, optname, optval, optlen)) < 0)
  392.     unix_error("Setsockopt error");
  393. }
  394.  
  395. void Bind(int sockfd, struct sockaddr *my_addr, int addrlen)
  396. {
  397.     int rc;
  398.  
  399.     if ((rc = bind(sockfd, my_addr, addrlen)) < 0)
  400.     unix_error("Bind error");
  401. }
  402.  
  403. void Listen(int s, int backlog)
  404. {
  405.     int rc;
  406.  
  407.     if ((rc = listen(s,  backlog)) < 0)
  408.     unix_error("Listen error");
  409. }
  410.  
  411. int Accept(int s, struct sockaddr *addr, socklen_t *addrlen)
  412. {
  413.     int rc;
  414.  
  415.     if ((rc = accept(s, addr, addrlen)) < 0)
  416.     unix_error("Accept error");
  417.     return rc;
  418. }
  419.  
  420. void Connect(int sockfd, struct sockaddr *serv_addr, int addrlen)
  421. {
  422.     int rc;
  423.  
  424.     if ((rc = connect(sockfd, serv_addr, addrlen)) < 0)
  425.     unix_error("Connect error");
  426. }
  427.  
  428. /************************
  429.  * DNS interface wrappers
  430.  ***********************/
  431.  
  432. /* $begin gethostbyname */
  433. struct hostent *Gethostbyname(const char *name)
  434. {
  435.     struct hostent *p;
  436.  
  437.     if ((p = gethostbyname(name)) == NULL)
  438.     dns_error("Gethostbyname error");
  439.     return p;
  440. }
  441. /* $end gethostbyname */
  442.  
  443. struct hostent *Gethostbyaddr(const char *addr, int len, int type)
  444. {
  445.     struct hostent *p;
  446.  
  447.     if ((p = gethostbyaddr(addr, len, type)) == NULL)
  448.     dns_error("Gethostbyaddr error");
  449.     return p;
  450. }
  451.  
  452. /************************************************
  453.  * Wrappers for Pthreads thread control functions
  454.  ************************************************/
  455.  
  456. void Pthread_create(pthread_t *tidp, pthread_attr_t *attrp,
  457.             void * (*routine)(void *), void *argp)
  458. {
  459.     int rc;
  460.  
  461.     if ((rc = pthread_create(tidp, attrp, routine, argp)) != 0)
  462.     posix_error(rc, "Pthread_create error");
  463. }
  464.  
  465. void Pthread_cancel(pthread_t tid) {
  466.     int rc;
  467.  
  468.     if ((rc = pthread_cancel(tid)) != 0)
  469.     posix_error(rc, "Pthread_cancel error");
  470. }
  471.  
  472. void Pthread_join(pthread_t tid, void **thread_return) {
  473.     int rc;
  474.  
  475.     if ((rc = pthread_join(tid, thread_return)) != 0)
  476.     posix_error(rc, "Pthread_join error");
  477. }
  478.  
  479. /* $begin detach */
  480. void Pthread_detach(pthread_t tid) {
  481.     int rc;
  482.  
  483.     if ((rc = pthread_detach(tid)) != 0)
  484.     posix_error(rc, "Pthread_detach error");
  485. }
  486. /* $end detach */
  487.  
  488. void Pthread_exit(void *retval) {
  489.     pthread_exit(retval);
  490. }
  491.  
  492. pthread_t Pthread_self(void) {
  493.     return pthread_self();
  494. }
  495.  
  496. void Pthread_once(pthread_once_t *once_control, void (*init_function)()) {
  497.     pthread_once(once_control, init_function);
  498. }
  499.  
  500. /*******************************
  501.  * Wrappers for Posix semaphores
  502.  *******************************/
  503.  
  504. void Sem_init(sem_t *sem, int pshared, unsigned int value)
  505. {
  506.     if (sem_init(sem, pshared, value) < 0)
  507.     unix_error("Sem_init error");
  508. }
  509.  
  510. void P(sem_t *sem)
  511. {
  512.     if (sem_wait(sem) < 0)
  513.     unix_error("P error");
  514. }
  515.  
  516. void V(sem_t *sem)
  517. {
  518.     if (sem_post(sem) < 0)
  519.     unix_error("V error");
  520. }
  521.  
  522. /*********************************************************************
  523.  * The Rio package - robust I/O functions
  524.  **********************************************************************/
  525. /*
  526.  * rio_readn - robustly read n bytes (unbuffered)
  527.  */
  528. /* $begin rio_readn */
  529. ssize_t rio_readn(int fd, void *usrbuf, size_t n)
  530. {
  531.     size_t nleft = n;
  532.     ssize_t nread;
  533.     char *bufp = usrbuf;
  534.  
  535.     while (nleft > 0) {
  536.     if ((nread = read(fd, bufp, nleft)) < 0) {
  537.         if (errno == EINTR) /* interrupted by sig handler return */
  538.         nread = 0;      /* and call read() again */
  539.         else
  540.         return -1;      /* errno set by read() */
  541.     }
  542.     else if (nread == 0)
  543.         break;              /* EOF */
  544.     nleft -= nread;
  545.     bufp += nread;
  546.     }
  547.     return (n - nleft);         /* return >= 0 */
  548. }
  549. /* $end rio_readn */
  550.  
  551. /*
  552.  * rio_writen - robustly write n bytes (unbuffered)
  553.  */
  554. /* $begin rio_writen */
  555. ssize_t rio_writen(int fd, void *usrbuf, size_t n)
  556. {
  557.     size_t nleft = n;
  558.     ssize_t nwritten;
  559.     char *bufp = usrbuf;
  560.  
  561.     while (nleft > 0) {
  562.     if ((nwritten = write(fd, bufp, nleft)) <= 0) {
  563.         if (errno == EINTR)  /* interrupted by sig handler return */
  564.         nwritten = 0;    /* and call write() again */
  565.         else
  566.         return -1;       /* errorno set by write() */
  567.     }
  568.     nleft -= nwritten;
  569.     bufp += nwritten;
  570.     }
  571.     return n;
  572. }
  573. /* $end rio_writen */
  574.  
  575.  
  576. /*
  577.  * rio_read - This is a wrapper for the Unix read() function that
  578.  *    transfers min(n, rio_cnt) bytes from an internal buffer to a user
  579.  *    buffer, where n is the number of bytes requested by the user and
  580.  *    rio_cnt is the number of unread bytes in the internal buffer. On
  581.  *    entry, rio_read() refills the internal buffer via a call to
  582.  *    read() if the internal buffer is empty.
  583.  */
  584. /* $begin rio_read */
  585. static ssize_t rio_read(rio_t *rp, char *usrbuf, size_t n)
  586. {
  587.     int cnt;
  588.  
  589.     while (rp->rio_cnt <= 0) {  /* refill if buf is empty */
  590.     rp->rio_cnt = read(rp->rio_fd, rp->rio_buf,
  591.                sizeof(rp->rio_buf));
  592.     if (rp->rio_cnt < 0) {
  593.         if (errno != EINTR) /* interrupted by sig handler return */
  594.         return -1;
  595.     }
  596.     else if (rp->rio_cnt == 0)  /* EOF */
  597.         return 0;
  598.     else
  599.         rp->rio_bufptr = rp->rio_buf; /* reset buffer ptr */
  600.     }
  601.  
  602.     /* Copy min(n, rp->rio_cnt) bytes from internal buf to user buf */
  603.     cnt = n;          
  604.     if (rp->rio_cnt < n)  
  605.     cnt = rp->rio_cnt;
  606.     memcpy(usrbuf, rp->rio_bufptr, cnt);
  607.     rp->rio_bufptr += cnt;
  608.     rp->rio_cnt -= cnt;
  609.     return cnt;
  610. }
  611. /* $end rio_read */
  612.  
  613. /*
  614.  * rio_readinitb - Associate a descriptor with a read buffer and reset buffer
  615.  */
  616. /* $begin rio_readinitb */
  617. void rio_readinitb(rio_t *rp, int fd)
  618. {
  619.     rp->rio_fd = fd;  
  620.     rp->rio_cnt = 0;  
  621.     rp->rio_bufptr = rp->rio_buf;
  622. }
  623. /* $end rio_readinitb */
  624.  
  625. /*
  626.  * rio_readnb - Robustly read n bytes (buffered)
  627.  */
  628. /* $begin rio_readnb */
  629. ssize_t rio_readnb(rio_t *rp, void *usrbuf, size_t n)
  630. {
  631.     size_t nleft = n;
  632.     ssize_t nread;
  633.     char *bufp = usrbuf;
  634.    
  635.     while (nleft > 0) {
  636.     if ((nread = rio_read(rp, bufp, nleft)) < 0) {
  637.         if (errno == EINTR) /* interrupted by sig handler return */
  638.         nread = 0;      /* call read() again */
  639.         else
  640.         return -1;      /* errno set by read() */
  641.     }
  642.     else if (nread == 0)
  643.         break;              /* EOF */
  644.     nleft -= nread;
  645.     bufp += nread;
  646.     }
  647.     return (n - nleft);         /* return >= 0 */
  648. }
  649. /* $end rio_readnb */
  650.  
  651. /*
  652.  * rio_readlineb - robustly read a text line (buffered)
  653.  */
  654. /* $begin rio_readlineb */
  655. ssize_t rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen)
  656. {
  657.     int n, rc;
  658.     char c, *bufp = usrbuf;
  659.  
  660.     for (n = 1; n < maxlen; n++) {
  661.     if ((rc = rio_read(rp, &c, 1)) == 1) {
  662.         *bufp++ = c;
  663.         if (c == '\n')
  664.         break;
  665.     } else if (rc == 0) {
  666.         if (n == 1)
  667.         return 0; /* EOF, no data read */
  668.         else
  669.         break;    /* EOF, some data was read */
  670.     } else
  671.         return -1;    /* error */
  672.     }
  673.     *bufp = 0;
  674.     return n;
  675. }
  676. /* $end rio_readlineb */
  677.  
  678. /**********************************
  679.  * Wrappers for robust I/O routines
  680.  **********************************/
  681. ssize_t Rio_readn(int fd, void *ptr, size_t nbytes)
  682. {
  683.     ssize_t n;
  684.  
  685.     if ((n = rio_readn(fd, ptr, nbytes)) < 0)
  686.     unix_error("Rio_readn error");
  687.     return n;
  688. }
  689.  
  690. void Rio_writen(int fd, void *usrbuf, size_t n)
  691. {
  692.     if (rio_writen(fd, usrbuf, n) != n)
  693.     unix_error("Rio_writen error");
  694. }
  695.  
  696. void Rio_readinitb(rio_t *rp, int fd)
  697. {
  698.     rio_readinitb(rp, fd);
  699. }
  700.  
  701. ssize_t Rio_readnb(rio_t *rp, void *usrbuf, size_t n)
  702. {
  703.     ssize_t rc;
  704.  
  705.     if ((rc = rio_readnb(rp, usrbuf, n)) < 0)
  706.     unix_error("Rio_readnb error");
  707.     return rc;
  708. }
  709.  
  710. ssize_t Rio_readlineb(rio_t *rp, void *usrbuf, size_t maxlen)
  711. {
  712.     ssize_t rc;
  713.  
  714.     if ((rc = rio_readlineb(rp, usrbuf, maxlen)) < 0)
  715.     unix_error("Rio_readlineb error");
  716.     return rc;
  717. }
  718.  
  719. /********************************
  720.  * Client/server helper functions
  721.  ********************************/
  722. /*
  723.  * open_clientfd - open connection to server at <hostname, port>
  724.  *   and return a socket descriptor ready for reading and writing.
  725.  *   Returns -1 and sets errno on Unix error.
  726.  *   Returns -2 and sets h_errno on DNS (gethostbyname) error.
  727.  */
  728. /* $begin open_clientfd */
  729. int open_clientfd(char *hostname, int port)
  730. {
  731.     int clientfd;
  732.     struct hostent *hp;
  733.     struct sockaddr_in serveraddr;
  734.  
  735.     if ((clientfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  736.     return -1; /* check errno for cause of error */
  737.  
  738.     /* Fill in the server's IP address and port */
  739.     if ((hp = gethostbyname(hostname)) == NULL)
  740.     return -2; /* check h_errno for cause of error */
  741.     bzero((char *) &serveraddr, sizeof(serveraddr));
  742.     serveraddr.sin_family = AF_INET;
  743.     bcopy((char *)hp->h_addr_list[0],
  744.       (char *)&serveraddr.sin_addr.s_addr, hp->h_length);
  745.     serveraddr.sin_port = htons(port);
  746.  
  747.     /* Establish a connection with the server */
  748.     if (connect(clientfd, (SA *) &serveraddr, sizeof(serveraddr)) < 0)
  749.     return -1;
  750.     return clientfd;
  751. }
  752. /* $end open_clientfd */
  753.  
  754. /*  
  755.  * open_listenfd - open and return a listening socket on port
  756.  *     Returns -1 and sets errno on Unix error.
  757.  */
  758. /* $begin open_listenfd */
  759. int open_listenfd(int port)
  760. {
  761.     int listenfd, optval=1;
  762.     struct sockaddr_in serveraddr;
  763.  
  764.     /* Create a socket descriptor */
  765.     if ((listenfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
  766.     return -1;
  767.  
  768.     /* Eliminates "Address already in use" error from bind. */
  769.     if (setsockopt(listenfd, SOL_SOCKET, SO_REUSEADDR,
  770.            (const void *)&optval , sizeof(int)) < 0)
  771.     return -1;
  772.  
  773.     /* Listenfd will be an endpoint for all requests to port
  774.        on any IP address for this host */
  775.     bzero((char *) &serveraddr, sizeof(serveraddr));
  776.     serveraddr.sin_family = AF_INET;
  777.     serveraddr.sin_addr.s_addr = htonl(INADDR_ANY);
  778.     serveraddr.sin_port = htons((unsigned short)port);
  779.     if (bind(listenfd, (SA *)&serveraddr, sizeof(serveraddr)) < 0)
  780.     return -1;
  781.  
  782.     /* Make it a listening socket ready to accept connection requests */
  783.     if (listen(listenfd, LISTENQ) < 0)
  784.     return -1;
  785.     return listenfd;
  786. }
  787. /* $end open_listenfd */
  788.  
  789. /******************************************
  790.  * Wrappers for the client/server helper routines
  791.  ******************************************/
  792. int Open_clientfd(char *hostname, int port)
  793. {
  794.     int rc;
  795.  
  796.     if ((rc = open_clientfd(hostname, port)) < 0) {
  797.     if (rc == -1)
  798.         unix_error("Open_clientfd Unix error");
  799.     else        
  800.         dns_error("Open_clientfd DNS error");
  801.     }
  802.     return rc;
  803. }
  804.  
  805. int Open_listenfd(int port)
  806. {
  807.     int rc;
  808.  
  809.     if ((rc = open_listenfd(port)) < 0)
  810.     unix_error("Open_listenfd error");
  811.     return rc;
  812. }
  813. /* $end csapp.c */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement