X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=src%2Ftext%2Ffilesystem.c;h=31fddef92647e1d80da80da98ce82bc16497cb2d;hb=447d0c8fad511536e86bad5141bd9dd9721ed95a;hp=a0d10502337327e4b396cffafda6e9e1d24fa57d;hpb=3eb3e72a3149bbbf328ce2baa382b65102d72f7b;p=vlc diff --git a/src/text/filesystem.c b/src/text/filesystem.c index a0d1050233..31fddef926 100644 --- a/src/text/filesystem.c +++ b/src/text/filesystem.c @@ -37,6 +37,7 @@ #include #include +#include /* NAME_MAX */ #include #include #ifdef HAVE_DIRENT_H @@ -225,7 +226,7 @@ int vlc_openat (int dir, const char *filename, int flags, ...) return -1; } -#ifdef HAVE_FDOPENDIR +#ifdef HAVE_OPENAT int fd = openat (dir, local_name, flags, mode); # ifdef HAVE_FCNTL if (fd != -1) @@ -322,12 +323,18 @@ char *vlc_readdir( DIR *dir ) return FromWide (ent->d_name); #else struct dirent *ent; - - ent = readdir( (DIR *)dir ); - if( ent == NULL ) + struct + { + struct dirent ent; + char buf[NAME_MAX + 1]; + } buf; + int val = readdir_r (dir, &buf.ent, &ent); + if (val) + { + errno = val; return NULL; - - return vlc_fix_readdir( ent->d_name ); + } + return ent ? vlc_fix_readdir( ent->d_name ) : NULL; #endif } @@ -520,7 +527,17 @@ int vlc_rename (const char *oldpath, const char *newpath) else return -1; #else - return _wrename (wold, wnew); + if (_wrename (wold, wnew) && errno == EACCES) + { /* Windows does not allow atomic file replacement */ + if (_wremove (wnew)) + { + errno = EACCES; /* restore errno */ + return -1; + } + if (_wrename (wold, wnew)) + return -1; + } + return 0; #endif #endif @@ -617,6 +634,8 @@ int vlc_dup (int oldfd) return newfd; } +#include + /** * Creates a socket file descriptor. The new file descriptor has the * close-on-exec flag set. @@ -634,7 +653,7 @@ int vlc_socket (int pf, int type, int proto, bool nonblock) type |= SOCK_CLOEXEC; if (nonblock) type |= SOCK_NONBLOCK; - fd = socket (pf, type | SOCK_NONBLOCK | SOCK_CLOEXEC, proto); + fd = socket (pf, type, proto); if (fd != -1 || errno != EINVAL) return fd; @@ -655,3 +674,55 @@ int vlc_socket (int pf, int type, int proto, bool nonblock) #endif return fd; } + +/** + * Accepts an inbound connection request on a listening socket. + * The new file descriptor has the close-on-exec flag set. + * @param lfd listening socket file descriptor + * @param addr pointer to the peer address or NULL [OUT] + * @param alen pointer to the length of the peer address or NULL [OUT] + * @param nonblock whether to put the new socket in non-blocking mode + * @return a new file descriptor, or -1 on error. + */ +int vlc_accept (int lfd, struct sockaddr *addr, socklen_t *alen, bool nonblock) +{ +#ifdef HAVE_ACCEPT4 + int flags = SOCK_CLOEXEC; + if (nonblock) + flags |= SOCK_NONBLOCK; + + do + { + int fd = accept4 (lfd, addr, alen, flags); + if (fd != -1) + return fd; + } + while (errno == EINTR); + + if (errno != ENOSYS) + return -1; +#endif +#ifdef WIN32 + errno = 0; +#endif + + do + { + int fd = accept (lfd, addr, alen); + if (fd != -1) + { +#ifndef WIN32 + fcntl (fd, F_SETFD, FD_CLOEXEC); + if (nonblock) + fcntl (fd, F_SETFL, fcntl (fd, F_GETFL, 0) | O_NONBLOCK); +#else + if (nonblock) + ioctlsocket (fd, FIONBIO, &(unsigned long){ 1 }); +#endif + return fd; + } + } + while (errno == EINTR); + + return -1; +}