#include #include #include #include #include #include #include #include #include #include "syslog_test.h" int syslog_test(void) { int status = 0; int fd = socket(AF_UNIX, SOCK_DGRAM, 0); if (fd < 0) { perror("syslog_test: socket"); status = 1; goto syslog_test_exit_0; } if (fcntl(fd, F_SETFL, O_NONBLOCK) != 0) { perror("syslog_test: fcntl"); status = 1; goto syslog_test_exit_1; } // remove it if already there; ignore error unlink(SYSLOG_SOCK_NAME); struct sockaddr_un sa_un; memset(&sa_un, 0, sizeof(sa_un)); sa_un.sun_family = AF_UNIX; strncpy(sa_un.sun_path, SYSLOG_SOCK_NAME, sizeof(sa_un.sun_path) - 1); if (bind(fd, (struct sockaddr *)&sa_un, sizeof(sa_un)) != 0) { perror("syslog_test: bind"); status = 1; goto syslog_test_exit_1; } openlog("test", 0, LOG_LOCAL0); char msg[256]; // should be nothing there if (recv(fd, msg, sizeof(msg), 0) != -1 || (errno != EAGAIN && errno != EWOULDBLOCK)) { fprintf(stderr, "syslog_test: unexpected message\n"); status = 1; goto syslog_test_exit_2; } syslog(LOG_INFO, "hello!"); // should be a message if (recv(fd, msg, sizeof(msg), 0) <= 0) { fprintf(stderr, "syslog_test: expected message (%s)\n", strerror(errno)); status = 1; goto syslog_test_exit_2; } // should be nothing there if (recv(fd, msg, sizeof(msg), 0) != -1 || (errno != EAGAIN && errno != EWOULDBLOCK)) { fprintf(stderr, "syslog_test: unexpected message\n"); status = 1; goto syslog_test_exit_2; } // Test dropping messages: Send more than can be queued, then verify we // get fewer than that back. On the next send, a "drop" message should be // inserted, so verify that after clearing out the queue, one more message // causes two to be received. // fill it up such that it drops messages int msgs_sent = 200; int n; for (n = 0; n < msgs_sent; n++) syslog(LOG_INFO, "hello!"); // should get fewer than that back n = 0; int r; while ((r = recv(fd, msg, sizeof(msg), 0)) > 0) { // msg[r] = '\0'; // msg is not '\0' terminated // printf("%s\n", msg); n++; } if (n >= msgs_sent) { // this might mean /proc/sys/net/unix/max_dgram_qlen > msgs_sent fprintf(stderr, "syslog_test: received too many messages\n"); status = 1; goto syslog_test_exit_2; } // on the next one, we get the drop message then the new message syslog(LOG_INFO, "hello!"); n = 0; while ((r = recv(fd, msg, sizeof(msg), 0)) > 0) { // msg[r] = '\0'; // msg is not '\0' terminated // printf("%s\n", msg); n++; } if (n != 2) { fprintf(stderr, "syslog_test: did not get drop message\n"); status = 1; goto syslog_test_exit_2; } // Verify overflowing the maximum message length for (n = 0; n < SYSLOG_MSG_MAX; n++) { // create a string of length n memset(msg, 'X', n); msg[n] = '\0'; syslog(LOG_INFO, msg); memset(msg, 0, sizeof(msg)); if ((r = recv(fd, msg, sizeof(msg), 0)) <= 0) { fprintf(stderr, "syslog_test: expected message (%s)\n", strerror(errno)); status = 1; goto syslog_test_exit_2; } msg[r] = '\0'; // msg is not '\0' terminated // syslog.c was compiled with SYSLOG_MSG_MAX, so the total length of // the returned message should be less than that if (strlen(msg) >= (SYSLOG_MSG_MAX - 1)) { fprintf(stderr, "syslog_test: message overflow\n"); status = 1; goto syslog_test_exit_2; } // printf("%s\n", msg); // again, with formatting that would overrun memset(msg, ' ', n); msg[n] = '%'; msg[n + 1] = 'd'; msg[n + 2] = '\0'; syslog(LOG_INFO, msg, 1234); memset(msg, 0, sizeof(msg)); if ((r = recv(fd, msg, sizeof(msg), 0)) <= 0) { fprintf(stderr, "syslog_test: expected message (%s)\n", strerror(errno)); status = 1; goto syslog_test_exit_2; } msg[r] = '\0'; // msg is not '\0' terminated // syslog.c was compiled with SYSLOG_MSG_MAX, so the total length of // the returned message should be less than that if (strlen(msg) >= (SYSLOG_MSG_MAX - 1)) { fprintf(stderr, "syslog_test: message overflow\n"); status = 1; goto syslog_test_exit_2; } // printf("%s\n", msg); } syslog_test_exit_2: closelog(); unlink(SYSLOG_SOCK_NAME); syslog_test_exit_1: close(fd); syslog_test_exit_0: return status; } // syslog_test