Commit ce434124ab445b5a203c8870baf062cb9899aaa8

Authored by Grzegorz Jabłoński
0 parents

Initial version

eintrc.c 0 → 100644
  1 +++ a/eintrc.c
  1 +/* Make the necessary includes and set up the variables. */
  2 +
  3 +#include <sys/types.h>
  4 +#include <sys/socket.h>
  5 +#include <stdio.h>
  6 +#include <stdlib.h>
  7 +#include <netinet/in.h>
  8 +#include <arpa/inet.h>
  9 +#include <unistd.h>
  10 +#include <signal.h>
  11 +
  12 +void
  13 +alarmhandler (int s)
  14 +{
  15 + signal (SIGALRM, alarmhandler);
  16 + alarm (1);
  17 +}
  18 +
  19 +int
  20 +main ()
  21 +{
  22 + int sockfd;
  23 + socklen_t len;
  24 + struct sockaddr_in address;
  25 + int result;
  26 + ssize_t count;
  27 + char buffer[1024 * 1024];
  28 + signal (SIGALRM, alarmhandler);
  29 + alarm (1);
  30 +
  31 + /* Create a socket for the client. */
  32 +
  33 + sockfd = socket (AF_INET, SOCK_STREAM, 0);
  34 +
  35 + /* Name the socket, as agreed with the server. */
  36 +
  37 + address.sin_family = AF_INET;
  38 + address.sin_addr.s_addr = inet_addr ("127.0.0.1");
  39 + address.sin_port = htons (9734);
  40 + len = sizeof (address);
  41 +
  42 + /* Now connect our socket to the server's socket. */
  43 +
  44 + result = connect (sockfd, (struct sockaddr *) &address, len);
  45 +
  46 + if (result == -1)
  47 + {
  48 + perror ("oops: eintrc");
  49 + exit (1);
  50 + }
  51 +
  52 + /* We can now read/write via sockfd. */
  53 + while (1)
  54 + {
  55 +
  56 + count = write (sockfd, buffer, 1024 * 1024);
  57 + if (count == -1)
  58 + perror ("write");
  59 + else
  60 + printf ("Wrote %zd bytes\n", count);
  61 + }
  62 +}
... ...
eintrs.c 0 → 100644
  1 +++ a/eintrs.c
  1 +#include <sys/types.h>
  2 +#include <sys/socket.h>
  3 +#include <stdio.h>
  4 +#include <netinet/in.h>
  5 +#include <signal.h>
  6 +#include <unistd.h>
  7 +
  8 +int
  9 +main ()
  10 +{
  11 + ssize_t count;
  12 + char buffer[1024 * 1024];
  13 + int server_sockfd, client_sockfd;
  14 + socklen_t server_len, client_len;
  15 + struct sockaddr_in server_address;
  16 + struct sockaddr_in client_address;
  17 +
  18 + server_sockfd = socket (AF_INET, SOCK_STREAM, 0);
  19 +
  20 + server_address.sin_family = AF_INET;
  21 + server_address.sin_addr.s_addr = htonl (INADDR_ANY);
  22 + server_address.sin_port = htons (9734);
  23 + server_len = sizeof (server_address);
  24 + bind (server_sockfd, (struct sockaddr *) &server_address, server_len);
  25 +
  26 + /* Create a connection queue and wait for clients. */
  27 +
  28 + listen (server_sockfd, 5);
  29 +
  30 + printf ("server waiting\n");
  31 +
  32 + /* Accept connection. */
  33 +
  34 + client_len = sizeof (client_address);
  35 + client_sockfd = accept (server_sockfd,
  36 + (struct sockaddr *) &client_address, &client_len);
  37 +
  38 + while (1)
  39 + {
  40 + count = read (client_sockfd, buffer, 1024 * 1024);
  41 + printf ("Read %zd bytes\n", count);
  42 + }
  43 +}
... ...
epoll1.c 0 → 100644
  1 +++ a/epoll1.c
  1 +#include <stdio.h> // for fprintf()
  2 +#include <unistd.h> // for close()
  3 +#include <sys/epoll.h> // for epoll_create1()
  4 +
  5 +int main()
  6 +{
  7 + int epoll_fd = epoll_create1(0);
  8 +
  9 + if(epoll_fd == -1)
  10 + {
  11 + fprintf(stderr, "Failed to create epoll file descriptor\n");
  12 + return 1;
  13 + }
  14 +
  15 + if(close(epoll_fd))
  16 + {
  17 + fprintf(stderr, "Failed to close epoll file descriptor\n");
  18 + return 1;
  19 + }
  20 + return 0;
  21 +}
  22 +
... ...
epoll2.c 0 → 100644
  1 +++ a/epoll2.c
  1 +#include <stdio.h> // for fprintf()
  2 +#include <unistd.h> // for close()
  3 +#include <sys/epoll.h> // for epoll_create1(), epoll_ctl(), struct epoll_event
  4 +
  5 +int main()
  6 +{
  7 + struct epoll_event event;
  8 + int epoll_fd = epoll_create1(0);
  9 +
  10 + if(epoll_fd == -1)
  11 + {
  12 + fprintf(stderr, "Failed to create epoll file descriptor\n");
  13 + return 1;
  14 + }
  15 +
  16 + event.events = EPOLLIN;
  17 + event.data.fd = 0;
  18 +
  19 + if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, 0, &event))
  20 + {
  21 + fprintf(stderr, "Failed to add file descriptor to epoll\n");
  22 + close(epoll_fd);
  23 + return 1;
  24 + }
  25 +
  26 + if(close(epoll_fd))
  27 + {
  28 + fprintf(stderr, "Failed to close epoll file descriptor\n");
  29 + return 1;
  30 + }
  31 + return 0;
  32 +}
  33 +
