Exemplo n.º 1
0
void u0051_hidlookup__create_file__numbers(
	SG_context* pCtx,
	SG_pathname* pPath,
	const char* pszName,
	const SG_uint32 countLines
	)
{
	SG_pathname* pPathFile = NULL;
	SG_uint32 i;
	SG_file* pFile = NULL;

	VERIFY_ERR_CHECK(  SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPathFile, pPath, pszName)  );
	VERIFY_ERR_CHECK(  SG_file__open__pathname(pCtx, pPathFile, SG_FILE_CREATE_NEW | SG_FILE_RDWR, 0600, &pFile)  );
	for (i=0; i<countLines; i++)
	{
		char buf[64];

		VERIFY_ERR_CHECK(  SG_sprintf(pCtx, buf, sizeof(buf), "%d\n", i)  );
		VERIFY_ERR_CHECK(  SG_file__write(pCtx, pFile, (SG_uint32) strlen(buf), (SG_byte*) buf, NULL)  );
	}
	VERIFY_ERR_CHECK(  SG_file__close(pCtx, &pFile)  );

	SG_PATHNAME_NULLFREE(pCtx, pPathFile);

	return;
fail:
	SG_FILE_NULLCLOSE(pCtx, pFile);
	SG_PATHNAME_NULLFREE(pCtx, pPathFile);
}
Exemplo n.º 2
0
void SG_unzip__fetch_next_file_into_file(SG_context* pCtx, SG_unzip* punzip, SG_pathname* pPath, SG_bool* pb, const char** ppsz_name, SG_uint64* piLength)
{
   SG_byte* pBytes = NULL;
    SG_uint32 sofar = 0;
    SG_uint32 got = 0;
    SG_file* pFile = NULL;
    SG_bool b = SG_FALSE;
    SG_uint64 len = 0;
    const char* psz_name = NULL;

    SG_ERR_CHECK(  SG_unzip__goto_next_file(pCtx, punzip, &b, &psz_name, &len)  );
    if (!b)
    {
        *pb = SG_FALSE;
        goto done;
    }

	SG_ERR_CHECK(  SG_malloc(pCtx, (SG_uint32)SG_STREAMING_BUFFER_SIZE, &pBytes)  );

    SG_ERR_CHECK(  SG_file__open__pathname(pCtx, pPath, SG_FILE_WRONLY | SG_FILE_CREATE_NEW, 0644, &pFile)  );

    SG_ERR_CHECK(  SG_unzip__currentfile__open(pCtx, punzip)  );
    while (sofar < (SG_uint32) len)
    {
        SG_uint32 want = 0;
        if ((len - sofar) > SG_STREAMING_BUFFER_SIZE)
        {
            want = SG_STREAMING_BUFFER_SIZE;
        }
        else
        {
            want = (SG_uint32) (len - sofar);
        }
        SG_ERR_CHECK(  SG_unzip__currentfile__read(pCtx, punzip, pBytes, want, &got)  );
        if (!got)
        {
            SG_ERR_THROW(  SG_ERR_UNSPECIFIED  ); /* TODO better error */
        }
        SG_ERR_CHECK(  SG_file__write(pCtx, pFile, got, pBytes, NULL)  );

        sofar += got;
    }
    SG_NULLFREE(pCtx, pBytes);
    SG_ERR_CHECK(  SG_file__close(pCtx, &pFile)  );
    SG_ERR_CHECK(  SG_unzip__currentfile__close(pCtx, punzip)  );

    *pb = SG_TRUE;
    *ppsz_name = psz_name;
    *piLength = len;

done:
    /* fall through */

fail:
    SG_FILE_NULLCLOSE(pCtx, pFile);
    SG_NULLFREE(pCtx, pBytes);

}
void SG_random__generate_random_binary_file(SG_context * pCtx, SG_pathname * pPath, SG_uint64 length)
{
	SG_file * pFile = NULL;
	SG_NULLARGCHECK_RETURN(pPath);
	SG_ERR_CHECK(  SG_file__open__pathname(pCtx, pPath, SG_FILE_OPEN_OR_CREATE|SG_FILE_WRONLY,  0644, &pFile)  );
	SG_ERR_CHECK(  SG_random__write_random_bytes_to_file(pCtx, pFile, length)  );
	SG_ERR_CHECK(  SG_file__close(pCtx, &pFile)  );

	return;
fail:
	SG_FILE_NULLCLOSE(pCtx, pFile);
}
void u0038_test_version(SG_context * pCtx)
{
	/* This test pokes around in closet internals in ways normal closet callers shouldn't. */

	SG_string* pstrEnv = NULL;
	SG_uint32 len;
	SG_pathname* pPathCloset = NULL;
	SG_pathname* pPathClosetVersion = NULL;
	SG_pathname* pPathClosetVersionBackup = NULL;
	SG_file* pFile = NULL;
	SG_vhash* pvh = NULL;
	
	/* Deliberately making this break for closet version 3 -- current is version 2. */
	SG_byte buf[3]; 
	
	VERIFY_ERR_CHECK(  SG_environment__get__str(pCtx, "SGCLOSET", &pstrEnv, &len)  );
	if (len)
	{
		VERIFY_ERR_CHECK(  SG_PATHNAME__ALLOC__SZ(pCtx, &pPathCloset, SG_string__sz(pstrEnv))  );
	}
	else
	{
		VERIFY_ERR_CHECK(  SG_PATHNAME__ALLOC__USER_APPDATA_DIRECTORY(pCtx, &pPathCloset)  );
		VERIFY_ERR_CHECK(  SG_pathname__append__from_sz(pCtx, pPathCloset, ".sgcloset")  );
	}

	VERIFY_ERR_CHECK(  SG_pathname__alloc__pathname_sz(pCtx, &pPathClosetVersion, pPathCloset, "version")  );
	VERIFY_ERR_CHECK(  SG_pathname__alloc__pathname_sz(pCtx, &pPathClosetVersionBackup, pPathCloset, "version.bak")  );

	VERIFY_ERR_CHECK(  SG_fsobj__move__pathname_pathname(pCtx, pPathClosetVersion, pPathClosetVersionBackup)  );
	
	VERIFY_ERR_CHECK(  SG_file__open__pathname(pCtx, pPathClosetVersion, SG_FILE_OPEN_OR_CREATE|SG_FILE_WRONLY|SG_FILE_TRUNC, 0644, &pFile)  );
	VERIFY_ERR_CHECK(  SG_file__write(pCtx, pFile, sizeof(buf), buf, NULL)  ); 
	VERIFY_ERR_CHECK(  SG_file__close(pCtx, &pFile)  );

	SG_closet__descriptors__list(pCtx, &pvh);
	VERIFY_COND("", SG_context__err_equals(pCtx, SG_ERR_UNSUPPORTED_CLOSET_VERSION));
	SG_ERR_DISCARD;

	VERIFY_ERR_CHECK(  SG_fsobj__remove__pathname(pCtx, pPathClosetVersion)  );
	VERIFY_ERR_CHECK(  SG_fsobj__move__pathname_pathname(pCtx, pPathClosetVersionBackup, pPathClosetVersion)  );

	/* Common cleanup */
fail:
	SG_STRING_NULLFREE(pCtx, pstrEnv);
	SG_PATHNAME_NULLFREE(pCtx, pPathCloset);
	SG_PATHNAME_NULLFREE(pCtx, pPathClosetVersion);
	SG_PATHNAME_NULLFREE(pCtx, pPathClosetVersionBackup);
	SG_FILE_NULLCLOSE(pCtx, pFile);
	SG_VHASH_NULLFREE(pCtx, pvh);
}
Exemplo n.º 5
0
int u0020_utf8pathnames__create_file(SG_context * pCtx, const SG_pathname * pPathnameTmpDir, _tableitem * pti)
{
	// create a file in the given tmp dir using the given filename.

	SG_pathname * pPathnameNewFile;
	char * pBufUtf8;
	SG_uint32 lenUtf8;
	SG_file * pFile;
	int iResult;
	SG_bool bTest;

	// convert the utf32 string into utf8.

	VERIFY_ERR_CHECK_DISCARD(  SG_utf8__from_utf32(pCtx, pti->pa32,&pBufUtf8,&lenUtf8)  );	// we have to free pBufUtf8

	// verify that the computed utf8 string matches what we thought it should be.
	// (this hopefully guards against the conversion layer playing NFC/NFD tricks.)

	iResult = SG_utf8__compare(pBufUtf8,(char *)pti->pa8);
	VERIFYP_COND("u0020_utf8pathnames",(iResult==0),("Compare failed [%s][%s]",pBufUtf8,pti->pa8));

	// create full pathname to the file to create.

	VERIFY_ERR_CHECK_DISCARD(  SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx,
															   &pPathnameNewFile,
															   pPathnameTmpDir,pBufUtf8)  );

	// create the file and close it.
	// on Linux when our locale is set to something other than UTF-8, we may
	// get an ICU(10) == U_INVALID_CHAR_FOUND error because the test data is
	// not necessarily friendly to any one locale and there are some NFD
	// cases too.   we map ICU(10) to SG_ERR_UNMAPPABLE_UNICODE_CHAR

	SG_file__open__pathname(pCtx,pPathnameNewFile,SG_FILE_WRONLY|SG_FILE_CREATE_NEW,0755,&pFile);
