socket_utimes.c

text/plain

Filename: socket_utimes.c
Type: text/plain
Part: 0
Message: Re: Bug #882: Cannot manually log in to database.
#include <sys/time.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/un.h>

#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>

int
main(int argc, char *argv[])
{
    char *path;
    int sock_fd;
    struct sockaddr_un addr;
    struct stat sb_before;
    struct stat sb_after;

    if (argc != 2) {
        fprintf(stderr, "usage: socket_utimes path\n");
        exit(EXIT_FAILURE);
    }
    path = argv[1];

    sock_fd = socket(AF_UNIX, SOCK_STREAM, 0);
    if (sock_fd == -1) {
        fprintf(stderr, "socket: %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }

    memset(&addr, 0, sizeof(addr));
    addr.sun_family = AF_UNIX;
    strncpy(addr.sun_path, path, sizeof(addr.sun_path) - 1);

#ifndef SUN_LEN
#define SUN_LEN(su) \
    (sizeof(*(su)) - sizeof((su)->sun_path) + strlen((su)->sun_path)) 
#endif

    if (bind(sock_fd, (struct sockaddr *) &addr, SUN_LEN(&addr)) == -1) {
        fprintf(stderr, "bind: %s\n", strerror(errno));
        exit(EXIT_FAILURE);
    }

    if (stat(path, &sb_before) == -1) {
        fprintf(stderr, "stat: %s: %s\n", path, strerror(errno));
        (void) unlink(path);
        exit(EXIT_FAILURE);
    }

    sleep(2);

    if (utimes(path, (struct timeval *) 0) == -1) {
        fprintf(stderr, "utimes: %s: %s\n", path, strerror(errno));
        (void) unlink(path);
        exit(EXIT_FAILURE);
    }

    if (stat(path, &sb_after) == -1) {
        fprintf(stderr, "stat: %s: %s\n", path, strerror(errno));
        (void) unlink(path);
        exit(EXIT_FAILURE);
    }

    if (sb_before.st_mtime == sb_after.st_mtime) {
        printf("Oops: utimes() failed to change mtime\n");
        (void) unlink(path);
        exit(EXIT_FAILURE);
    }

    printf("utimes() successfully changed a Unix domain socket mtime.\n");
    (void) unlink(path);
    exit(EXIT_SUCCESS);
}