... ...
epoll3.c 0 → 100644
  1 +++ a/epoll3.c
  1 +#define MAX_EVENTS 5
  2 +#define READ_SIZE 10
  3 +#include <stdio.h> // for fprintf()
  4 +#include <unistd.h> // for close(), read()
  5 +#include <sys/epoll.h> // for epoll_create1(), epoll_ctl(), struct epoll_event
  6 +#include <string.h> // for strncmp
  7 +
  8 +int main()
  9 +{
  10 + int running = 1, event_count, i;
  11 + size_t bytes_read;
  12 + char read_buffer[READ_SIZE + 1];
  13 + struct epoll_event event, events[MAX_EVENTS];
  14 + int epoll_fd = epoll_create1(0);
  15 +
  16 + if(epoll_fd == -1)
  17 + {
  18 + fprintf(stderr, "Failed to create epoll file descriptor\n");
  19 + return 1;
  20 + }
  21 +
  22 + event.events = EPOLLIN;
  23 + event.data.fd = 0;
  24 +
  25 + if(epoll_ctl(epoll_fd, EPOLL_CTL_ADD, 0, &event))
  26 + {
  27 + fprintf(stderr, "Failed to add file descriptor to epoll\n");
  28 + close(epoll_fd);
  29 + return 1;
  30 + }
  31 +
  32 + while(running)
  33 + {
  34 + printf("\nPolling for input...\n");
  35 + event_count = epoll_wait(epoll_fd, events, MAX_EVENTS, 30000);
  36 + printf("%d ready events\n", event_count);
  37 + for(i = 0; i < event_count; i++)
  38 + {
  39 + printf("Reading file descriptor '%d' -- ", events[i].data.fd);
  40 + bytes_read = read(events[i].data.fd, read_buffer, READ_SIZE);
  41 + printf("%zd bytes read.\n", bytes_read);
  42 + read_buffer[bytes_read] = '\0';
  43 + printf("Read '%s'\n", read_buffer);
  44 +
  45 + if(!strncmp(read_buffer, "stop\n", 5))
  46 + running = 0;
  47 + }
  48 + }
  49 +
  50 + if(close(epoll_fd))
  51 + {
  52 + fprintf(stderr, "Failed to close epoll file descriptor\n");
  53 + return 1;
  54 + }
  55 + return 0;
  56 +}
  57 +
