Example #1
0
int
my_fstat(int fd, Stat_t *sbufptr)
{
    /* This fixes a bug in fstat() on Windows 9x.  fstat() uses the
     * GetFileType() win32 syscall, which will fail on Windows 9x.
     * So if we recognize a socket on Windows 9x, we return the
     * same results as on Windows NT/2000.
     * XXX this should be extended further to set S_IFSOCK on
     * sbufptr->st_mode.
     */
    int osf;
    if (!wsock_started || IsWinNT()) {
#if defined(WIN64) || defined(USE_LARGE_FILES)
#if defined(__BORLANDC__) /* buk */
	return win32_fstat(fd, sbufptr );
#else
	return _fstati64(fd, sbufptr);
#endif
#else
	return fstat(fd, sbufptr);
#endif
    }

    osf = TO_SOCKET(fd);
    if (osf != -1) {
	char sockbuf[256];
	int optlen = sizeof(sockbuf);
	int retval;

	retval = getsockopt((SOCKET)osf, SOL_SOCKET, SO_TYPE, sockbuf, &optlen);
	if (retval != SOCKET_ERROR || WSAGetLastError() != WSAENOTSOCK) {
#if defined(__BORLANDC__)&&(__BORLANDC__<=0x520)
	    sbufptr->st_mode = S_IFIFO;
#else
	    sbufptr->st_mode = _S_IFIFO;
#endif
	    sbufptr->st_rdev = sbufptr->st_dev = (dev_t)fd;
	    sbufptr->st_nlink = 1;
	    sbufptr->st_uid = sbufptr->st_gid = sbufptr->st_ino = 0;
	    sbufptr->st_atime = sbufptr->st_mtime = sbufptr->st_ctime = 0;
	    sbufptr->st_size = (Off_t)0;
	    return 0;
	}
    }
#if defined(WIN64) || defined(USE_LARGE_FILES)
#if defined(__BORLANDC__) /* buk */
    return win32_fstat(fd, sbufptr );
#else
    return _fstati64(fd, sbufptr);
#endif
#else
    return fstat(fd, sbufptr);
#endif
}
Example #2
0
/* Win32 */ sf_count_t
psf_get_filelen (SF_PRIVATE *psf)
{
#if 0
	/* 
	** Windoze is SOOOOO F****D!!!!!!!
	** This code should work but doesn't. Why?
	** Code below does work.
	*/
	struct _stati64 statbuf ;

	if (_fstati64 (psf->filedes, &statbuf))
	{	psf_log_syserr (psf, errno) ;
		return (sf_count_t) -1 ;
		} ;

	return statbuf.st_size ;
#else
	sf_count_t  current, len ;
	
	current = psf_fseek (psf, 0, SEEK_CUR) ;
	len = psf_fseek (psf, 0, SEEK_END) ;
	psf_fseek (psf, current, SEEK_SET) ;
	
	return len ;
#endif
} /* psf_get_filelen */
Example #3
0
/* Get file length ... 64-bitally. -1 for error.
 */