#if defined(LINUX)
	bTest = (  (!SG_context__has_err(pCtx))  ||  (SG_context__err_equals(pCtx,SG_ERR_UNMAPPABLE_UNICODE_CHAR))  );
#else
	bTest = (  (!SG_context__has_err(pCtx))  );
#endif
	SG_context__err_reset(pCtx);

	VERIFYP_COND("u0020_utf8pathnames",bTest,
			 ("Error Creating file [%s]",SG_pathname__sz(pPathnameNewFile)));

	VERIFY_ERR_CHECK_DISCARD(  SG_file__close(pCtx, &pFile)  );

	SG_PATHNAME_NULLFREE(pCtx, pPathnameNewFile);
	SG_NULLFREE(pCtx, pBufUtf8);

	return 1;
}
Exemplo n.º 6
0
void _read_template_file(
	SG_context *pCtx,
	const char *templateFn,
	SG_string **pContent,	/**< we allocate, we free on error, else caller owns it */
	const _request_headers *pRequestHeaders,
	_replacer_cb replacer)
{
	SG_pathname *tpath = NULL;
	SG_file *pFile = NULL;
	SG_uint32 got = 0;
	char	tbuf[1024];

    //todo: make this thread-safe:
    if(_sg_uridispatch__templatePath==NULL)
        SG_ERR_CHECK(  _sgui_set_templatePath(pCtx)  );

	SG_ERR_CHECK(  SG_PATHNAME__ALLOC__COPY(pCtx, &tpath, _sg_uridispatch__templatePath)  );
	SG_ERR_CHECK(  SG_pathname__append__from_sz(pCtx, tpath, templateFn)  );

	SG_ERR_CHECK(  SG_file__open__pathname(pCtx, tpath, SG_FILE_RDONLY|SG_FILE_OPEN_EXISTING, 0644, &pFile)  );
	SG_PATHNAME_NULLFREE(pCtx, tpath);

	SG_ERR_CHECK(  SG_STRING__ALLOC(pCtx, pContent)  );

	do
	{
		SG_file__read(pCtx, pFile, sizeof(tbuf), (SG_byte *)tbuf, &got);
        if (SG_context__err_equals(pCtx, SG_ERR_EOF))
        {
			SG_context__err_reset(pCtx);
            break;
        }
		SG_ERR_CHECK_CURRENT;

		SG_ERR_CHECK(  SG_string__append__buf_len(pCtx, *pContent, (const SG_byte *)tbuf, got) );
	} while (got > 0);

	SG_ERR_CHECK(  SG_file__close(pCtx, &pFile)  );

	SG_ERR_CHECK(  _templatize(pCtx, *pContent, pRequestHeaders, replacer)  );

	return;

fail:
	SG_STRING_NULLFREE(pCtx, *pContent);
	SG_FILE_NULLCLOSE(pCtx, pFile);
	SG_PATHNAME_NULLFREE(pCtx, tpath);
}
/**
 * Export the contents of the given file entry (which reflects a specific version)
 * into a temp file so that an external tool can use it.
 *
 * You own the returned pathname and the file on disk.
 */
void _sg_mrg__export_to_temp_file(SG_context * pCtx, SG_mrg * pMrg,
								  const char * pszHidBlob,
								  const SG_pathname * pPathTempFile)
{
	SG_file * pFile = NULL;
	SG_bool bExists;

	SG_ERR_CHECK(  SG_fsobj__exists__pathname(pCtx,pPathTempFile,&bExists,NULL,NULL)  );
	if (bExists)
	{
#if TRACE_WC_MERGE
		SG_ERR_IGNORE(  SG_console(pCtx,SG_CS_STDERR,
								   "Skipping export of [blob %s] to [%s]\n",pszHidBlob,SG_pathname__sz(pPathTempFile))  );
#endif
	}
	else
	{
#if TRACE_WC_MERGE
		SG_ERR_IGNORE(  SG_console(pCtx,SG_CS_STDERR,
								   "Exporting          [blob %s] to [%s]\n",pszHidBlob,SG_pathname__sz(pPathTempFile))  );
#endif

		// Ideally, when we create this TEMP file it should be read-only.
		// Afterall, it does represent a historical version of the file and
		// it should only be used as INPUT to whatever merge tool the user
		// has configured.  So it should be read-only.  This might allow
		// a GUI merge tool to show locks/whatever and/or prevent accidental
		// editing of these files.
		//
		// However, this can cause an "Access is Denied" error on Windows
		// when we get ready to delete the contents of the TEMP directory.
		// We'll deal with that there rather than here.

		SG_ERR_CHECK(  SG_file__open__pathname(pCtx,pPathTempFile,SG_FILE_WRONLY|SG_FILE_CREATE_NEW,0400,&pFile)  );
		SG_ERR_CHECK(  SG_repo__fetch_blob_into_file(pCtx, pMrg->pWcTx->pDb->pRepo, pszHidBlob,pFile,NULL)  );
		SG_FILE_NULLCLOSE(pCtx,pFile);
	}

	return;

fail:
	if (pFile)			// only if **WE** created the file, do we try to delete it on error.
	{
		SG_FILE_NULLCLOSE(pCtx,pFile);
		SG_ERR_IGNORE(  SG_fsobj__remove__pathname(pCtx,pPathTempFile)  );
	}
}
Exemplo n.º 8
0
/**
 * Export a blob-of-interest from the REPO into a temporary directory
 * so that we can let the external diff tool compare it with another
 * version somewhere.
 *
 * We create a file with a GID-based name rather than re-creating
 * the working-directory hierarchy in the temp directory.  This lets
 * us flatten the export in one directory without collisions and
 * avoids move/rename and added/deleted sub-directory issues.
 *
 * pPathTempSessionDir should be something like "$TMPDIR/gid_session/".
 * This should be a unique directory name such that everything being
 * exported is isolated from other runs.  (if we are doing a
 * changeset-vs-changeset diff, we may create lots of files on each
 * side -- and our command should not interfere with other diffs
 * in progress in other processes.)
 *
 * szVersion should be a value to let us group everything from cset[0]
 * in a different directory from stuff from cset[1].  this might be
 * simply "0" and "1" or it might be the cset's HIDs.
 *
 * szGidObject is the gid of the object.
 *
 * szHidBlob is the HID of the content.  Normally this is the content
 * of the file that will be compared (corresponding to a user-file
 * under version control).  However, we may also want to use this
 * to splat the XATTRs to a file so that they can be compared (on
 * non-apple systems) -- but this may be too weird.
 *
 * You are responsible for freeing the returned pathname and
 * deleting the file that we create.
 */