... ...
epoll4.c 0 → 100644
  1 +++ a/epoll4.c
  1 +/*
  2 + * Attention:
  3 + * To keep things simple, do not handle socket/bind/listen/.../epoll_create/epoll_wait API error
  4 + */
  5 +#include <sys/types.h>
  6 +#include <sys/socket.h>
  7 +#include <netdb.h>
  8 +#include <string.h>
  9 +#include <unistd.h>
  10 +#include <fcntl.h>
  11 +#include <sys/epoll.h>
  12 +#include <errno.h>
  13 +#include <stdio.h>
  14 +#include <stdlib.h>
  15 +#include <arpa/inet.h>
  16 +
  17 +
  18 +#define DEFAULT_PORT 9734
  19 +#define MAX_CONN 16
  20 +#define MAX_EVENTS 32
  21 +#define BUF_SIZE 16
  22 +#define MAX_LINE 256
  23 +
  24 +void server_run();
  25 +void client_run();
  26 +
  27 +int main(int argc, char *argv[])
  28 +{
  29 + int opt;
  30 + char role = 's';
  31 + while ((opt = getopt(argc, argv, "cs")) != -1) {
  32 + switch (opt) {
  33 + case 'c':
  34 + role = 'c';
  35 + break;
  36 + case 's':
  37 + break;
  38 + default:
  39 + printf("usage: %s [-cs]\n", argv[0]);
  40 + exit(1);
  41 + }
  42 + }
  43 + if (role == 's') {
  44 + server_run();
  45 + } else {
  46 + client_run();
  47 + }
  48 + return 0;
  49 +}
  50 +
  51 +/*
  52 + * register events of fd to epfd
  53 + */
  54 +static void epoll_ctl_add(int epfd, int fd, uint32_t events)
  55 +{
  56 + struct epoll_event ev;
  57 + ev.events = events;
  58 + ev.data.fd = fd;
  59 + if (epoll_ctl(epfd, EPOLL_CTL_ADD, fd, &ev) == -1) {
  60 + perror("epoll_ctl()\n");
  61 + exit(1);
  62 + }
  63 +}
  64 +
  65 +static void set_sockaddr(struct sockaddr_in *addr)
  66 +{
  67 + bzero((char *)addr, sizeof(struct sockaddr_in));
  68 + addr->sin_family = AF_INET;
  69 + addr->sin_addr.s_addr = INADDR_ANY;
  70 + addr->sin_port = htons(DEFAULT_PORT);
  71 +}
  72 +
  73 +static int setnonblocking(int sockfd)
  74 +{
  75 + if (fcntl(sockfd, F_SETFD, fcntl(sockfd, F_GETFD, 0) | O_NONBLOCK) ==
  76 + -1) {
  77 + return -1;
  78 + }
  79 + return 0;
  80 +}
  81 +
  82 +/*
  83 + * epoll echo server
  84 + */
  85 +void server_run()
  86 +{
  87 + int i;
  88 + int n;
  89 + int epfd;
  90 + int nfds;
  91 + int listen_sock;
  92 + int conn_sock;
  93 + int socklen;
  94 + char buf[BUF_SIZE];
  95 + struct sockaddr_in srv_addr;
  96 + struct sockaddr_in cli_addr;
  97 + struct epoll_event events[MAX_EVENTS];
  98 +
  99 + listen_sock = socket(AF_INET, SOCK_STREAM, 0);
  100 +
  101 + set_sockaddr(&srv_addr);
  102 + bind(listen_sock, (struct sockaddr *)&srv_addr, sizeof(srv_addr));
  103 +
  104 + setnonblocking(listen_sock);
  105 + listen(listen_sock, MAX_CONN);
  106 +
  107 + epfd = epoll_create(1);
  108 + epoll_ctl_add(epfd, listen_sock, EPOLLIN | EPOLLOUT | EPOLLET);
  109 +
  110 + socklen = sizeof(cli_addr);
  111 + for (;;) {
  112 + nfds = epoll_wait(epfd, events, MAX_EVENTS, -1);
  113 + for (i = 0; i < nfds; i++) {
  114 + if (events[i].data.fd == listen_sock) {
  115 + /* handle new connection */
  116 + conn_sock =
  117 + accept(listen_sock,
  118 + (struct sockaddr *)&cli_addr,
  119 + &socklen);
  120 +
  121 + inet_ntop(AF_INET, (char *)&(cli_addr.sin_addr),
  122 + buf, sizeof(cli_addr));
  123 + printf("[+] connected with %s:%d\n", buf,
  124 + ntohs(cli_addr.sin_port));
  125 +
  126 + setnonblocking(conn_sock);
  127 + epoll_ctl_add(epfd, conn_sock,
  128 + EPOLLIN | EPOLLET | EPOLLRDHUP |
  129 + EPOLLHUP);
  130 + } else if (events[i].events & EPOLLIN) {
  131 + /* handle EPOLLIN event */
  132 + for (;;) {
  133 + bzero(buf, sizeof(buf));
  134 + n = read(events[i].data.fd, buf,
  135 + sizeof(buf) - 1);
  136 + if (n <= 0 /* || errno == EAGAIN */ ) {
  137 + break;
  138 + } else {
  139 + printf("[+] data: %s\n", buf);
  140 + write(events[i].data.fd, buf,
  141 + strlen(buf));
  142 + }
  143 + }
  144 + } else {
  145 + printf("[+] unexpected\n");
  146 + }
  147 + /* check if the connection is closing */
  148 + if (events[i].events & (EPOLLRDHUP | EPOLLHUP)) {
  149 + printf("[+] connection closed\n");
  150 + epoll_ctl(epfd, EPOLL_CTL_DEL,
  151 + events[i].data.fd, NULL);
  152 + close(events[i].data.fd);
  153 + continue;
  154 + }
  155 + }
  156 + }
  157 +}
  158 +
  159 +/*
  160 + * test clinet
  161 + */
  162 +void client_run()
  163 +{
  164 + int n;
  165 + int c;
  166 + int sockfd;
  167 + char buf[MAX_LINE];
  168 + struct sockaddr_in srv_addr;
  169 +
  170 + sockfd = socket(AF_INET, SOCK_STREAM, 0);
  171 +
  172 + set_sockaddr(&srv_addr);
  173 +
  174 + if (connect(sockfd, (struct sockaddr *)&srv_addr, sizeof(srv_addr)) < 0) {
  175 + perror("connect()");
  176 + exit(1);
  177 + }
  178 +
  179 + for (;;) {
  180 + printf("input: ");
  181 + fgets(buf, sizeof(buf), stdin);
  182 + c = strlen(buf) - 1;
  183 + buf[c] = '\0';
  184 + write(sockfd, buf, c + 1);
  185 +
  186 + bzero(buf, sizeof(buf));
  187 + while (errno != EAGAIN
  188 + && (n = read(sockfd, buf, sizeof(buf) - 1)) > 0) {
  189 + printf("echo: %s\n", buf);
  190 + bzero(buf, sizeof(buf));
  191 +
  192 + c -= n;
  193 + if (c <= 0) {
  194 + break;
  195 + }
  196 + }
  197 + }
  198 + close(sockfd);
  199 +}
  200 +