gint64
vips_file_length( int fd )
{
#ifdef OS_WIN32
	struct _stati64 st;

	if( _fstati64( fd, &st ) == -1 ) {
#else /*!OS_WIN32*/
	struct stat st;

	if( fstat( fd, &st ) == -1 ) {
#endif /*OS_WIN32*/
		vips_error_system( errno, "vips_file_length", 
			"%s", _( "unable to get file stats" ) );
		return( -1 );
	}

	return( st.st_size );
}

/* Wrap write() up
 */
int
vips__write( int fd, const void *buf, size_t count )
{
	do {
		size_t nwritten = write( fd, buf, count );

		if( nwritten == (size_t) -1 ) {
                        vips_error_system( errno, "vips__write", 
				"%s", _( "write failed" ) );
                        return( -1 ); 
		}

		buf = (void *) ((char *) buf + nwritten);
		count -= nwritten;
	} while( count > 0 );

	return( 0 );
}

#ifdef OS_WIN32
/* Set the create date on a file. On Windows, the create date may be copied 
 * over from an existing file of the same name, unless you reset it. 
 *
 * See https://blogs.msdn.microsoft.com/oldnewthing/20050715-14/?p=34923
 */
void
vips__set_create_time( int fd )
{
	HANDLE handle;
	SYSTEMTIME st;
	FILETIME ft;

	if( (handle = _get_osfhandle( fd )) == INVALID_HANDLE_VALUE )
		return;
	GetSystemTime( &st );
	SystemTimeToFileTime( &st, &ft );
	SetFileTime( handle, &ft, &ft, &ft );
}
Example #4
0
/*
  Quick and dirty my_fstat() implementation for Windows.
  Use CRT fstat on temporarily allocated file descriptor.
  Patch file size, because size that fstat returns is not 
  reliable (may be outdated)
*/
int my_win_fstat(File fd, struct _stati64 *buf)
{
  int crt_fd;
  int retval;
  HANDLE hFile, hDup;

  DBUG_ENTER("my_win_fstat");

  hFile= my_get_osfhandle(fd);
  if(!DuplicateHandle( GetCurrentProcess(), hFile, GetCurrentProcess(), 
    &hDup ,0,FALSE,DUPLICATE_SAME_ACCESS))
  {
    my_osmaperr(GetLastError());
    DBUG_RETURN(-1);
  }
  if ((crt_fd= _open_osfhandle((intptr_t)hDup,0)) < 0)
    DBUG_RETURN(-1);

  retval= _fstati64(crt_fd, buf);
  if(retval == 0)
  {
    /* File size returned by stat is not accurate (may be outdated), fix it*/
    GetFileSizeEx(hDup, (PLARGE_INTEGER) (&(buf->st_size)));
  }
  _close(crt_fd);
  DBUG_RETURN(retval);
}
Example #5
0
int sim_fseeko (FILE *st, t_offset offset, int whence)
{
fpos_t fileaddr;
struct _stati64 statb;

switch (whence) {

    case SEEK_SET:
        fileaddr = (fpos_t)offset;
        break;

    case SEEK_END:
        if (_fstati64 (_fileno (st), &statb))
            return (-1);
        fileaddr = statb.st_size + offset;
        break;
    case SEEK_CUR:
        if (fgetpos (st, &fileaddr))
            return (-1);
        fileaddr = fileaddr + offset;
        break;

    default:
        errno = EINVAL;
        return (-1);
        }

return fsetpos (st, &fileaddr);
}
Example #6
0
int mingw_fstat(int fd, struct stat *buf)
{
	HANDLE fh = (HANDLE)_get_osfhandle(fd);
	BY_HANDLE_FILE_INFORMATION fdata;

	if (fh == INVALID_HANDLE_VALUE) {
		errno = EBADF;
		return -1;
	}
	/* direct non-file handles to MS's fstat() */
	if (GetFileType(fh) != FILE_TYPE_DISK)
		return _fstati64(fd, buf);

	if (GetFileInformationByHandle(fh, &fdata)) {
		buf->st_ino = 0;
		buf->st_gid = 0;
		buf->st_uid = 0;
		buf->st_nlink = 1;
		buf->st_mode = file_attr_to_st_mode(fdata.dwFileAttributes);
		buf->st_size = fdata.nFileSizeLow |
			(((off_t)fdata.nFileSizeHigh)<<32);
		buf->st_dev = buf->st_rdev = 0; /* not used by Git */
		buf->st_atime = filetime_to_time_t(&(fdata.ftLastAccessTime));
		buf->st_mtime = filetime_to_time_t(&(fdata.ftLastWriteTime));
		buf->st_ctime = filetime_to_time_t(&(fdata.ftCreationTime));
		return 0;
	}
	errno = EBADF;
	return -1;
}
Example #7
0
CAMLprim value unix_fstat_64(value handle)
{
  int ret;
  struct _stati64 buf;

  ret = _fstati64(win_CRT_fd_of_filedescr(handle), &buf);
  if (ret == -1) uerror("fstat", Nothing);
  return stat_aux(1, &buf);
}
Example #8
0
/* Get file length ... 64-bitally. -1 for error.
 */
gint64
vips_file_length( int fd )
{
#ifdef OS_WIN32
	struct _stati64 st;

	if( _fstati64( fd, &st ) == -1 ) {
#else /*!OS_WIN32*/
	struct stat st;

	if( fstat( fd, &st ) == -1 ) {
#endif /*OS_WIN32*/
		vips_error_system( errno, "vips_file_length", 
			"%s", _( "unable to get file stats" ) );
		return( -1 );
	}

	return( st.st_size );
}

/* Wrap write() up
 */
int
vips__write( int fd, const void *buf, size_t count )
{
	do {
		size_t nwritten = write( fd, buf, count );

		if( nwritten == (size_t) -1 ) {
                        vips_error_system( errno, "vips__write", 
				"%s", _( "write failed" ) );
                        return( -1 ); 
		}

		buf = (void *) ((char *) buf + nwritten);
		count -= nwritten;
	} while( count > 0 );

	return( 0 );
}

/* Does a filename contain a directory separator?
 */
static gboolean 
filename_hasdir( const char *filename )
{
	char *dirname;
	gboolean hasdir;

	dirname = g_path_get_dirname( filename );
	hasdir = (strcmp( dirname, "." ) != 0);
	g_free( dirname );

	return( hasdir );
}
Example #9
0
/* Win32 */ sf_count_t
psf_get_filelen (int fd)
{	struct _stati64 statbuf ;

	if (_fstati64 (fd, &statbuf))
	{	perror ("fstat") ;
		return -1 ;
		} ;

	return statbuf.st_size ;
} /* psf_fclose */
Example #10
0
File: fs.c Project: Cahya/node
void fs__fstat(uv_fs_t* req, uv_file file) {
  int result;

  result = _fstati64(file, &req->stat);
  if (result == -1) {
    req->ptr = NULL;
  } else {
    req->ptr = &req->stat;
  }

  SET_REQ_RESULT(req, result);
}
Example #11
0
CAMLprim value unix_fstat(value handle)
{
  int ret;
  struct _stati64 buf;

  ret = _fstati64(win_CRT_fd_of_filedescr(handle), &buf);
  if (ret == -1) uerror("fstat", Nothing);
  if (buf.st_size > Max_long) {
    win32_maperr(ERROR_ARITHMETIC_OVERFLOW);
    uerror("fstat", Nothing);
  }
  return stat_aux(0, &buf);
}
Example #12
0
int _fstat64i32( int fd, struct _stat64i32 *buffer )
{
	struct _stat64 s;
	int retval = _fstati64( fd, &s );
	if(!retval )
	{
		buffer->st_atime = s.st_atime;
		buffer->st_ctime = s.st_ctime;
		buffer->st_dev = s.st_dev;
		buffer->st_gid = s.st_gid;
		buffer->st_ino = s.st_ino;
		buffer->st_mode = s.st_mode;
		buffer->st_mtime = s.st_mtime;
		buffer->st_nlink = s.st_nlink;
		buffer->st_rdev = s.st_rdev;
		buffer->st_size = (_off_t)s.st_size;
		buffer->st_uid = s.st_uid;
	}
	return retval;
}
Example #13
0
//==============================
// FileSize
static size_t FileSize( FILE * f
 )
{
	if ( f == NULL )
	{
		return 0;
	}
#if defined( WIN32 )
	struct _stat64 stats;
	__int64 r = _fstati64( f->_file, &stats );
#else
	struct stat stats;
	int r = fstat( f->_file, &stats );
#endif
	if ( r < 0 )
	{
		return 0;
	}
	return static_cast< size_t >( stats.st_size );	// why st_size is signed I have no idea... negative file lengths?
}
Example #14
0
/**
 * Internal implementation of _wstati64().
 * MSVCRT's _wstati64() fails if the filename contains '?' or '*',
 * which breaks long filename support, e.g. \\?\.
 * @param pathname Pathname.
 * @param buf Stat buffer.
 * @return 0 on success; -1 on error.
 */
static int W32U_wstati64(const wchar_t *pathname, struct _stati64 *buffer)
{
	int fd, ret;

	if (!pathname || !buffer) {
		errno = EINVAL;
		return -1;
	}

	// _fstati64() can obtain all the information.
	// We just need to open the file first.
	// FIXME: Use FindFirstFileW() instead to avoid having to open the file?
	fd = _wopen(pathname, _O_RDONLY, 0);
	if (fd < 0) {
		// Error opening the file.
		return fd;
	}

	ret = _fstati64(fd, buffer);
	_close(fd);
	return ret;
}
	// must not be called in the ctor, can throw exceptions
	void MemoryDataSource::_loadFile()
	{
		if (this->data == NULL)
		{
			VideoClip::Format format;
			FILE* file = openSupportedFormatFile(filename, format, this->fullFilename);
			if (file == NULL)
			{
				std::string message = "Can't open or find video file: " + filename;
				log(message);
				throw TheoraplayerException(message);
			}
			this->formatName = format.name;
#ifdef _WIN32
			struct _stat64 s;
			_fstati64(_fileno(file), &s);
#else
			struct stat s;
			fstat(fileno(file), &s);
#endif
			this->size = (int64_t)s.st_size;
			if (this->size > 0xFFFFFFFF)
			{
				fclose(file);
				throw TheoraplayerException("MemoryDataSource doesn't support files larger than 4GB!");
			}
			if (this->size < UINT_MAX)
			{
				this->data = new unsigned char[(unsigned int)this->size];
				fread(this->data, 1, (size_t)this->size, file);
			}
			else
			{
				fclose(file);
				throw TheoraplayerException("Unable to preload file to memory, file is too large.");
			}
			fclose(file);
		}
	}
Example #16
0
/** Retrieves a file's size
 * @param[in] _pstFile              Concerned file
 * @return Returns the length of the file, <= 0 if invalid
 */
orxS64 orxFASTCALL orxFile_GetSize(const orxFILE *_pstFile)
{
  orxS64 s64Result;

  /* Checks */
  orxASSERT((sstFile.u32Flags & orxFILE_KU32_STATIC_FLAG_READY) == orxFILE_KU32_STATIC_FLAG_READY);

  /* Valid? */
  if(_pstFile != orxNULL)
  {
#if defined(__orxWINDOWS__) && (_MSC_VER < 1900)

    struct _stati64 stStat;

    /* Gets file stats */
    _fstati64(((FILE *)_pstFile)->_file, &stStat);

#else /* __orxWINDOWS__ && _MSC_VER < 1900 */

    struct stat stStat;

    /* Gets file stats */
    fstat(fileno((FILE *)_pstFile), &stStat);

#endif /* __orxWINDOWS__ && _MSC_VER < 1900 */

    /* Updates result */
    s64Result = (orxS64)stStat.st_size;
  }
  else
  {
    /* Updates result */
    s64Result = 0;
  }

  /* Done! */
  return s64Result;
}
	void FileDataSource::_openFile()
	{
		if (this->filePtr == NULL)
		{
			VideoClip::Format format;
			this->filePtr = openSupportedFormatFile(this->filename, format, this->fullFilename);
			if (this->filePtr == NULL)
			{
				std::string message = "Can't open or find video file: " + filename;
				log(message);
				throw TheoraplayerException(message);
			}
			this->formatName = format.name;
#ifdef _WIN32
			struct _stat64 s;
			_fstati64(_fileno(this->filePtr), &s);
#else
			struct stat s;
			fstat(fileno(this->filePtr), &s);
#endif
			this->length = (int64_t)s.st_size;
		}
	}
Example #18
0
int sim_fseeko (FILE *st, t_offset offset, int whence)
{
fpos_t fileaddr;
#ifdef _WIN32_WCE
struct stat statb;
#else
struct _stati64 statb;
#endif

switch (whence) {

    case SEEK_SET:
        fileaddr = (fpos_t)offset;
        break;

    case SEEK_END:
#ifdef _WIN32_WCE
		if(fstat(fileno(st), &statb) < 0)
#else
        if (_fstati64(_fileno (st), &statb) < 0)
#endif
            return (-1);
        fileaddr = statb.st_size + offset;
        break;
    case SEEK_CUR:
        if (fgetpos (st, &fileaddr))
            return (-1);
        fileaddr = fileaddr + offset;
        break;

    default:
        errno = EINVAL;
        return (-1);
        }

return fsetpos (st, &fileaddr);
}
__private_extern__ SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pathURL, Boolean *exists, SInt32 *posixMode, int64_t *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents) {
    Boolean fileExists;
    Boolean isDirectory = false;

#if DEPLOYMENT_TARGET_WINDOWS
    struct _stati64 statBuf;
    int fd = -1;
#else
    struct stat64 statBuf;
#endif
    char path[CFMaxPathSize];

    if ((exists == NULL) && (posixMode == NULL) && (size == NULL) && (modTime == NULL) && (ownerID == NULL) && (dirContents == NULL)) {
        // Nothing to do.
        return 0;
    }

    if (!CFURLGetFileSystemRepresentation(pathURL, true, (uint8_t *)path, CFMaxPathLength)) {
        return -1;
    }

#if DEPLOYMENT_TARGET_WINDOWS
    HANDLE hFile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0);
    if (INVALID_HANDLE_VALUE == hFile)
       return -1;

    fd = _open_osfhandle((intptr_t)hFile, _O_RDONLY|CF_OPENFLGS);
    if (fd < 0) {
        if (thread_errno() == ENOENT) {
            fileExists = false;
        } else {
            CloseHandle (hFile);
            return thread_errno();
        }
    }
    else
    {
        if (_fstati64(fd, &statBuf) != 0) {
            close(fd);
            CloseHandle (hFile);
            // stat failed, but why?
            if (thread_errno() == ENOENT) {
                fileExists = false;
            } else {
                return thread_errno();
            }
       } else {
            close(fd);
            CloseHandle (hFile);
            fileExists = true;
            isDirectory = ((statBuf.st_mode & S_IFMT) == S_IFDIR);
       }
    }
#else
    if (stat64(path, &statBuf) != 0) {
        // stat failed, but why?
        if (thread_errno() == ENOENT) {
            fileExists = false;
        } else {
            return thread_errno();
        }
    } else {
        fileExists = true;
        isDirectory = ((statBuf.st_mode & S_IFMT) == S_IFDIR);
    }    
#endif

    if (exists != NULL) {
        *exists = fileExists;
    }

    if (posixMode != NULL) {
        if (fileExists) {

            *posixMode = statBuf.st_mode;

        } else {
            *posixMode = 0;
        }
    }

    if (size != NULL) {
        if (fileExists) {

            *size = statBuf.st_size;

        } else {
            *size = 0;
        }
    }

    if (modTime != NULL) {
        if (fileExists) {
#if DEPLOYMENT_TARGET_WINDOWS
            CFAbsoluteTime theTime = (CFAbsoluteTime)statBuf.st_mtime;
#elif DEPLOYMENT_TARGET_LINUX
#if defined _BSD_SOURCE || defined _SVID_SOURCE
            CFAbsoluteTime theTime = (CFAbsoluteTime)statBuf.st_mtim.tv_sec - kCFAbsoluteTimeIntervalSince1970;
            theTime += (CFAbsoluteTime)statBuf.st_mtim.tv_nsec / 1000000000.0;
#else
            CFAbsoluteTime theTime = (CFAbsoluteTime)statBuf.st_mtime - kCFAbsoluteTimeIntervalSince1970;
            theTime += (CFAbsoluteTime)statBuf.st_mtimensec / 1000000000.0;
#endif /* defined _BSD_SOURCE || defined _SVID_SOURCE */
#else
            CFAbsoluteTime theTime = (CFAbsoluteTime)statBuf.st_mtimespec.tv_sec - kCFAbsoluteTimeIntervalSince1970;
            theTime += (CFAbsoluteTime)statBuf.st_mtimespec.tv_nsec / 1000000000.0;
#endif
            *modTime = CFDateCreate(alloc, theTime);
        } else {
            *modTime = NULL;
        }
    }

    if (ownerID != NULL) {
        if (fileExists) {

            *ownerID = statBuf.st_uid;

        } else {
            *ownerID = -1;
        }
    }
    
    if (dirContents != NULL) {
        if (fileExists && isDirectory) {

            CFMutableArrayRef contents = _CFContentsOfDirectory(alloc, path, NULL, pathURL, NULL);

            if (contents) {
                *dirContents = contents;
            } else {
                *dirContents = NULL;
            }
        } else {
            *dirContents = NULL;
        }
    }
    return 0;
}
Example #20
0
__private_extern__ SInt32 _CFGetFileProperties(CFAllocatorRef alloc, CFURLRef pathURL, Boolean *exists, SInt32 *posixMode, int64_t *size, CFDateRef *modTime, SInt32 *ownerID, CFArrayRef *dirContents) {
    Boolean fileExists;
    Boolean isDirectory = false;

#if DEPLOYMENT_TARGET_WINDOWS
    struct _stati64 statBuf;
    int fd = -1;
#else
    struct stat64 statBuf;
#endif
    char path[CFMaxPathSize];

    if ((exists == NULL) && (posixMode == NULL) && (size == NULL) && (modTime == NULL) && (ownerID == NULL) && (dirContents == NULL)) {
        // Nothing to do.
        return 0;
    }

    if (!CFURLGetFileSystemRepresentation(pathURL, true, (uint8_t *)path, CFMaxPathLength)) {
        return -1;
    }

#if DEPLOYMENT_TARGET_WINDOWS
    SECURITY_ATTRIBUTES sa;
    sa.nLength = sizeof(sa);
    sa.bInheritHandle = TRUE;
    sa.lpSecurityDescriptor = NULL;

    HANDLE hFile = CreateFileA(path, GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, &sa, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
    if (INVALID_HANDLE_VALUE == hFile)
    {
       DWORD error = GetLastError ();
       return -1;
    }

    fd = _open_osfhandle((intptr_t)hFile, _O_RDONLY|CF_OPENFLGS);
    if (fd < 0) {
        if (thread_errno() == ENOENT) {
            fileExists = false;
        } else {
            CloseHandle (hFile);
            return thread_errno();
        }
    }
    else
    {
        if (_fstati64(fd, &statBuf) != 0) {
            close(fd);

            // stat failed, but why?
            if (thread_errno() == ENOENT) {
                fileExists = false;
            } else {
                return thread_errno();
            }
       } else {
            fileExists = true;

            // Hack to work around Windows strange stat behavior:
            DWORD attributes = GetFileAttributesA (path);
            close(fd);

            if (attributes & FILE_ATTRIBUTE_DIRECTORY)
            {
               statBuf.st_mode &= ~S_IFREG;  // Don't claim it's a regular file.
               statBuf.st_mode |= S_IFDIR;   // Properly mark it as a directory
            }

            isDirectory = ((statBuf.st_mode & S_IFMT) == S_IFDIR);
       }
    }
#else
    if (stat64(path, &statBuf) != 0) {
        // stat failed, but why?
        if (thread_errno() == ENOENT) {
            fileExists = false;
        } else {
            return thread_errno();
        }
    } else {
        fileExists = true;
        isDirectory = ((statBuf.st_mode & S_IFMT) == S_IFDIR);
    }    
#endif

    if (exists != NULL) {
        *exists = fileExists;
    }

    if (posixMode != NULL) {
        if (fileExists) {

            *posixMode = statBuf.st_mode;

        } else {
            *posixMode = 0;
        }
    }

    if (size != NULL) {
        if (fileExists) {

            *size = statBuf.st_size;

        } else {
            *size = 0;
        }
    }

    if (modTime != NULL) {
        if (fileExists) {
#if DEPLOYMENT_TARGET_WINDOWS
            CFAbsoluteTime theTime = (CFAbsoluteTime)statBuf.st_mtime;
#elif DEPLOYMENT_TARGET_LINUX
#if defined _BSD_SOURCE || defined _SVID_SOURCE
            CFAbsoluteTime theTime = (CFAbsoluteTime)statBuf.st_mtim.tv_sec - kCFAbsoluteTimeIntervalSince1970;
            theTime += (CFAbsoluteTime)statBuf.st_mtim.tv_nsec / 1000000000.0;
#else
            CFAbsoluteTime theTime = (CFAbsoluteTime)statBuf.st_mtime - kCFAbsoluteTimeIntervalSince1970;
            theTime += (CFAbsoluteTime)statBuf.st_mtimensec / 1000000000.0;
#endif /* defined _BSD_SOURCE || defined _SVID_SOURCE */
#else
            CFAbsoluteTime theTime = (CFAbsoluteTime)statBuf.st_mtimespec.tv_sec - kCFAbsoluteTimeIntervalSince1970;
            theTime += (CFAbsoluteTime)statBuf.st_mtimespec.tv_nsec / 1000000000.0;
#endif
            *modTime = CFDateCreate(alloc, theTime);
        } else {
            *modTime = NULL;
        }
    }

    if (ownerID != NULL) {
        if (fileExists) {

            *ownerID = statBuf.st_uid;

        } else {
            *ownerID = -1;
        }
    }
    
    if (dirContents != NULL) {
        if (fileExists && isDirectory) {

            CFMutableArrayRef contents = _CFContentsOfDirectory(alloc, path, NULL, pathURL, NULL);

            if (contents) {
                *dirContents = contents;
            } else {
                *dirContents = NULL;
            }
        } else {
            *dirContents = NULL;
        }
    }
    return 0;
}
Example #21
0
static int
handle_overwrite_open (const char    *filename,
		       const char    *etag,
		       gboolean       create_backup,
		       char         **temp_filename,
		       GCancellable  *cancellable,
		       GError       **error)
{
  int fd = -1;
  GLocalFileStat original_stat;
  char *current_etag;
  gboolean is_symlink;
  int open_flags;
  int res;

  /* We only need read access to the original file if we are creating a backup.
   * We also add O_CREATE to avoid a race if the file was just removed */
  if (create_backup)
    open_flags = O_RDWR | O_CREAT | O_BINARY;
  else
    open_flags = O_WRONLY | O_CREAT | O_BINARY;
  
  /* Some systems have O_NOFOLLOW, which lets us avoid some races
   * when finding out if the file we opened was a symlink */
#ifdef O_NOFOLLOW
  is_symlink = FALSE;
  fd = g_open (filename, open_flags | O_NOFOLLOW, 0666);
  if (fd == -1 && errno == ELOOP)
    {
      /* Could be a symlink, or it could be a regular ELOOP error,
       * but then the next open will fail too. */
      is_symlink = TRUE;
      fd = g_open (filename, open_flags, 0666);
    }
#else
  fd = g_open (filename, open_flags, 0666);
  /* This is racy, but we do it as soon as possible to minimize the race */
  is_symlink = g_file_test (filename, G_FILE_TEST_IS_SYMLINK);
#endif
    
  if (fd == -1)
    {
      int errsv = errno;
      char *display_name = g_filename_display_name (filename);
      g_set_error (error, G_IO_ERROR,
		   g_io_error_from_errno (errsv),
		   _("Error opening file '%s': %s"),
		   display_name, g_strerror (errsv));
      g_free (display_name);
      return -1;
    }
  
#ifdef G_OS_WIN32
  res = _fstati64 (fd, &original_stat);
#else
  res = fstat (fd, &original_stat);
#endif

  if (res != 0) 
    {
      int errsv = errno;
      char *display_name = g_filename_display_name (filename);
      g_set_error (error, G_IO_ERROR,
		   g_io_error_from_errno (errsv),
		   _("Error stating file '%s': %s"),
		   display_name, g_strerror (errsv));
      g_free (display_name);
      goto err_out;
    }
  
  /* not a regular file */
  if (!S_ISREG (original_stat.st_mode))
    {
      if (S_ISDIR (original_stat.st_mode))
	g_set_error_literal (error,
                             G_IO_ERROR,
                             G_IO_ERROR_IS_DIRECTORY,
                             _("Target file is a directory"));
      else
	g_set_error_literal (error,
                             G_IO_ERROR,
                             G_IO_ERROR_NOT_REGULAR_FILE,
                             _("Target file is not a regular file"));
      goto err_out;
    }
  
  if (etag != NULL)
    {
      current_etag = _g_local_file_info_create_etag (&original_stat);
      if (strcmp (etag, current_etag) != 0)
	{
	  g_set_error_literal (error,
                               G_IO_ERROR,
                               G_IO_ERROR_WRONG_ETAG,
                               _("The file was externally modified"));
	  g_free (current_etag);
	  goto err_out;
	}
      g_free (current_etag);
    }

  /* We use two backup strategies.
   * The first one (which is faster) consist in saving to a
   * tmp file then rename the original file to the backup and the
   * tmp file to the original name. This is fast but doesn't work
   * when the file is a link (hard or symbolic) or when we can't
   * write to the current dir or can't set the permissions on the
   * new file. 
   * The second strategy consist simply in copying the old file
   * to a backup file and rewrite the contents of the file.
   */
  
  if (!(original_stat.st_nlink > 1) && !is_symlink)
    {
      char *dirname, *tmp_filename;
      int tmpfd;
      
      dirname = g_path_get_dirname (filename);
      tmp_filename = g_build_filename (dirname, ".goutputstream-XXXXXX", NULL);
      g_free (dirname);

      tmpfd = g_mkstemp (tmp_filename);
      if (tmpfd == -1)
	{
	  g_free (tmp_filename);
	  goto fallback_strategy;
	}
      
      /* try to keep permissions */

      if (
#ifdef HAVE_FCHOWN
	  fchown (tmpfd, original_stat.st_uid, original_stat.st_gid) == -1 ||
#endif
#ifdef HAVE_FCHMOD
	  fchmod (tmpfd, original_stat.st_mode) == -1 ||
#endif
	  0
	  )
	{
	  struct stat tmp_statbuf;
	  
	  /* Check that we really needed to change something */
	  if (fstat (tmpfd, &tmp_statbuf) != 0 ||
	      original_stat.st_uid != tmp_statbuf.st_uid ||
	      original_stat.st_gid != tmp_statbuf.st_gid ||
	      original_stat.st_mode != tmp_statbuf.st_mode)
	    {
	      close (tmpfd);
	      g_unlink (tmp_filename);
	      g_free (tmp_filename);
	      goto fallback_strategy;
	    }
	}

      close (fd);
      *temp_filename = tmp_filename;
      return tmpfd;
    }

 fallback_strategy:

  if (create_backup)
    {
#if defined(HAVE_FCHOWN) && defined(HAVE_FCHMOD)
      struct stat tmp_statbuf;      
#endif
      char *backup_filename;
      int bfd;
      
      backup_filename = create_backup_filename (filename);

      if (g_unlink (backup_filename) == -1 && errno != ENOENT)
	{
	  g_set_error_literal (error,
                               G_IO_ERROR,
                               G_IO_ERROR_CANT_CREATE_BACKUP,
                               _("Backup file creation failed"));
	  g_free (backup_filename);
	  goto err_out;
	}

      bfd = g_open (backup_filename,
		    O_WRONLY | O_CREAT | O_EXCL | O_BINARY,
		    original_stat.st_mode & 0777);

      if (bfd == -1)
	{
	  g_set_error_literal (error,
                               G_IO_ERROR,
                               G_IO_ERROR_CANT_CREATE_BACKUP,
                               _("Backup file creation failed"));
	  g_free (backup_filename);
	  goto err_out;
	}

      /* If needed, Try to set the group of the backup same as the
       * original file. If this fails, set the protection
       * bits for the group same as the protection bits for
       * others. */
#if defined(HAVE_FCHOWN) && defined(HAVE_FCHMOD)
      if (fstat (bfd, &tmp_statbuf) != 0)
	{
	  g_set_error_literal (error,
                               G_IO_ERROR,
                               G_IO_ERROR_CANT_CREATE_BACKUP,
                               _("Backup file creation failed"));
	  g_unlink (backup_filename);
	  g_free (backup_filename);
	  goto err_out;
	}
      
      if ((original_stat.st_gid != tmp_statbuf.st_gid)  &&
	  fchown (bfd, (uid_t) -1, original_stat.st_gid) != 0)
	{
	  if (fchmod (bfd,
		      (original_stat.st_mode & 0707) |
		      ((original_stat.st_mode & 07) << 3)) != 0)
	    {
	      g_set_error_literal (error,
                                   G_IO_ERROR,
                                   G_IO_ERROR_CANT_CREATE_BACKUP,
                                   _("Backup file creation failed"));
	      g_unlink (backup_filename);
	      close (bfd);
	      g_free (backup_filename);
	      goto err_out;
	    }
	}
#endif

      if (!copy_file_data (fd, bfd, NULL))
	{
	  g_set_error_literal (error,
                               G_IO_ERROR,
                               G_IO_ERROR_CANT_CREATE_BACKUP,
                               _("Backup file creation failed"));
	  g_unlink (backup_filename);
	  close (bfd);
	  g_free (backup_filename);
	  
	  goto err_out;
	}
      
      close (bfd);
      g_free (backup_filename);

      /* Seek back to the start of the file after the backup copy */
      if (lseek (fd, 0, SEEK_SET) == -1)
	{
          int errsv = errno;

	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error seeking in file: %s"),
		       g_strerror (errsv));
	  goto err_out;
	}
    }

  /* Truncate the file at the start */
#ifdef G_OS_WIN32
  if (g_win32_ftruncate (fd, 0) == -1)
#else
  if (ftruncate (fd, 0) == -1)
#endif
    {
      int errsv = errno;

      g_set_error (error, G_IO_ERROR,
		   g_io_error_from_errno (errsv),
		   _("Error truncating file: %s"),
		   g_strerror (errsv));
      goto err_out;
    }
    
  return fd;

 err_out:
  close (fd);
  return -1;
}
Example #22
0
static gboolean
g_local_file_output_stream_close (GOutputStream  *stream,
				  GCancellable   *cancellable,
				  GError        **error)
{
  GLocalFileOutputStream *file;
  GLocalFileStat final_stat;
  int res;

  file = G_LOCAL_FILE_OUTPUT_STREAM (stream);

#ifdef G_OS_WIN32

  /* Must close before renaming on Windows, so just do the close first
   * in all cases for now.
   */
  if (_fstati64 (file->priv->fd, &final_stat) == 0)
    file->priv->etag = _g_local_file_info_create_etag (&final_stat);

  res = close (file->priv->fd);
  if (res == -1)
    {
      int errsv = errno;
      
      g_set_error (error, G_IO_ERROR,
		   g_io_error_from_errno (errsv),
		   _("Error closing file: %s"),
		   g_strerror (errsv));
      return FALSE;
    }

#endif

  if (file->priv->tmp_filename)
    {
      /* We need to move the temp file to its final place,
       * and possibly create the backup file
       */

      if (file->priv->backup_filename)
	{
	  if (g_cancellable_set_error_if_cancelled (cancellable, error))
	    goto err_out;
	  
#ifdef HAVE_LINK
	  /* create original -> backup link, the original is then renamed over */
	  if (g_unlink (file->priv->backup_filename) != 0 &&
	      errno != ENOENT)
	    {
              int errsv = errno;

	      g_set_error (error, G_IO_ERROR,
			   G_IO_ERROR_CANT_CREATE_BACKUP,
			   _("Error removing old backup link: %s"),
			   g_strerror (errsv));
	      goto err_out;
	    }

	  if (link (file->priv->original_filename, file->priv->backup_filename) != 0)
	    {
	      /*  link failed or is not supported, try rename  */
	      if (g_rename (file->priv->original_filename, file->priv->backup_filename) != 0)
		{
                  int errsv = errno;

	    	  g_set_error (error, G_IO_ERROR,
		    	       G_IO_ERROR_CANT_CREATE_BACKUP,
			       _("Error creating backup copy: %s"),
			       g_strerror (errsv));
	          goto err_out;
		}
	    }
#else
	    /* If link not supported, just rename... */
	  if (g_rename (file->priv->original_filename, file->priv->backup_filename) != 0)
	    {
              int errsv = errno;

	      g_set_error (error, G_IO_ERROR,
			   G_IO_ERROR_CANT_CREATE_BACKUP,
			   _("Error creating backup copy: %s"),
			   g_strerror (errsv));
	      goto err_out;
	    }
#endif
	}
      

      if (g_cancellable_set_error_if_cancelled (cancellable, error))
	goto err_out;

      /* tmp -> original */
      if (g_rename (file->priv->tmp_filename, file->priv->original_filename) != 0)
	{
          int errsv = errno;

	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errno),
		       _("Error renaming temporary file: %s"),
		       g_strerror (errsv));
	  goto err_out;
	}
    }
  
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    goto err_out;
      