void SG_diff_utils__export_to_temp_file(SG_context * pCtx,
										SG_repo * pRepo,
										const SG_pathname * pPathTempSessionDir,	// value of "$TMPDIR/session/"
										const char * szVersion,						// an index (like 0 or 1, _older_ _newer_) or maybe cset HID
										const char * szGidObject,
										const char * szHidBlob,
										SG_pathname ** ppPathTempFile)
{
	SG_pathname * pPathFile = NULL;
	SG_file * pFile = NULL;
	SG_bool bDirExists;

	// mkdir $TMPDIR/session/version
	// create pathname for the temp file: $TMPDIR/session/version/object_gid
	//
	// TODO do we want to append the suffix from the file to this pathname so that
	// TODO tools like SGDM can use it?  what if the file is renamed and given a
	// TODO different suffix between versions?

	SG_ERR_CHECK(  SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx,&pPathFile,pPathTempSessionDir,szVersion)  );
	SG_ERR_CHECK(  SG_fsobj__exists__pathname(pCtx,pPathFile,&bDirExists,NULL,NULL)  );
	if (!bDirExists)
		SG_ERR_CHECK(  SG_fsobj__mkdir_recursive__pathname(pCtx,pPathFile)  );
	SG_ERR_CHECK(  SG_pathname__append__from_sz(pCtx,pPathFile,szGidObject)  );

	// open the file and copy the contents of the blob into it

	SG_ERR_CHECK(  SG_file__open__pathname(pCtx,pPathFile,SG_FILE_WRONLY|SG_FILE_CREATE_NEW,0600,&pFile)  );
	SG_ERR_CHECK(  SG_repo__fetch_blob_into_file(pCtx,pRepo,szHidBlob,pFile,NULL)  );
	SG_ERR_CHECK(  SG_file__close(pCtx,&pFile)  );

	*ppPathTempFile = pPathFile;
	return;

fail:
	if (pFile)				// only if **WE** created the file, do we try to delete it on an error.
	{
		SG_FILE_NULLCLOSE(pCtx,pFile);
		SG_ERR_IGNORE(  SG_fsobj__remove__pathname(pCtx,pPathFile)  );
	}
	SG_PATHNAME_NULLFREE(pCtx, pPathFile);
}
static void sg_read_entire_file(
	SG_context* pCtx,
	const SG_pathname* pPath,
	char** ppbuf,
	SG_uint32* plen
	)
{
	SG_uint32 len32;
	SG_fsobj_type t;
	SG_byte* p = NULL;
	SG_bool bExists;
	SG_fsobj_type FsObjType;
	SG_fsobj_perms FsObjPerms;
	SG_file* pFile = NULL;

	SG_ERR_CHECK(  SG_fsobj__exists__pathname(pCtx, pPath, &bExists, &FsObjType, &FsObjPerms)  );

	if (
		bExists
		&& (SG_FSOBJ_TYPE__REGULAR != FsObjType)
		)
	{
		SG_ERR_IGNORE(  SG_log__report_error(pCtx, "Unable to open file: %s.", SG_pathname__sz(pPath))  );
		
		SG_ERR_THROW_RETURN(SG_ERR_NOTAFILE);
	}

	if (bExists)
	{
		SG_uint64 len64;
		SG_ERR_CHECK(  SG_fsobj__length__pathname(pCtx, pPath, &len64, &t)  );

		// TODO "len" is uint64 because we can have huge files, but
		// TODO our buffer is limited to uint32 (on 32bit systems).
		// TODO verify that len will fit in uint32.
		len32 = (SG_uint32)len64;

		SG_ERR_CHECK(  SG_file__open__pathname(pCtx, pPath, SG_FILE_RDONLY | SG_FILE_OPEN_EXISTING, SG_FSOBJ_PERMS__UNUSED, &pFile)  );
	}
	else
	{
		SG_ERR_THROW_RETURN(SG_ERR_NOTAFILE);
		//len32 = 0;
	}

	if (len32 > 0)
	{
		SG_ERR_CHECK(  SG_alloc(pCtx, 1,len32+1,&p)  );
		SG_ERR_CHECK(  SG_file__read(pCtx, pFile, len32, p, NULL)  );

		p[len32] = 0;

		*ppbuf = (char*) p;
		p = NULL;
		*plen = len32;
	}
	else
	{
		*ppbuf = NULL;
		*plen = 0;
	}

fail:
	SG_FILE_NULLCLOSE(pCtx, pFile);
	SG_NULLFREE(pCtx, p);
}
Exemplo n.º 10
0
void SG_unzip__open(SG_context* pCtx, const SG_pathname* pPath, SG_unzip** ppResult)
{
    SG_unzip us;
    SG_unzip *s;
    SG_uint64 central_pos = 0;
    SG_uint32 uL;

    SG_uint16 number_disk = 0;          /* number of the current dist, used for
                                   spaning ZIP, unsupported, always 0*/
    SG_uint16 number_disk_with_CD = 0;  /* number the the disk with central dir, used
                                   for spaning ZIP, unsupported, always 0*/
    SG_uint16 number_entry_CD = 0;      /* total number of entries in
                                   the central dir
                                   (same than number_entry on nospan) */


    SG_ERR_CHECK(  SG_file__open__pathname(pCtx, pPath, SG_FILE_RDONLY | SG_FILE_OPEN_EXISTING, SG_FSOBJ_PERMS__UNUSED, &us.pFile)  );

    SG_ERR_CHECK(  sg_unzip__locate_central_dir(pCtx, us.pFile, &central_pos)  );

    SG_ERR_CHECK(  SG_file__seek(pCtx, us.pFile, central_pos)  );

    /* the signature, already checked */
    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, us.pFile,&uL)  );

    /* number of this disk */
    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, us.pFile,&number_disk)  );

    /* number of the disk with the start of the central directory */
    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, us.pFile,&number_disk_with_CD)  );

    /* total number of entries in the central dir on this disk */
    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, us.pFile,&us.gi.number_entry)  );

    /* total number of entries in the central dir */
    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, us.pFile,&number_entry_CD)  );

    if ((number_entry_CD!=us.gi.number_entry) ||
        (number_disk_with_CD!=0) ||
        (number_disk!=0))
    {
        SG_ERR_THROW(  SG_ERR_ZIP_BAD_FILE  );
    }

    /* size of the central directory */
    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, us.pFile,&us.size_central_dir)  );

    /* offset of start of central directory with respect to the
          starting disk number */
    SG_ERR_CHECK(  sg_unzip__get_uint32(pCtx, us.pFile,&us.offset_central_dir)  );

    /* zipfile comment length */
    SG_ERR_CHECK(  sg_unzip__get_uint16(pCtx, us.pFile,&us.gi.size_comment)  );

    if (central_pos<us.offset_central_dir+us.size_central_dir)
    {
        SG_ERR_THROW(  SG_ERR_ZIP_BAD_FILE  );
    }

    us.byte_before_the_zipfile = (SG_uint32) (central_pos - (us.offset_central_dir+us.size_central_dir));
    us.central_pos = central_pos;
    us.pfile_in_zip_read = NULL;

    us.current_file_ok = SG_FALSE;

	SG_ERR_CHECK(  SG_malloc(pCtx, sizeof(SG_unzip), &s)  );
    *s=us;

    *ppResult = s;

    return;