... ...
fork1.c 0 → 100644
  1 +++ a/fork1.c
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <unistd.h>
  4 +#include <signal.h>
  5 +#include <sys/types.h>
  6 +#include <sys/wait.h>
  7 +#include <errno.h>
  8 +
  9 +int
  10 +main ()
  11 +{
  12 + pid_t res;
  13 + int status;
  14 + res = fork ();
  15 + if (res == 0)
  16 + {
  17 + printf ("Hello from child\n");
  18 + sleep (1);
  19 + exit (1);
  20 + };
  21 + if (res == -1)
  22 + perror ("fork");
  23 + wait (&status);
  24 + if (WIFEXITED (status))
  25 + printf ("Child exited normally with exit code %d\n",
  26 + WEXITSTATUS (status));
  27 + else
  28 + printf ("Child exited abnormally\n");
  29 + exit (0);
  30 +}
... ...
fork2.c 0 → 100644
  1 +++ a/fork2.c
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <unistd.h>
  4 +#include <signal.h>
  5 +#include <sys/types.h>
  6 +#include <sys/wait.h>
  7 +#include <errno.h>
  8 +
  9 +int
  10 +main ()
  11 +{
  12 + pid_t res;
  13 + int status;
  14 + res = fork ();
  15 + if (res == 0)
  16 + {
  17 + printf ("Hello from child\n");
  18 + sleep (1);
  19 + abort ();
  20 + };
  21 + if (res == -1)
  22 + perror ("fork");
  23 + wait (&status);
  24 + if (WIFEXITED (status))
  25 + printf ("Child exited normally with exit code %d\n",
  26 + WEXITSTATUS (status));
  27 + else
  28 + printf ("Child exited abnormally\n");
  29 + exit (0);
  30 +}
... ...
fork3.c 0 → 100644
  1 +++ a/fork3.c
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <unistd.h>
  4 +#include <signal.h>
  5 +#include <sys/types.h>
  6 +#include <sys/wait.h>
  7 +#include <errno.h>
  8 +
  9 +int
  10 +main ()
  11 +{
  12 + pid_t res;
  13 + int i;
  14 + res = fork ();
  15 + if (res == 0)
  16 + {
  17 + for (i = 0; i < 200; ++i)
  18 + {
  19 + printf ("Hello #%d from child\n", i);
  20 + }
  21 + abort ();
  22 + };
  23 + if (res == -1)
  24 + perror ("fork");
  25 + for (i = 0; i < 200; ++i)
  26 + {
  27 + printf ("Hello #%d from parent\n", i);
  28 + sleep (1);
  29 + };
  30 + exit (0);
  31 +}
... ...
fork4.c 0 → 100644
  1 +++ a/fork4.c
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <unistd.h>
  4 +#include <signal.h>
  5 +#include <sys/types.h>
  6 +#include <sys/wait.h>
  7 +#include <errno.h>
  8 +
  9 +int
  10 +main ()
  11 +{
  12 + pid_t res;
  13 + int status;
  14 + int i;
  15 + res = fork ();
  16 + if (res == 0)
  17 + {
  18 + for (i = 0; i < 200; ++i)
  19 + printf ("Hello #%d from child\n", i);
  20 + abort ();
  21 + };
  22 + if (res == -1)
  23 + perror ("fork");
  24 + for (i = 0; i < 200; ++i)
  25 + {
  26 + printf ("Hello #%d from parent\n", i);
  27 + if (waitpid (res, &status, WNOHANG) == res)
  28 + printf ("Child exited\n");
  29 + sleep (1);
  30 + };
  31 + exit (0);
  32 +}
... ...
fork5.c 0 → 100644
  1 +++ a/fork5.c
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <unistd.h>
  4 +#include <signal.h>
  5 +#include <sys/types.h>
  6 +#include <sys/wait.h>
  7 +#include <errno.h>
  8 +
  9 +void
  10 +childsignal (int what)
  11 +{
  12 + pid_t v;
  13 + int old_errno = errno;
  14 + printf ("New signal\n");
  15 + while ((v = waitpid (-1, NULL, WNOHANG)) != 0
  16 + && !(v == -1 && errno != EINTR))
  17 + printf ("%d\n", v);
  18 + if (v == -1)
  19 + perror ("waitpid");
  20 + printf ("Signal exit\n");
  21 + errno = old_errno;
  22 +}
  23 +
  24 +int
  25 +main ()
  26 +{
  27 + int i;
  28 + struct sigaction sig;
  29 + sig.sa_handler = childsignal;
  30 + sigemptyset (&sig.sa_mask);
  31 + sig.sa_flags = SA_NOCLDSTOP;
  32 + sigaction (SIGCHLD, &sig, NULL);
  33 + for (i = 0; i < 200; i++)
  34 + {
  35 + pid_t res;
  36 + printf ("Starting child #%d\n", i);
  37 + res = fork ();
  38 + if (res == 0)
  39 + {
  40 + sleep (5);
  41 + exit (i + 1);
  42 + };
  43 + if (res == -1)
  44 + perror ("fork");
  45 + };
  46 + for (i = 0; i < 360; i++)
  47 + sleep (1);
  48 + exit (0);
  49 +}