#ifndef G_OS_WIN32		/* Already did the fstat() and close() above on Win32 */

  if (fstat (file->priv->fd, &final_stat) == 0)
    file->priv->etag = _g_local_file_info_create_etag (&final_stat);

  while (1)
    {
      res = close (file->priv->fd);
      if (res == -1)
	{
          int errsv = errno;

	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error closing file: %s"),
		       g_strerror (errsv));
	}
      break;
    }
  
  return res != -1;

#else

  return TRUE;

#endif

 err_out:

#ifndef G_OS_WIN32
  /* A simple try to close the fd in case we fail before the actual close */
  close (file->priv->fd);
#endif
  return FALSE;
}
Example #23
0
File: util.c Project: kjell/libvips
/* Get file length ... 64-bitally. -1 for error.
 */
gint64
vips_file_length( int fd )
{
#ifdef OS_WIN32
	struct _stati64 st;

	if( _fstati64( fd, &st ) == -1 ) {
#else /*!OS_WIN32*/
	struct stat st;

	if( fstat( fd, &st ) == -1 ) {
#endif /*OS_WIN32*/
		vips_error_system( errno, "vips_file_length", 
			"%s", _( "unable to get file stats" ) );
		return( -1 );
	}

	return( st.st_size );
}

/* Wrap write() up
 */
int
vips__write( int fd, const void *buf, size_t count )
{
	do {
		size_t nwritten = write( fd, buf, count );

		if( nwritten == (size_t) -1 ) {
                        vips_error_system( errno, "vips__write", 
				"%s", _( "write failed" ) );
                        return( -1 ); 
		}

		buf = (void *) ((char *) buf + nwritten);
		count -= nwritten;
	} while( count > 0 );

	return( 0 );
}

/* open() with a utf8 filename, setting errno.
 */
int
vips__open( const char *filename, int flags, ... )
{
	int fd;
	mode_t mode;
	va_list ap;

	va_start( ap, flags );
	mode = va_arg( ap, int );
	va_end( ap );

#ifdef OS_WIN32
{
	wchar_t *path16;

	if( !(path16 = (wchar_t *) 
		g_utf8_to_utf16( filename, -1, NULL, NULL, NULL )) ) { 
		errno = EACCES;
		return( -1 );
	}

	fd = _wopen( path16, flags, mode );

	g_free( path16 );
}
#else /*!OS_WIN32*/
	fd = open( filename, flags, mode );
#endif

	return( fd );
}
Example #24
0
/* Retrieves the size of the file
 * This function uses the POSIX fstat function or equivalent
 * Returns 1 if successful or -1 on error
 */
int libcfile_stream_get_size(
     libcfile_stream_t *stream,
     size64_t *size,
     libcerror_error_t **error )
{
#if defined( _MSC_VER )
	struct __stat64 file_statistics;
#elif defined( __BORLANDC__ )
	struct stati64 file_statistics;
#else
	struct stat file_statistics;
#endif

	libcfile_internal_stream_t *internal_stream = NULL;
	static char *function                       = "libcfile_stream_get_size";
	size_t file_statistics_size                 = 0;
	int file_descriptor                         = 0;

#if defined( S_ISBLK ) && defined( S_ISCHR )
	off64_t current_offset                      = 0;
	off64_t offset                              = 0;
#endif

	if( stream == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid stream.",
		 function );

		return( -1 );
	}
	internal_stream = (libcfile_internal_stream_t *) stream;

	if( internal_stream->stream == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_VALUE_MISSING,
		 "%s: invalid stream - missing stream.",
		 function );

		return( -1 );
	}
	if( size == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_ARGUMENTS,
		 LIBCERROR_ARGUMENT_ERROR_INVALID_VALUE,
		 "%s: invalid size.",
		 function );

		return( -1 );
	}