fail:
    /* TODO free stuff */
    SG_FILE_NULLCLOSE(pCtx, us.pFile);
}
static void read_entire_stream__file(
    SG_context* pCtx,
    CFReadStreamRef myReadStream,
    SG_pathname* pPath,
    CFHTTPMessageRef* pp,
    SG_bool b_progress
)
{
    CFHTTPMessageRef myResponse = NULL;
    CFIndex numBytesRead = 0;
    SG_file* pFile = NULL;
    SG_int64 content_length = 0;
    SG_int64 so_far = 0;

    SG_ERR_CHECK(  SG_file__open__pathname(pCtx, pPath, SG_FILE_CREATE_NEW | SG_FILE_WRONLY, 0644, &pFile)  );
    do
    {
        UInt8 buf[8192]; // TODO
        numBytesRead = CFReadStreamRead(myReadStream, buf, sizeof(buf));
        if( numBytesRead > 0 )
        {
            SG_ERR_CHECK(  SG_file__write(pCtx, pFile, numBytesRead, buf, NULL)  );
            if (!myResponse)
            {
                myResponse = (CFHTTPMessageRef)CFReadStreamCopyProperty(myReadStream, kCFStreamPropertyHTTPResponseHeader);
                CFStringRef contentLengthString = CFHTTPMessageCopyHeaderFieldValue(myResponse, CFSTR("Content-Length"));
                if (contentLengthString)
                {
                    // TODO 32 bit limit problem here
                    content_length = CFStringGetIntValue(contentLengthString);
                    CFRelease(contentLengthString);
                }
                if (b_progress)
                {
                    SG_ERR_CHECK(  SG_log__set_steps(pCtx, content_length / 1024, "KB")  );
                }
            }
            so_far += (SG_uint32) numBytesRead;
            if (b_progress)
            {
                SG_ERR_CHECK(  SG_log__set_finished(pCtx, so_far / 1024)  );
            }
        }
        else if( numBytesRead < 0 )
        {
            CFStreamError myErr = CFReadStreamGetError(myReadStream);
            // TODO clean this up
            if (myErr.domain == kCFStreamErrorDomainPOSIX)
            {
                if (ETIMEDOUT == myErr.error)
                {
                    usleep(5000);
                    numBytesRead = 0;
                }
                else
                {
                    // Interpret myErr.error as a UNIX errno.
                    SG_ERR_THROW(  SG_ERR_ERRNO(myErr.error)  );
                }
            }
            else if (myErr.domain == kCFStreamErrorDomainMacOSStatus)
            {
                // Interpret myErr.error as a MacOS error code.
                // TODO SG_ERR_THROW(  SG_ERR_MAC((OSStatus) myErr.error)  );
                SG_ERR_THROW(  SG_ERR_UNSPECIFIED  );
            }
        }
    } while( numBytesRead > 0 );

    SG_ERR_CHECK(  SG_file__close(pCtx, &pFile)  );

    if (!myResponse)
    {
        myResponse = (CFHTTPMessageRef)CFReadStreamCopyProperty(myReadStream, kCFStreamPropertyHTTPResponseHeader);
    }

    *pp = myResponse;
    myResponse = NULL;

fail:
    if (pFile)
    {
        SG_ERR_CHECK(  SG_file__close(pCtx, &pFile)  );
        // TODO delete it too
    }
    if (myResponse)
    {
        CFRelease(myResponse);
    }
}
Exemplo n.º 12
0
/**
 * create 1 test file.
 * cat it to a second file using files bound to child's STDIN and STDOUT.
 * cat both files to third file using cl args for input and third bound to child's STDOUT.
 * cat all 3 files using cl args to OUR STDOUT.
 */
void MyFn(test1)(SG_context * pCtx)
{
	SG_exit_status exitStatusChild;
	SG_file * pFileF1 = NULL;
	SG_file * pFileF2 = NULL;
	SG_file * pFileF3 = NULL;
	SG_pathname * pPathTempDir = NULL;
	SG_pathname * pPathF1 = NULL;
	SG_pathname * pPathF2 = NULL;
	SG_pathname * pPathF3 = NULL;
	SG_exec_argvec * pArgVec = NULL;

	// create a GID temp directory in the current directory.

	VERIFY_ERR_CHECK(  unittest__alloc_unique_pathname_in_cwd(pCtx,&pPathTempDir)  );
	VERIFY_ERR_CHECK(  SG_fsobj__mkdir_recursive__pathname(pCtx,pPathTempDir)  );

	// create a couple of pathnames to test files in the temp directory.

	VERIFY_ERR_CHECK(  unittest__alloc_unique_pathname_in_dir(pCtx,SG_pathname__sz(pPathTempDir),&pPathF1)  );
	INFOP("exec",("PathF1 is %s",SG_pathname__sz(pPathF1)));
	VERIFY_ERR_CHECK(  unittest__alloc_unique_pathname_in_dir(pCtx,SG_pathname__sz(pPathTempDir),&pPathF2)  );
	INFOP("exec",("PathF2 is %s",SG_pathname__sz(pPathF2)));
	VERIFY_ERR_CHECK(  unittest__alloc_unique_pathname_in_dir(pCtx,SG_pathname__sz(pPathTempDir),&pPathF3)  );
	INFOP("exec",("PathF3 is %s",SG_pathname__sz(pPathF3)));

	//////////////////////////////////////////////////////////////////
	// create F1 and write some data to it.

	VERIFY_ERR_CHECK(  SG_file__open__pathname(pCtx,pPathF1,SG_FILE_WRONLY|SG_FILE_CREATE_NEW,0644,&pFileF1)  );
	VERIFY_ERR_CHECK(  SG_file__write(pCtx,pFileF1,
									  SG_pathname__length_in_bytes(pPathF1),
									  (SG_byte *)SG_pathname__sz(pPathF1),
									  NULL)  );
	VERIFY_ERR_CHECK(  SG_file__write(pCtx,pFileF1,
									  1,
									  (SG_byte *)"\n",
									  NULL)  );
	VERIFY_ERR_CHECK(  SG_file__write(pCtx,pFileF1,
									  SG_pathname__length_in_bytes(pPathF1),
									  (SG_byte *)SG_pathname__sz(pPathF1),
									  NULL)  );
	VERIFY_ERR_CHECK(  SG_file__write(pCtx,pFileF1,
									  1,
									  (SG_byte *)"\n",
									  NULL)  );
	SG_FILE_NULLCLOSE(pCtx, pFileF1);

	//////////////////////////////////////////////////////////////////
	// re-open F1 for reading.
	// create F2 as a place for STDOUT of command.

	VERIFY_ERR_CHECK(  SG_file__open__pathname(pCtx,pPathF1,SG_FILE_RDONLY|SG_FILE_OPEN_EXISTING,0644,&pFileF1)  );
	VERIFY_ERR_CHECK(  SG_file__open__pathname(pCtx,pPathF2,SG_FILE_WRONLY|SG_FILE_CREATE_NEW,   0644,&pFileF2)  );

	// exec: /bin/cat <f1 >f2

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,NULL,pFileF1,pFileF2,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));

	INFOP("/bin/cat <f1 >f2",("Child exit status is [%d]",exitStatusChild));
	SG_FILE_NULLCLOSE(pCtx, pFileF1);
	SG_FILE_NULLCLOSE(pCtx, pFileF2);

	//////////////////////////////////////////////////////////////////
	// let F1 and F2 be given on the command line.
	// create F3 as a place for STDOUT of command.

	VERIFY_ERR_CHECK(  SG_file__open__pathname(pCtx,pPathF3,SG_FILE_WRONLY|SG_FILE_CREATE_NEW,   0644,&pFileF3)  );

	// exec: /bin/cat -n f1 f2 >f3

	VERIFY_ERR_CHECK(  SG_exec_argvec__alloc(pCtx,&pArgVec)  );
	VERIFY_ERR_CHECK(  SG_exec_argvec__append__sz(pCtx,pArgVec,"-n")  );
	VERIFY_ERR_CHECK(  SG_exec_argvec__append__sz(pCtx,pArgVec,SG_pathname__sz(pPathF1))  );
	VERIFY_ERR_CHECK(  SG_exec_argvec__append__sz(pCtx,pArgVec,SG_pathname__sz(pPathF2))  );

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,pArgVec,NULL,pFileF3,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));

	INFOP("/bin/cat -n f1 f2 >f3",("Child exit status is [%d]",exitStatusChild));
	SG_FILE_NULLCLOSE(pCtx, pFileF3);
	SG_EXEC_ARGVEC_NULLFREE(pCtx, pArgVec);

	//////////////////////////////////////////////////////////////////
	// exec: /bin/cat f1 f2 f3 (to our stdout)

	VERIFY_ERR_CHECK(  SG_exec_argvec__alloc(pCtx,&pArgVec)  );
	VERIFY_ERR_CHECK(  SG_exec_argvec__append__sz(pCtx,pArgVec,SG_pathname__sz(pPathF1))  );
	VERIFY_ERR_CHECK(  SG_exec_argvec__append__sz(pCtx,pArgVec,SG_pathname__sz(pPathF2))  );
	VERIFY_ERR_CHECK(  SG_exec_argvec__append__sz(pCtx,pArgVec,SG_pathname__sz(pPathF3))  );

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,pArgVec,NULL,NULL,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));

	INFOP("/bin/cat -n f1 f2 f3",("Child exit status is [%d]",exitStatusChild));
	SG_EXEC_ARGVEC_NULLFREE(pCtx, pArgVec);

	//////////////////////////////////////////////////////////////////
	// exec: /bin/cat f3 f2 f1 (to our stdout)

	VERIFY_ERR_CHECK(  SG_exec_argvec__alloc(pCtx,&pArgVec)  );
	VERIFY_ERR_CHECK(  SG_exec_argvec__append__sz(pCtx,pArgVec,SG_pathname__sz(pPathF3))  );
	VERIFY_ERR_CHECK(  SG_exec_argvec__append__sz(pCtx,pArgVec,SG_pathname__sz(pPathF2))  );
	VERIFY_ERR_CHECK(  SG_exec_argvec__append__sz(pCtx,pArgVec,SG_pathname__sz(pPathF1))  );

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,pArgVec,NULL,NULL,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));

	INFOP("/bin/cat -n f3 f2 f1",("Child exit status is [%d]",exitStatusChild));
	SG_EXEC_ARGVEC_NULLFREE(pCtx, pArgVec);

	// fall through to common cleanup.

