X-Git-Url: https://pintos-os.org/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=lib%2Fsocket-util.c;h=912c47e097f8e80c807cabf3cfddcab343594184;hb=55aa00e0df2cacc67081d31b813328fb39ce3561;hp=adc1c6b26ee9ada8e75035f37d9a098e963973e9;hpb=e1bd3bee5cd7065e019b4b6736918b2fda95fa49;p=openvswitch diff --git a/lib/socket-util.c b/lib/socket-util.c index adc1c6b2..912c47e0 100644 --- a/lib/socket-util.c +++ b/lib/socket-util.c @@ -204,7 +204,7 @@ make_sockaddr_un(const char *name, struct sockaddr_un* un, socklen_t *un_len) * * Returns the socket's fd if successful, otherwise a negative errno value. */ int -make_unix_socket(int style, bool nonblock, bool passcred UNUSED, +make_unix_socket(int style, bool nonblock, bool passcred OVS_UNUSED, const char *bind_path, const char *connect_path) { int error; @@ -400,9 +400,13 @@ exit: * For TCP, the socket will have SO_REUSEADDR turned on. * * On success, returns a non-negative file descriptor. On failure, returns a - * negative errno value. */ + * negative errno value. + * + * If 'sinp' is non-null, then on success the bound address is stored into + * '*sinp'. */ int -inet_open_passive(int style, const char *target_, int default_port) +inet_open_passive(int style, const char *target_, int default_port, + struct sockaddr_in *sinp) { char *target = xstrdup(target_); char *string_ptr = target; @@ -468,6 +472,21 @@ inet_open_passive(int style, const char *target_, int default_port) VLOG_ERR("%s: listen: %s", target_, strerror(error)); goto exit_close; } + + if (sinp) { + socklen_t sin_len = sizeof sin; + if (getsockname(fd, (struct sockaddr *) &sin, &sin_len) < 0){ + error = errno; + VLOG_ERR("%s: getsockname: %s", target_, strerror(error)); + goto exit_close; + } + if (sin.sin_family != AF_INET || sin_len != sizeof sin) { + VLOG_ERR("%s: getsockname: invalid socket name", target_); + goto exit_close; + } + *sinp = sin; + } + error = 0; goto exit; @@ -538,3 +557,34 @@ write_fully(int fd, const void *p_, size_t size, size_t *bytes_written) } return 0; } + +/* Given file name 'file_name', fsyncs the directory in which it is contained. + * Returns 0 if successful, otherwise a positive errno value. */ +int +fsync_parent_dir(const char *file_name) +{ + int error = 0; + char *dir; + int fd; + + dir = dir_name(file_name); + fd = open(dir, O_RDONLY); + if (fd >= 0) { + if (fsync(fd)) { + if (errno == EINVAL || errno == EROFS) { + /* This directory does not support synchronization. Not + * really an error. */ + } else { + error = errno; + VLOG_ERR("%s: fsync failed (%s)", dir, strerror(error)); + } + } + close(fd); + } else { + error = errno; + VLOG_ERR("%s: open failed (%s)", dir, strerror(error)); + } + free(dir); + + return error; +}