#if defined( _MSC_VER )
	file_statistics_size = sizeof( struct __stat64 );
#elif defined( __BORLANDC__ )
	file_statistics_size = sizeof( struct stati64 );
#else
	file_statistics_size = sizeof( struct stat );
#endif

	if( memory_set(
	     &file_statistics,
	     0,
	     file_statistics_size ) == NULL )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_MEMORY,
		 LIBCERROR_MEMORY_ERROR_SET_FAILED,
		 "%s: unable to clear file statistics.",
		 function );

		return( -1 );
	}
#if defined( WINAPI )
	file_descriptor = _fileno(
	                   internal_stream->stream );
#else
	file_descriptor = fileno(
	                   internal_stream->stream );
#endif

	if( file_descriptor == -1 )
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to retrieve file descriptor of stream.",
		 function );

		return( -1 );
	}
#if defined( _MSC_VER )
	if( _fstat64(
	     file_descriptor,
	     &file_statistics ) != 0 )
#elif defined( __BORLANDC__ )
	if( _fstati64(
	     file_descriptor,
	     &file_statistics ) != 0 )
#else
	if( fstat(
	     file_descriptor,
	     &file_statistics ) != 0 )
#endif
	{
		libcerror_error_set(
		 error,
		 LIBCERROR_ERROR_DOMAIN_RUNTIME,
		 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
		 "%s: unable to retrieve file statistics.",
		 function );

		return( -1 );
	}