fail:
	SG_EXEC_ARGVEC_NULLFREE(pCtx, pArgVec);
	SG_PATHNAME_NULLFREE(pCtx, pPathTempDir);
	SG_PATHNAME_NULLFREE(pCtx, pPathF1);
	SG_PATHNAME_NULLFREE(pCtx, pPathF2);
	SG_PATHNAME_NULLFREE(pCtx, pPathF3);
	SG_FILE_NULLCLOSE(pCtx, pFileF1);
	SG_FILE_NULLCLOSE(pCtx, pFileF2);
	SG_FILE_NULLCLOSE(pCtx, pFileF3);
}
Exemplo n.º 13
0
static void _sg_workingdir__get_entry2(SG_context * pCtx,
									   SG_repo * pRepo,
									   const SG_pathname * pPathSub,
									   const char * pszGid,
									   SG_treenode_entry_type type,
									   const char * pszidHidContent,
									   const char * pszidHidXattrs,
									   SG_int64 iAttributeBits,
									   SG_vhash * pvhTimestamps)
{
	SG_file* pFile = NULL;
	SG_string* pstrLink = NULL;
	SG_byte* pBytes = NULL;
	SG_vhash * pvhGid = NULL;

    if (SG_TREENODEENTRY_TYPE_DIRECTORY == type)
    {
        /* create the directory and then recurse into it */
        SG_ERR_CHECK(  SG_fsobj__mkdir__pathname(pCtx, pPathSub)  );
        SG_ERR_CHECK(  _sg_workingdir__get_dir(pCtx, pRepo, pPathSub, pszidHidContent, pvhTimestamps)  );
    }
    else if (SG_TREENODEENTRY_TYPE_REGULAR_FILE == type)
    {
        SG_ERR_CHECK(  SG_file__open__pathname(pCtx, pPathSub, SG_FILE_RDWR | SG_FILE_CREATE_NEW, SG_FSOBJ_PERMS__MASK, &pFile)  );
        SG_ERR_CHECK(  SG_repo__fetch_blob_into_file(pCtx, pRepo, pszidHidContent, pFile, NULL)  );
        SG_ERR_CHECK(  SG_file__close(pCtx, &pFile)  );
    }
    else if (SG_TREENODEENTRY_TYPE_SYMLINK == type)
    {
        SG_uint64 iLenBytes = 0;

        SG_ERR_CHECK(  SG_repo__fetch_blob_into_memory(pCtx, pRepo, pszidHidContent, &pBytes, &iLenBytes)  );
        SG_ERR_CHECK(  SG_STRING__ALLOC__BUF_LEN(pCtx, &pstrLink, pBytes, (SG_uint32) iLenBytes)  );
        SG_ERR_CHECK(  SG_fsobj__symlink(pCtx, pstrLink, pPathSub)  );
        SG_NULLFREE(pCtx, pBytes);
        SG_STRING_NULLFREE(pCtx, pstrLink);
    }
    else
    {
        SG_ERR_THROW(SG_ERR_NOTIMPLEMENTED);
    }

    if (pszidHidXattrs)
    {
#ifdef SG_BUILD_FLAG_FEATURE_XATTR
        SG_ERR_CHECK(  _sg_workingdir__set_xattrs(pCtx, pRepo, pPathSub, pszidHidXattrs)  );
#else
		// TODO do we need to stuff something into the pendingtree to remind us
		// TODO that the entry originally had an XAttr and we just didn't restore
		// TODO it when we populated the WD on this Windows system?
#endif
    }

    SG_ERR_CHECK(  SG_attributes__bits__apply(pCtx, pPathSub, iAttributeBits)  );

	if (pvhTimestamps && (SG_TREENODEENTRY_TYPE_REGULAR_FILE == type))
	{
		SG_fsobj_stat stat;
		SG_int64 iTimeNow;

		SG_ERR_CHECK(  SG_fsobj__stat__pathname(pCtx, pPathSub, &stat)  );
		SG_ERR_CHECK(  SG_time__get_milliseconds_since_1970_utc(pCtx, &iTimeNow)  );

		SG_ERR_CHECK(  SG_VHASH__ALLOC(pCtx, &pvhGid)  );
		SG_ERR_CHECK(  SG_vhash__add__int64(pCtx, pvhGid, "mtime_ms", stat.mtime_ms)  );
		SG_ERR_CHECK(  SG_vhash__add__int64(pCtx, pvhGid, "clock_ms", iTimeNow)  );

		SG_ERR_CHECK(  SG_vhash__add__vhash(pCtx, pvhTimestamps, pszGid, &pvhGid)  );	// this steals our vhash
	}

fail:
	SG_VHASH_NULLFREE(pCtx, pvhGid);
}
Exemplo n.º 14
0
int u0040_unc__stat_dir(SG_context * pCtx, const char * szDir)
{
	SG_pathname * pPathname = NULL;
	SG_pathname * pPathnameFile = NULL;
	SG_file * pf = NULL;
	SG_fsobj_stat fsobjStat;
	SG_bool bFileExists;
	SG_int_to_string_buffer bufSize;
	char bufDate[100];

	SG_context__err_reset(pCtx);

	//////////////////////////////////////////////////////////////////
	// stat the given directory.
	//////////////////////////////////////////////////////////////////

	INFOP("u0040_unc",("Inspecting [%s]",szDir));

	VERIFY_ERR_CHECK_RETURN(  SG_PATHNAME__ALLOC__SZ(pCtx,&pPathname,szDir)  );

	VERIFY_ERR_CHECK(  SG_fsobj__stat__pathname(pCtx,pPathname,&fsobjStat)  );
	VERIFY_COND("u0040_unc",(fsobjStat.type == SG_FSOBJ_TYPE__DIRECTORY));

	// TODO should we verify length == 0 ?
	// TODO should we verify modtime ?

	SG_uint64_to_sz(fsobjStat.size, bufSize);
	VERIFY_ERR_CHECK_DISCARD(  SG_time__format_utc__i64(pCtx,fsobjStat.mtime_ms,bufDate,SG_NrElements(bufDate))  );

	INFOP("u0040_unc",("Result: [perms %04o][type %d][size %s][mtime %s]",
					   fsobjStat.perms,fsobjStat.type,
					   bufSize,bufDate));

	//////////////////////////////////////////////////////////////////
	// create a unique file in the directory and stat it.
	//////////////////////////////////////////////////////////////////

	VERIFY_ERR_CHECK(  unittest__alloc_unique_pathname(pCtx,szDir,&pPathnameFile)  );

	INFOP("u0040_unc",("    Creating file [%s]",SG_pathname__sz(pPathnameFile)));

	VERIFY_ERR_CHECK(  SG_file__open__pathname(pCtx,pPathnameFile,SG_FILE_CREATE_NEW | SG_FILE_RDWR,0777,&pf)  );

	VERIFY_ERR_CHECK(  SG_fsobj__stat__pathname(pCtx,pPathnameFile,&fsobjStat)  );
	VERIFY_COND("u0040_unc",(fsobjStat.type == SG_FSOBJ_TYPE__REGULAR));
	VERIFY_COND("u0040_unc",(fsobjStat.size == 0));
	VERIFY_COND("u0040_unc",(SG_fsobj__equivalent_perms(fsobjStat.perms,0777)));
	// TODO should we verify modtime ?

	SG_uint64_to_sz(fsobjStat.size, bufSize);
	VERIFY_ERR_CHECK_DISCARD(  SG_time__format_utc__i64(pCtx,fsobjStat.mtime_ms,bufDate,SG_NrElements(bufDate))  );

	INFOP("u0040_unc",("    Result: [perms %04o][type %d][size %s][mtime %s]",
					   fsobjStat.perms,fsobjStat.type,
					   bufSize,bufDate));

	VERIFY_ERR_CHECK_DISCARD(  SG_file__close(pCtx, &pf)  );

	// delete the file and stat it again

	VERIFY_ERR_CHECK_DISCARD(  SG_fsobj__remove__pathname(pCtx,pPathnameFile)  );
	VERIFY_ERR_CHECK_DISCARD(  SG_fsobj__exists__pathname(pCtx,pPathnameFile,&bFileExists,NULL,NULL)  );
	VERIFY_COND("u0040_unc",(!bFileExists));

	//////////////////////////////////////////////////////////////////
	// clean up
	//////////////////////////////////////////////////////////////////

	SG_PATHNAME_NULLFREE(pCtx, pPathnameFile);
	SG_PATHNAME_NULLFREE(pCtx, pPathname);
	return 1;

fail:
	SG_FILE_NULLCLOSE(pCtx, pf);
	SG_PATHNAME_NULLFREE(pCtx, pPathnameFile);
	SG_PATHNAME_NULLFREE(pCtx, pPathname);
	return 0;
}
Exemplo n.º 15
0
void SG_vfile__begin(
	SG_context* pCtx,
	const SG_pathname* pPath, /**< The path of the file containing the JSON text */
	SG_file_flags mode,
	SG_vhash** ppvh, /**< If there are no errors, the resulting vhash table will be returned here. */
	SG_vfile** ppvf
	)
{
	SG_vfile* pvf = NULL;
	SG_vhash* pvh = NULL;
	SG_uint32 len32;
	SG_fsobj_type t;
	SG_byte* p = NULL;
	SG_bool bExists;
	SG_fsobj_type FsObjType;
	SG_fsobj_perms FsObjPerms;

	SG_ERR_CHECK(  SG_fsobj__exists__pathname(pCtx, pPath, &bExists, &FsObjType, &FsObjPerms)  );

	if (
		bExists
		&& (SG_FSOBJ_TYPE__REGULAR != FsObjType)
		)
	{
		SG_ERR_THROW_RETURN(SG_ERR_NOTAFILE);
	}

	if (bExists)
	{
		SG_uint64 len64;
		SG_ERR_CHECK(  SG_fsobj__length__pathname(pCtx, pPath, &len64, &t)  );

		// TODO "len" is uint64 because we can have huge files, but
		// TODO our buffer is limited to uint32 (on 32bit systems).
		// TODO verify that len will fit in uint32.
		len32 = (SG_uint32)len64;
	}
	else
	{
		len32 = 0;
	}

	SG_ERR_CHECK_RETURN(  SG_alloc1(pCtx, pvf)  );

	SG_ERR_CHECK(  SG_file__open__pathname(pCtx, pPath, mode | SG_FILE_LOCK, SG_FSOBJ_PERMS__UNUSED, &pvf->pFile)  );

	pvf->mode = mode;

#if TRACE_VFILE
	SG_ERR_IGNORE(  SG_console(pCtx, SG_CS_STDERR, "VFileBegin: Reading %d bytes from %s\n", len32, SG_pathname__sz(pPath))  );
#endif

	if (len32 > 0)
	{
		SG_ERR_CHECK(  SG_alloc(pCtx, 1,len32+1,&p)  );
		SG_ERR_CHECK(  SG_file__read(pCtx, pvf->pFile, len32, p, NULL)  );

		p[len32] = 0;

		SG_ERR_CHECK(  SG_VHASH__ALLOC__FROM_JSON(pCtx, &pvh, (const char*) p)  );

		SG_NULLFREE(pCtx, p);
		p = NULL;
	}
	else
	{
		pvh = NULL;
	}

	*ppvf = pvf;
	*ppvh = pvh;

	return;

fail:
	SG_FILE_NULLCLOSE(pCtx, pvf->pFile);
	SG_NULLFREE(pCtx, p);
	SG_NULLFREE(pCtx, pvf);
}
Exemplo n.º 16
0
void MyFn(create_blob_from_file)(SG_context * pCtx,
								 SG_repo * pRepo,
								 const SG_pathname * pPathnameTempDir,
								 SG_uint64 lenFile,
								 const char * szSrc)
{
	// create a file of length "lenFile" in the temp directory.
	// use it to create a blob.
	// try to create it a second time and verify that we get an duplicate-hid error.

	char* pszidGidRandom1 = NULL;
	char* pszidGidRandom2 = NULL;
	SG_pathname * pPathnameTempFile1 = NULL;
	SG_pathname * pPathnameTempFile2 = NULL;
	SG_file * pFileTempFile1 = NULL;
	SG_file * pFileTempFile2 = NULL;
	SG_uint32 lenSrc;
	SG_uint64 lenWritten;
	char* pszidHidBlob1 = NULL;
	char* pszidHidBlob1Dup = NULL;
	char* pszidHidBlob2 = NULL;
	char* pszidHidVerify1 = NULL;
	char* pszidHidVerify2 = NULL;
	SG_bool bEqual;
	SG_repo_tx_handle* pTx = NULL;
	SG_uint64 iBlobFullLength = 0;

	//////////////////////////////////////////////////////////////////
	// create temp-file-1 of length "lenFile" in the temp directory.

	VERIFY_ERR_CHECK_DISCARD(  SG_gid__alloc(pCtx, &pszidGidRandom1)  );
	VERIFY_ERR_CHECK_DISCARD(  SG_gid__alloc(pCtx, &pszidGidRandom2)  );

	VERIFY_ERR_CHECK_DISCARD(  SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPathnameTempFile1,pPathnameTempDir,(pszidGidRandom1))  );

	VERIFY_ERR_CHECK_DISCARD(  SG_file__open__pathname(pCtx, pPathnameTempFile1,SG_FILE_RDWR|SG_FILE_CREATE_NEW,0644,&pFileTempFile1)  );

	// write random gid at the beginning of the file
	// so that we won't get collisions if we are called
	// multiple times.

	VERIFY_ERR_CHECK_DISCARD(  SG_file__write(pCtx, pFileTempFile1,(SG_uint32)strlen(pszidGidRandom1),(SG_byte *)pszidGidRandom1,NULL)  );
	VERIFY_ERR_CHECK_DISCARD(  SG_file__write(pCtx, pFileTempFile1,1,(SG_byte *)"\n",NULL)  );

	// generate lots of data in the file so that we'll cause the
	// blob routines to exercise the chunking stuff.

	lenSrc = (SG_uint32)strlen(szSrc);
	lenWritten = 0;
	while (lenWritten < lenFile)
	{
		VERIFY_ERR_CHECK_DISCARD(  SG_file__write(pCtx, pFileTempFile1,lenSrc,(SG_byte *)szSrc,NULL)  );

		lenWritten += lenSrc;
	}
	// the test file does NOT have a final LF.  i'm not sure it matters one way or the
	// other, but i'm just saying that we're not putting on a final LF.

	SG_ERR_IGNORE(  SG_file__seek(pCtx, pFileTempFile1,0)  );

	//////////////////////////////////////////////////////////////////
	// use currently open temp file to create a blob.
	// we get the HID back.  (we need to free it later.)

	VERIFY_ERR_CHECK_DISCARD(  SG_repo__begin_tx(pCtx, pRepo, &pTx)  );
	VERIFY_ERR_CHECK_DISCARD(  SG_repo__store_blob_from_file(pCtx, pRepo,pTx,NULL,SG_FALSE,pFileTempFile1,&pszidHidBlob1,&iBlobFullLength)  );
	VERIFY_ERR_CHECK_DISCARD(  SG_repo__commit_tx(pCtx, pRepo, &pTx)  );

	INFOP("create_blob_from_file",("Created blob [%s]",(pszidHidBlob1)));

	//////////////////////////////////////////////////////////////////
	// try to create blob again and verify we get an duplicate-hid error.

	// Ian TODO: Put this back when SG_ERR_BLOBFILEALREADYEXISTS has been replaced.