... ...
fork6.c 0 → 100644
  1 +++ a/fork6.c
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <unistd.h>
  4 +#include <signal.h>
  5 +#include <sys/types.h>
  6 +#include <sys/wait.h>
  7 +#include <errno.h>
  8 +
  9 +int
  10 +main ()
  11 +{
  12 + int i;
  13 + signal (SIGCHLD, SIG_IGN);
  14 + for (i = 0; i < 200; i++)
  15 + {
  16 + pid_t res;
  17 + printf ("Starting child #%d\n", i);
  18 + res = fork ();
  19 + if (res == 0)
  20 + {
  21 + sleep (5);
  22 + exit (i + 1);
  23 + };
  24 + if (res == -1)
  25 + perror ("fork");
  26 + }
  27 + for (i = 0; i < 360; i++)
  28 + sleep (1);
  29 + exit (0);
  30 +}
... ...
makefile 0 → 100644
  1 +++ a/makefile
  1 +CFLAGS=-ggdb -Wall -pedantic -D_REENTRANT
  2 +
  3 +%: %.c
  4 + gcc $(CFLAGS) $< -o $@ -lpthread
  5 +
  6 +EXECS = fork1 fork2 fork3 fork4 fork5 fork6 \
  7 + netclient server1 server2 eintrc eintrs \
  8 + threadsafe1 threadsafe2 threadsafe3 threadsafe4 \
  9 + threadsafe5 threadsafe6 threadsafe7 \
  10 + signal_example epoll1 epoll2 epoll3 epoll4
  11 +
  12 +all: $(EXECS)
  13 +
  14 +fork1: fork1.c
  15 +
  16 +fork2: fork2.c
  17 +
  18 +fork3: fork3.c
  19 +
  20 +fork4: fork4.c
  21 +
  22 +fork5: fork5.c
  23 +
  24 +fork6: fork6.c
  25 +
  26 +netclient: netclient.c
  27 +
  28 +server1: server1.c
  29 +
  30 +server2: server2.c
  31 +
  32 +eintrc: eintrc.c
  33 +
  34 +eintrs: eintrs.c
  35 +
  36 +threadsafe1: threadsafe1.c
  37 +
  38 +threadsafe2: threadsafe2.c
  39 +
  40 +threadsafe3: threadsafe3.c
  41 +
  42 +threadsafe4: threadsafe4.c
  43 +
  44 +threadsafe5: threadsafe5.c
  45 +
  46 +threadsafe6: threadsafe6.c
  47 +
  48 +threadsafe7: threadsafe7.c
  49 +
  50 +signal_example: signal_example.c
  51 +
  52 +epoll1: epoll1.c
  53 +
  54 +epoll2: epoll2.c
  55 +
  56 +epoll3: epoll3.c
  57 +
  58 +epoll4: epoll4.c
  59 +
  60 +.PHONY: clean all
  61 +
  62 +clean:
  63 + rm -f $(EXECS)
... ...
nc 0 → 100755
  1 +++ a/nc
  1 +#!/bin/bash
  2 +
  3 +./netclient >> res &
... ...
netclient.c 0 → 100644
  1 +++ a/netclient.c
  1 +/* Make the necessary includes and set up the variables. */
  2 +
  3 +#include <sys/types.h>
  4 +#include <sys/socket.h>
  5 +#include <stdio.h>
  6 +#include <stdlib.h>
  7 +#include <netinet/in.h>
  8 +#include <arpa/inet.h>
  9 +#include <unistd.h>
  10 +
  11 +int
  12 +main ()
  13 +{
  14 + int sockfd;
  15 + socklen_t len;
  16 + struct sockaddr_in address;
  17 + int result;
  18 + char ch = 'A';
  19 +
  20 + /* Create a socket for the client. */
  21 +
  22 + sockfd = socket (AF_INET, SOCK_STREAM, 0);
  23 +
  24 + /* Name the socket, as agreed with the server. */
  25 +
  26 + address.sin_family = AF_INET;
  27 + address.sin_addr.s_addr = inet_addr ("127.0.0.1");
  28 + address.sin_port = htons (9734);
  29 + len = sizeof (address);
  30 +
  31 + /* Now connect our socket to the server's socket. */
  32 +
  33 + result = connect (sockfd, (struct sockaddr *) &address, len);
  34 +
  35 + if (result == -1)
  36 + {
  37 + perror ("oops: netclient");
  38 + exit (1);
  39 + }
  40 +
  41 + /* We can now read/write via sockfd. */
  42 +
  43 + write (sockfd, &ch, 1);
  44 + read (sockfd, &ch, 1);
  45 + printf ("char from server = %c\n", ch);
  46 + close (sockfd);
  47 + exit (0);
  48 +}
... ...
server1.c 0 → 100644
  1 +++ a/server1.c
  1 +#include <sys/types.h>
  2 +#include <sys/socket.h>
  3 +#include <stdio.h>
  4 +#include <netinet/in.h>
  5 +#include <signal.h>
  6 +#include <unistd.h>
  7 +
  8 +int
  9 +main ()
  10 +{
  11 + int server_sockfd, client_sockfd;
  12 + socklen_t server_len, client_len;
  13 + struct sockaddr_in server_address;
  14 + struct sockaddr_in client_address;
  15 +
  16 + server_sockfd = socket (AF_INET, SOCK_STREAM, 0);
  17 +
  18 + server_address.sin_family = AF_INET;
  19 + server_address.sin_addr.s_addr = htonl (INADDR_ANY);
  20 + server_address.sin_port = htons (9734);
  21 + server_len = sizeof (server_address);
  22 + bind (server_sockfd, (struct sockaddr *) &server_address, server_len);
  23 +
  24 + /* Create a connection queue and wait for clients. */
  25 +
  26 + listen (server_sockfd, 5);
  27 +
  28 + while (1)
  29 + {
  30 + char ch;
  31 +
  32 + printf ("server waiting\n");
  33 +
  34 + /* Accept connection. */
  35 +
  36 + client_len = sizeof (client_address);
  37 + client_sockfd = accept (server_sockfd,
  38 + (struct sockaddr *) &client_address,
  39 + &client_len);
  40 +
  41 + /* We can now read/write to the client on client_sockfd.
  42 + The five second delay is just for this demonstration. */
  43 +
  44 + read (client_sockfd, &ch, 1);
  45 + sleep (5);
  46 + ch++;
  47 + write (client_sockfd, &ch, 1);
  48 + close (client_sockfd);
  49 + }
  50 +}