/* TODO implement device support ? */
/* TODO does not work on Mac OS X or WINAPI */
#if defined( S_ISBLK ) && defined( S_ISCHR )
	if( S_ISBLK( file_statistics.st_mode )
	 || S_ISCHR( file_statistics.st_mode ) )
	{
		if( libcfile_stream_get_offset(
		     stream,
		     &current_offset,
		     error ) != 1  )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_RUNTIME,
			 LIBCERROR_RUNTIME_ERROR_GET_FAILED,
			 "%s: unable to retrieve current offset.",
			 function );

			return( -1 );
		}
		/* If the file is a device try to seek the end of the file
		 */
		offset = libcfile_stream_seek_offset(
		          stream,
		          0,
		          SEEK_END,
		          error );

		if( offset == -1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_SEEK_FAILED,
			 "%s: unable to seek end of file.",
			 function );

			return( -1 );
		}
		*size = (size64_t) offset;

		offset = libcfile_stream_seek_offset(
		          stream,
		          current_offset,
		          SEEK_SET,
		          error );

		if( offset == -1 )
		{
			libcerror_error_set(
			 error,
			 LIBCERROR_ERROR_DOMAIN_IO,
			 LIBCERROR_IO_ERROR_SEEK_FAILED,
			 "%s: unable to seek offset: %" PRIi64 ".",
			 function,
			 current_offset );

			return( -1 );
		}
	}
	else