// 	VERIFY_ERR_CHECK_DISCARD(  SG_repo__begin_tx(pCtx, pRepo, &pTx)  );
// 	err = SG_repo__store_blob_from_file(pRepo,pTx,SG_FALSE,pFileTempFile1,&pszidHidBlob1Dup);
// 	VERIFYP_CTX_ERR_IS("create_blob_from_file(duplicate)", pCtx, SG_ERR_BLOBFILEALREADYEXISTS, ("Duplicate create failed [%s][%s]",pszidHidBlob1,pszidHidBlob1Dup));
// 	VERIFY_ERR_CHECK_DISCARD(  SG_repo__commit_tx(pCtx, pRepo, SG_DAGNUM__NONE, NULL, &pTx)  );

	//////////////////////////////////////////////////////////////////
	// create empty temp-file-2 and try to read the blob from the repo.

	VERIFY_ERR_CHECK_DISCARD(  SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPathnameTempFile2,pPathnameTempDir,(pszidGidRandom2))  );

	VERIFY_ERR_CHECK_DISCARD(  SG_file__open__pathname(pCtx, pPathnameTempFile2,SG_FILE_RDWR|SG_FILE_CREATE_NEW,0644,&pFileTempFile2)  );

	VERIFY_ERR_CHECK_DISCARD(  SG_repo__fetch_blob_into_file(pCtx, pRepo,pszidHidBlob1,pFileTempFile2,NULL)  );

	//////////////////////////////////////////////////////////////////
	// verify that the contents of temp-file-2 is identical to the
	// contents of temp-file-1.  (we already know that the HIDs match
	// and was verified during the fetch, but there are times when the
	// HID is just being used as a key -- it doesn't mean that what we
	// actually restored is correct.

	VERIFY_ERR_CHECK_DISCARD(  SG_repo__alloc_compute_hash__from_file(pCtx, pRepo, pFileTempFile1, &pszidHidVerify1)  );

	VERIFY_ERR_CHECK_DISCARD(  SG_repo__alloc_compute_hash__from_file(pCtx, pRepo, pFileTempFile2, &pszidHidVerify2)  );

	bEqual = (0 == (strcmp(pszidHidVerify1,pszidHidVerify2)));
	VERIFY_COND("create_blob_from_file(verify v1==v2)",bEqual);

	bEqual = (0 == (strcmp(pszidHidVerify1,pszidHidBlob1)));
	VERIFY_COND("create_blob_from_file(verify v1==id)",bEqual);

	//////////////////////////////////////////////////////////////////
	// TODO delete temp source file

	SG_ERR_IGNORE(  SG_file__close(pCtx, &pFileTempFile1)  );
	SG_ERR_IGNORE(  SG_file__close(pCtx, &pFileTempFile2)  );

	//////////////////////////////////////////////////////////////////
	// cleanup

	SG_NULLFREE(pCtx, pszidGidRandom1);
	SG_NULLFREE(pCtx, pszidGidRandom2);
	SG_NULLFREE(pCtx, pszidHidBlob1);
	SG_NULLFREE(pCtx, pszidHidBlob1Dup);
	SG_NULLFREE(pCtx, pszidHidBlob2);
	SG_NULLFREE(pCtx, pszidHidVerify1);
	SG_NULLFREE(pCtx, pszidHidVerify2);
	SG_PATHNAME_NULLFREE(pCtx, pPathnameTempFile1);
	SG_PATHNAME_NULLFREE(pCtx, pPathnameTempFile2);
}
Exemplo n.º 17
0
/**
 * create 1 test file.
 * cat it to a second file using files bound to child's STDIN and STDOUT.
 * repeat using still open files.
 * verify that we get an append effect.
 *
 * do this again using input file on the command line into a third file.
 */