... ...
server2.c 0 → 100644
  1 +++ a/server2.c
  1 +#include <sys/types.h>
  2 +#include <sys/socket.h>
  3 +#include <stdio.h>
  4 +#include <stdlib.h>
  5 +#include <netinet/in.h>
  6 +#include <signal.h>
  7 +#include <unistd.h>
  8 +
  9 +int
  10 +main ()
  11 +{
  12 + int server_sockfd, client_sockfd;
  13 + socklen_t server_len, client_len;
  14 + struct sockaddr_in server_address;
  15 + struct sockaddr_in client_address;
  16 +
  17 + server_sockfd = socket (AF_INET, SOCK_STREAM, 0);
  18 +
  19 + server_address.sin_family = AF_INET;
  20 + server_address.sin_addr.s_addr = htonl (INADDR_ANY);
  21 + server_address.sin_port = htons (9734);
  22 + server_len = sizeof (server_address);
  23 + bind (server_sockfd, (struct sockaddr *) &server_address, server_len);
  24 +
  25 + /* Create a connection queue, ignore child exit details and wait for clients. */
  26 +
  27 + listen (server_sockfd, 5);
  28 +
  29 + signal (SIGCHLD, SIG_IGN);
  30 +
  31 + while (1)
  32 + {
  33 + char ch;
  34 +
  35 + printf ("server waiting\n");
  36 +
  37 + /* Accept connection. */
  38 +
  39 + client_len = sizeof (client_address);
  40 + client_sockfd = accept (server_sockfd,
  41 + (struct sockaddr *) &client_address,
  42 + &client_len);
  43 +
  44 + /* Fork to create a process for this client and perform a test to see
  45 + whether we're the parent or the child. */
  46 +
  47 + if (fork () == 0)
  48 + {
  49 +
  50 + /* If we're the child, we can now read/write to the client on client_sockfd.
  51 + The five second delay is just for this demonstration. */
  52 +
  53 + read (client_sockfd, &ch, 1);
  54 + sleep (5);
  55 + ch++;
  56 + write (client_sockfd, &ch, 1);
  57 + close (client_sockfd);
  58 + exit (0);
  59 + }
  60 +
  61 + /* Otherwise, we must be the parent and our work for this client is finished. */
  62 +
  63 + else
  64 + {
  65 + close (client_sockfd);
  66 + }
  67 + }
  68 +}
... ...
signal_example.c 0 → 100644
  1 +++ a/signal_example.c
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <unistd.h>
  4 +#include <signal.h>
  5 +#include <sys/types.h>
  6 +#include <sys/wait.h>
  7 +#include <errno.h>
  8 +
  9 +void
  10 +signal_handler (int what)
  11 +{
  12 + printf ("Signal number: %d\n", what);
  13 + printf ("Waiting for signal ... [send SIGKILL to abort]\n");
  14 +}
  15 +
  16 +int
  17 +main ()
  18 +{
  19 + struct sigaction sig;
  20 + sig.sa_handler = signal_handler;
  21 + sigemptyset (&sig.sa_mask);
  22 + sig.sa_flags = SA_NOCLDSTOP;
  23 + sigaction (SIGHUP, &sig, NULL);
  24 + sigaction (SIGINT, &sig, NULL);
  25 + sigaction (SIGQUIT, &sig, NULL);
  26 + sigaction (SIGABRT, &sig, NULL);
  27 + sigaction (SIGALRM, &sig, NULL);
  28 + sigaction (SIGTERM, &sig, NULL);
  29 + sigaction (SIGUSR1, &sig, NULL);
  30 + sigaction (SIGUSR2, &sig, NULL);
  31 +
  32 + printf ("PID: %d\n", getpid ());
  33 + printf ("Waiting for signal ... [send SIGKILL to abort]\n");
  34 +
  35 + while (1)
  36 + sleep (1);
  37 +
  38 + exit (0);
  39 +}
... ...
testnc 0 → 100755
  1 +++ a/testnc
  1 +#!/bin/bash
  2 +
  3 +rm -f res
  4 +for i in `seq 15`
  5 +do
  6 + ./nc
  7 +done
  8 +tail -f res