#endif
	{
		*size = (size64_t) file_statistics.st_size;
	}
	return( 1 );
}
Example #25
0
gboolean
_g_local_file_output_stream_really_close (GLocalFileOutputStream *file,
					  GCancellable   *cancellable,
					  GError        **error)
{
  GLocalFileStat final_stat;

#ifdef HAVE_FSYNC
  if (file->priv->sync_on_close &&
      fsync (file->priv->fd) != 0)
    {
      int errsv = errno;
      
      g_set_error (error, G_IO_ERROR,
		   g_io_error_from_errno (errsv),
		   _("Error writing to file: %s"),
		   g_strerror (errsv));
      goto err_out;
    }
#endif
 
#ifdef G_OS_WIN32

  /* Must close before renaming on Windows, so just do the close first
   * in all cases for now.
   */
  if (_fstati64 (file->priv->fd, &final_stat) == 0)
    file->priv->etag = _g_local_file_info_create_etag (&final_stat);

  if (!g_close (file->priv->fd, NULL))
    {
      int errsv = errno;
      
      g_set_error (error, G_IO_ERROR,
		   g_io_error_from_errno (errsv),
		   _("Error closing file: %s"),
		   g_strerror (errsv));
      return FALSE;
    }

#endif

  if (file->priv->tmp_filename)
    {
      /* We need to move the temp file to its final place,
       * and possibly create the backup file
       */

      if (file->priv->backup_filename)
	{
	  if (g_cancellable_set_error_if_cancelled (cancellable, error))
	    goto err_out;
	  
#ifdef G_OS_UNIX
	  /* create original -> backup link, the original is then renamed over */
	  if (g_unlink (file->priv->backup_filename) != 0 &&
	      errno != ENOENT)
	    {
              int errsv = errno;

	      g_set_error (error, G_IO_ERROR,
			   G_IO_ERROR_CANT_CREATE_BACKUP,
			   _("Error removing old backup link: %s"),
			   g_strerror (errsv));
	      goto err_out;
	    }

	  if (link (file->priv->original_filename, file->priv->backup_filename) != 0)
	    {
	      /*  link failed or is not supported, try rename  */
	      if (g_rename (file->priv->original_filename, file->priv->backup_filename) != 0)
		{
                  int errsv = errno;

	    	  g_set_error (error, G_IO_ERROR,
		    	       G_IO_ERROR_CANT_CREATE_BACKUP,
			       _("Error creating backup copy: %s"),
			       g_strerror (errsv));
	          goto err_out;
		}
	    }
#else
	    /* If link not supported, just rename... */
	  if (g_rename (file->priv->original_filename, file->priv->backup_filename) != 0)
	    {
              int errsv = errno;

	      g_set_error (error, G_IO_ERROR,
			   G_IO_ERROR_CANT_CREATE_BACKUP,
			   _("Error creating backup copy: %s"),
			   g_strerror (errsv));
	      goto err_out;
	    }
#endif
	}
      

      if (g_cancellable_set_error_if_cancelled (cancellable, error))
	goto err_out;

      /* tmp -> original */
      if (g_rename (file->priv->tmp_filename, file->priv->original_filename) != 0)
	{
          int errsv = errno;

	  g_set_error (error, G_IO_ERROR,
		       g_io_error_from_errno (errsv),
		       _("Error renaming temporary file: %s"),
		       g_strerror (errsv));
	  goto err_out;
	}

      g_clear_pointer (&file->priv->tmp_filename, g_free);
    }
  
  if (g_cancellable_set_error_if_cancelled (cancellable, error))
    goto err_out;
      
#ifndef G_OS_WIN32		/* Already did the fstat() and close() above on Win32 */

  if (fstat (file->priv->fd, &final_stat) == 0)
    file->priv->etag = _g_local_file_info_create_etag (&final_stat);

  if (!g_close (file->priv->fd, NULL))
    {
      int errsv = errno;
      
      g_set_error (error, G_IO_ERROR,
                   g_io_error_from_errno (errsv),
                   _("Error closing file: %s"),
                   g_strerror (errsv));
      goto err_out;
    }

#endif
  
  return TRUE;
 err_out:

#ifndef G_OS_WIN32
  /* A simple try to close the fd in case we fail before the actual close */
  g_close (file->priv->fd, NULL);
#endif
  if (file->priv->tmp_filename)
    g_unlink (file->priv->tmp_filename);

  return FALSE;
}