void MyFn(test2)(SG_context * pCtx)
{
	SG_exit_status exitStatusChild;
	SG_file * pFileF1 = NULL;
	SG_file * pFileF2 = NULL;
	SG_file * pFileF3 = NULL;
	SG_pathname * pPathTempDir = NULL;
	SG_pathname * pPathF1 = NULL;
	SG_pathname * pPathF2 = NULL;
	SG_pathname * pPathF3 = NULL;
	SG_exec_argvec * pArgVec = NULL;
	SG_uint64 lenFileF1, lenFileF2, lenFileF3;
	SG_uint64 posFileF1, posFileF2, posFileF3;

	// create a GID temp directory in the current directory.

	VERIFY_ERR_CHECK(  unittest__alloc_unique_pathname_in_cwd(pCtx,&pPathTempDir)  );
	VERIFY_ERR_CHECK(  SG_fsobj__mkdir_recursive__pathname(pCtx,pPathTempDir)  );

	// create a couple of pathnames to test files in the temp directory.

	VERIFY_ERR_CHECK(  unittest__alloc_unique_pathname_in_dir(pCtx,SG_pathname__sz(pPathTempDir),&pPathF1)  );
	INFOP("exec",("PathF1 is %s",SG_pathname__sz(pPathF1)));
	VERIFY_ERR_CHECK(  unittest__alloc_unique_pathname_in_dir(pCtx,SG_pathname__sz(pPathTempDir),&pPathF2)  );
	INFOP("exec",("PathF2 is %s",SG_pathname__sz(pPathF2)));
	VERIFY_ERR_CHECK(  unittest__alloc_unique_pathname_in_dir(pCtx,SG_pathname__sz(pPathTempDir),&pPathF3)  );
	INFOP("exec",("PathF3 is %s",SG_pathname__sz(pPathF3)));

	//////////////////////////////////////////////////////////////////
	// create F1 and write some data to it.

	VERIFY_ERR_CHECK(  SG_file__open__pathname(pCtx,pPathF1,SG_FILE_WRONLY|SG_FILE_CREATE_NEW,0644,&pFileF1)  );
	VERIFY_ERR_CHECK(  SG_file__write(pCtx,pFileF1,
									  SG_pathname__length_in_bytes(pPathF1),
									  (SG_byte *)SG_pathname__sz(pPathF1),
									  NULL)  );
	VERIFY_ERR_CHECK(  SG_file__write(pCtx,pFileF1,
									  1,
									  (SG_byte *)"\n",
									  NULL)  );
	SG_FILE_NULLCLOSE(pCtx, pFileF1);

	// get length of F1 as created on disk.

	VERIFY_ERR_CHECK(  SG_fsobj__length__pathname(pCtx,pPathF1,&lenFileF1,NULL)  );
	INFOP("lenCheck",("Length F1[%d]",(SG_uint32)lenFileF1));
	VERIFY_COND("lenCheck",(lenFileF1 > 0));

	//////////////////////////////////////////////////////////////////
	// re-open F1 for reading.
	// create F2 as a place for STDOUT of command.

	VERIFY_ERR_CHECK(  SG_file__open__pathname(pCtx,pPathF1,SG_FILE_RDONLY|SG_FILE_OPEN_EXISTING,0644,&pFileF1)  );
	VERIFY_ERR_CHECK(  SG_file__open__pathname(pCtx,pPathF2,SG_FILE_WRONLY|SG_FILE_CREATE_NEW,   0644,&pFileF2)  );

	// exec: "/bin/cat <f1 >f2" three times holding the file handles open between runs.

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,NULL,pFileF1,pFileF2,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));
	INFOP("/bin/cat <f1 >f2",("Child exit status is [%d]",exitStatusChild));
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF1,&posFileF1)  );
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF2,&posFileF2)  );
	INFOP("tell",("Position F1[%d] Position F2[%d]",(SG_uint32)posFileF1,(SG_uint32)posFileF2));
	VERIFY_COND("tell",(posFileF1 == lenFileF1));		// child has dup'd version of handles and so we share seek positions.
	VERIFY_COND("tell",(posFileF2 == posFileF1));		// so, the child should have caused our position to change.

	VERIFY_ERR_CHECK(  SG_file__seek(pCtx,pFileF1,0)  );

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,NULL,pFileF1,pFileF2,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));
	INFOP("/bin/cat <f1 >f2",("Child exit status is [%d]",exitStatusChild));
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF1,&posFileF1)  );
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF2,&posFileF2)  );
	INFOP("tell",("Position F1[%d] Position F2[%d]",(SG_uint32)posFileF1,(SG_uint32)posFileF2));
	VERIFY_COND("tell",(posFileF1 == lenFileF1));		// child has dup'd version of handles and so we share seek positions.
	VERIFY_COND("tell",(posFileF2 == 2*posFileF1));		// so, the child should have caused our position to change.

	VERIFY_ERR_CHECK(  SG_file__seek(pCtx,pFileF1,0)  );

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,NULL,pFileF1,pFileF2,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));
	INFOP("/bin/cat <f1 >f2",("Child exit status is [%d]",exitStatusChild));
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF1,&posFileF1)  );
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF2,&posFileF2)  );
	INFOP("tell",("Position F1[%d] Position F2[%d]",(SG_uint32)posFileF1,(SG_uint32)posFileF2));
	VERIFY_COND("tell",(posFileF1 == lenFileF1));		// child has dup'd version of handles and so we share seek positions.
	VERIFY_COND("tell",(posFileF2 == 3*posFileF1));		// so, the child should have caused our position to change.

	SG_FILE_NULLCLOSE(pCtx, pFileF1);
	SG_FILE_NULLCLOSE(pCtx, pFileF2);

	// get length of F2 and see how it compares with F1.

	VERIFY_ERR_CHECK(  SG_fsobj__length__pathname(pCtx,pPathF2,&lenFileF2,NULL)  );
	INFOP("lenCheck",("Length F1[%d] Length F2[%d]",(SG_uint32)lenFileF1,(SG_uint32)lenFileF2));
	VERIFY_COND("lenCheck",(lenFileF2 == 3*lenFileF1));

	//////////////////////////////////////////////////////////////////
	// let F1 be given on the command line.
	// create F3 as a place for STDOUT of command.

	VERIFY_ERR_CHECK(  SG_file__open__pathname(pCtx,pPathF3,SG_FILE_WRONLY|SG_FILE_CREATE_NEW,   0644,&pFileF3)  );

	// exec: "/bin/cat f1 >f3" three times holding F3 open between runs.

	VERIFY_ERR_CHECK(  SG_exec_argvec__alloc(pCtx,&pArgVec)  );
	VERIFY_ERR_CHECK(  SG_exec_argvec__append__sz(pCtx,pArgVec,SG_pathname__sz(pPathF1))  );

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,pArgVec,NULL,pFileF3,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));
	INFOP("/bin/cat f1 >f3",("Child exit status is [%d]",exitStatusChild));
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF3,&posFileF3)  );
	INFOP("tell",("Position F3[%d]",(SG_uint32)posFileF3));
	VERIFY_COND("tell",(posFileF3 == lenFileF1));

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,pArgVec,NULL,pFileF3,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));
	INFOP("/bin/cat f1 >f3",("Child exit status is [%d]",exitStatusChild));
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF3,&posFileF3)  );
	INFOP("tell",("Position F3[%d]",(SG_uint32)posFileF3));
	VERIFY_COND("tell",(posFileF3 == 2*lenFileF1));

	VERIFY_ERR_CHECK(  SG_exec__exec_sync__files(pCtx,MY_CAT_COMMAND,pArgVec,NULL,pFileF3,NULL,&exitStatusChild)  );
	VERIFY_COND("child status",(exitStatusChild == 0));
	INFOP("/bin/cat f1 >f3",("Child exit status is [%d]",exitStatusChild));
	VERIFY_ERR_CHECK(  SG_file__tell(pCtx,pFileF3,&posFileF3)  );
	INFOP("tell",("Position F3[%d]",(SG_uint32)posFileF3));
	VERIFY_COND("tell",(posFileF3 == 3*lenFileF1));

	SG_FILE_NULLCLOSE(pCtx, pFileF3);

	// get length of F3 and see how it compares with F1.

	VERIFY_ERR_CHECK(  SG_fsobj__length__pathname(pCtx,pPathF3,&lenFileF3,NULL)  );
	INFOP("lenCheck",("Length F1[%d] Length F3[%d]",(SG_uint32)lenFileF1,(SG_uint32)lenFileF3));
	VERIFY_COND("tell",(lenFileF3 == 3*lenFileF1));

	//////////////////////////////////////////////////////////////////

	// fall through to common cleanup.

fail:
	SG_EXEC_ARGVEC_NULLFREE(pCtx, pArgVec);
	SG_PATHNAME_NULLFREE(pCtx, pPathTempDir);
	SG_PATHNAME_NULLFREE(pCtx, pPathF1);
	SG_PATHNAME_NULLFREE(pCtx, pPathF2);
	SG_PATHNAME_NULLFREE(pCtx, pPathF3);
	SG_FILE_NULLCLOSE(pCtx, pFileF1);
	SG_FILE_NULLCLOSE(pCtx, pFileF2);
	SG_FILE_NULLCLOSE(pCtx, pFileF3);
}