... ...
threadsafe1.c 0 → 100644
  1 +++ a/threadsafe1.c
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <pthread.h>
  4 +
  5 +char *
  6 +unsafe_itoa (int number)
  7 +{
  8 + static char buf[16];
  9 + int i = 0, j;
  10 + do
  11 + {
  12 + buf[i++] = number % 10 + '0';
  13 + number /= 10;
  14 + }
  15 + while (number);
  16 + buf[i] = 0;
  17 + for (j = 0; j < i / 2; j++)
  18 + {
  19 + char c = buf[j];
  20 + buf[j] = buf[i - j - 1];
  21 + buf[i - j - 1] = c;
  22 + };
  23 + return buf;
  24 +}
  25 +
  26 +
  27 +void *
  28 +thread (void *param)
  29 +{
  30 + int start = *((int *) (param));
  31 + int i;
  32 + printf("Hello from thread %d\n",start);
  33 + for (i = 0; i < 10000; i++)
  34 + printf ("%d %s\n", i + start, unsafe_itoa (i + start));
  35 + pthread_exit (param);
  36 +}
  37 +
  38 +int
  39 +main (int argc, char *argv[])
  40 +{
  41 + pthread_t t1, t2;
  42 + pthread_attr_t attr;
  43 + int a, b;
  44 + void *retval;
  45 + a = 0;
  46 + pthread_attr_init (&attr);
  47 + pthread_create (&t1, &attr, thread, &a);
  48 + if (argc > 1)
  49 + {
  50 + b = 10000;
  51 + pthread_create (&t2, &attr, thread, &b);
  52 + pthread_join (t2, &retval);
  53 + };
  54 + pthread_join (t1, &retval);
  55 + exit (0);
  56 +}
... ...
threadsafe2.c 0 → 100644
  1 +++ a/threadsafe2.c
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <pthread.h>
  4 +
  5 +char *
  6 +safe_itoa (int number, char *buf)
  7 +{
  8 + int i = 0, j;
  9 + do
  10 + {
  11 + buf[i++] = number % 10 + '0';
  12 + number /= 10;
  13 + }
  14 + while (number);
  15 + buf[i] = 0;
  16 + for (j = 0; j < i / 2; j++)
  17 + {
  18 + char c = buf[j];
  19 + buf[j] = buf[i - j - 1];
  20 + buf[i - j - 1] = c;
  21 + };
  22 + return buf;
  23 +}
  24 +
  25 +
  26 +void *
  27 +thread (void *param)
  28 +{
  29 + char buf[16];
  30 + int start = *((int *) (param));
  31 + int i;
  32 + printf ("Hello from thread %d\n", start);
  33 + for (i = 0; i < 10000; i++)
  34 + printf ("%d %s\n", i + start, safe_itoa (i + start, buf));
  35 + pthread_exit (param);
  36 +}
  37 +int
  38 +main (int argc, char *argv[])
  39 +{
  40 + pthread_t t1, t2;
  41 + pthread_attr_t attr;
  42 + int a, b;
  43 + void *retval;
  44 + a = 0;
  45 + pthread_attr_init (&attr);
  46 + pthread_create (&t1, &attr, thread, &a);
  47 + if (argc > 1)
  48 + {
  49 + b = 10000;
  50 + pthread_create (&t2, &attr, thread, &b);
  51 + pthread_join (t2, &retval);
  52 + };
  53 + pthread_join (t1, &retval);
  54 + exit (0);
  55 +}
... ...
threadsafe3.c 0 → 100644
  1 +++ a/threadsafe3.c
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <pthread.h>
  4 +
  5 +char *
  6 +unsafe_itoa (int number)
  7 +{
  8 + static char buf[16];
  9 + int i = 0, j;
  10 + do
  11 + {
  12 + buf[i++] = number % 10 + '0';
  13 + number /= 10;
  14 + }
  15 + while (number);
  16 + buf[i] = 0;
  17 + for (j = 0; j < i / 2; j++)
  18 + {
  19 + char c = buf[j];
  20 + buf[j] = buf[i - j - 1];
  21 + buf[i - j - 1] = c;
  22 + };
  23 + return buf;
  24 +}
  25 +
  26 +pthread_mutex_t itoa_mutex;
  27 +
  28 +void *
  29 +thread (void *param)
  30 +{
  31 + int start = *((int *) (param));
  32 + int i;
  33 + printf("Hello from thread %d\n",start);
  34 + for (i = 0; i < 10000; i++)
  35 + {
  36 + pthread_mutex_lock(&itoa_mutex);
  37 + printf ("%d %s\n", i + start, unsafe_itoa (i + start));
  38 + pthread_mutex_unlock(&itoa_mutex);
  39 + }
  40 + pthread_exit (param);
  41 +}
  42 +
  43 +int
  44 +main (int argc, char *argv[])
  45 +{
  46 + pthread_t t1, t2;
  47 + pthread_attr_t attr;
  48 + int a, b;
  49 + void *retval;
  50 + a = 0;
  51 + pthread_mutex_init(&itoa_mutex,NULL);
  52 + pthread_attr_init (&attr);
  53 + pthread_create (&t1, &attr, thread, &a);
  54 + if (argc > 1)
  55 + {
  56 + b = 10000;
  57 + pthread_create (&t2, &attr, thread, &b);
  58 + pthread_join (t2, &retval);
  59 + };
  60 + pthread_join (t1, &retval);
  61 + pthread_mutex_destroy(&itoa_mutex);
  62 + exit (0);
  63 +}
