AsiaBSDCon 2017 Secure CGI

Asynchronous example

Asynchronous example

    1 /* Title: Asynchronous example */
    2 
    3 #include <err.h>
    4 #include <stdlib.h>
    5 #include <stdio.h>
    6 #include <unistd.h>
    7 
    8 int
    9 main(int argc, char *argv[])
   10 {
   11 	int	 c, async = 0;
   12 	pid_t	 pid;
   13 
   14 	/* 
   15 	 * Catch whether we're reentering.
   16 	 * This is "hackish", but works very well.
   17 	 */
   18 
   19 	while (-1 != (c = getopt(argc, argv, "X"))) 
   20 		switch (c) {
   21 		case 'X':
   22 			async = 1;
   23 			break;
   24 		default:
   25 			return(EXIT_SUCCESS);
   26 		}
   27 
   28 	if (async) {	
   29 		/*
   30 		 * Here we'd do our hard work.
   31 		 * We'll just sleep for a long time.
   32 		 */
   33 		sleep(20);
   34 		return(EXIT_SUCCESS);
   35 	}
   36 
   37 	/* Give our response to the server. */
   38 
   39 	puts("Status: 200 OK\r");
   40 	puts("Content-Type: text/html\r");
   41 	puts("\r");
   42 	puts("Hello, world!");
   43 
   44 	/* Start our worker child. */
   45 
   46 	if (0 == (pid = fork())) {
   47 		/*
   48 		 * Daemonise to close our file descriptors.
   49 		 * This will often "release" the calling web 
   50 		 * server from our request.
   51 		 */
   52 		if (-1 == daemon(1, 0))
   53 			err(EXIT_FAILURE, NULL);
   54 		execl(argv[0], argv[0], "-X", (char *)NULL);
   55 		err(EXIT_FAILURE, "%s", argv[0]);
   56 	} else if (-1 == pid)
   57 		err(EXIT_FAILURE, NULL);
   58 
   59 	/* 
   60 	 * Parent exits now, so if our web server is
   61 	 * waiting for child exit to release the request,
   62 	 * it will do so now.
   63 	 */
   64 
   65 	return(EXIT_SUCCESS);
   66 }
gcc -I/usr/local/include -static -o async async.c -L/usr/local/lib -lksql -lsqlite3