... ...
threadsafe4.c 0 → 100644
  1 +++ a/threadsafe4.c
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <pthread.h>
  4 +
  5 +int c;
  6 +
  7 +void *
  8 +thread (void *param)
  9 +{
  10 + int i;
  11 + for (i = 0; i < 10000; i++)
  12 + {
  13 + c=c*123413123+7;;
  14 + }
  15 + pthread_exit (param);
  16 +}
  17 +
  18 +int
  19 +main (int argc, char *argv[])
  20 +{
  21 + pthread_t t1, t2;
  22 + pthread_attr_t attr;
  23 + int a, b;
  24 + void *retval;
  25 + a = 0;
  26 + pthread_attr_init (&attr);
  27 + pthread_create (&t1, &attr, thread, &a);
  28 + if (argc > 1)
  29 + {
  30 + b = 10000;
  31 + pthread_create (&t2, &attr, thread, &b);
  32 + pthread_join (t2, &retval);
  33 + };
  34 + pthread_join (t1, &retval);
  35 + printf("c=%d\n",c);
  36 + exit (0);
  37 +}
... ...
threadsafe5.c 0 → 100644
  1 +++ a/threadsafe5.c
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <pthread.h>
  4 +
  5 +int c;
  6 +
  7 +pthread_mutex_t itoa_mutex;
  8 +
  9 +void *
  10 +thread (void *param)
  11 +{
  12 + int i;
  13 + for (i = 0; i < 10000; i++)
  14 + {
  15 + pthread_mutex_lock(&itoa_mutex);
  16 + c=c*123413123+7;;
  17 + pthread_mutex_unlock(&itoa_mutex);
  18 + }
  19 + pthread_exit (param);
  20 +}
  21 +
  22 +int
  23 +main (int argc, char *argv[])
  24 +{
  25 + pthread_t t1, t2;
  26 + pthread_attr_t attr;
  27 + int a, b;
  28 + void *retval;
  29 + a = 0;
  30 + pthread_mutex_init(&itoa_mutex,NULL);
  31 + pthread_attr_init (&attr);
  32 + pthread_create (&t1, &attr, thread, &a);
  33 + if (argc > 1)
  34 + {
  35 + b = 10000;
  36 + pthread_create (&t2, &attr, thread, &b);
  37 + pthread_join (t2, &retval);
  38 + };
  39 + pthread_join (t1, &retval);
  40 + pthread_mutex_destroy(&itoa_mutex);
  41 + printf("c=%d\n",c);
  42 + exit (0);
  43 +}
... ...
threadsafe6.c 0 → 100644
  1 +++ a/threadsafe6.c
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <pthread.h>
  4 +
  5 +volatile int c;
  6 +
  7 +pthread_mutex_t itoa_mutex;
  8 +
  9 +void *
  10 +thread (void *param)
  11 +{
  12 + int i;
  13 + for (i = 0; i < 10000; i++)
  14 + {
  15 + pthread_mutex_lock(&itoa_mutex);
  16 + c=c*123413123+7;;
  17 + pthread_mutex_unlock(&itoa_mutex);
  18 + }
  19 + pthread_exit (param);
  20 +}
  21 +
  22 +int
  23 +main (int argc, char *argv[])
  24 +{
  25 + pthread_t t1, t2;
  26 + pthread_attr_t attr;
  27 + int a, b;
  28 + void *retval;
  29 + a = 0;
  30 + pthread_mutex_init(&itoa_mutex,NULL);
  31 + pthread_attr_init (&attr);
  32 + pthread_create (&t1, &attr, thread, &a);
  33 + if (argc > 1)
  34 + {
  35 + b = 10000;
  36 + pthread_create (&t2, &attr, thread, &b);
  37 + pthread_join (t2, &retval);
  38 + };
  39 + pthread_join (t1, &retval);
  40 + pthread_mutex_destroy(&itoa_mutex);
  41 + printf("c=%d\n",c);
  42 + exit (0);
  43 +}
... ...
threadsafe7.c 0 → 100644
  1 +++ a/threadsafe7.c
  1 +#include <stdio.h>
  2 +#include <stdlib.h>
  3 +#include <pthread.h>
  4 +
  5 +volatile int c;
  6 +
  7 +void *
  8 +thread (void *param)
  9 +{
  10 + int i;
  11 + for (i = 0; i < 10000; i++)
  12 + {
  13 + c=c*123413123+7;;
  14 + }
  15 + pthread_exit (param);
  16 +}
  17 +
  18 +int
  19 +main (int argc, char *argv[])
  20 +{
  21 + pthread_t t1, t2;
  22 + pthread_attr_t attr;
  23 + int a, b;
  24 + void *retval;
  25 + a = 0;
  26 + pthread_attr_init (&attr);
  27 + pthread_create (&t1, &attr, thread, &a);
  28 + if (argc > 1)
  29 + {
  30 + b = 10000;
  31 + pthread_create (&t2, &attr, thread, &b);
  32 + pthread_join (t2, &retval);
  33 + };
  34 + pthread_join (t1, &retval);
  35 + printf("c=%d\n",c);
  36 + exit (0);
  37 +}
... ...