void SG_mrg_cset_entry_conflict__free(SG_context * pCtx, SG_mrg_cset_entry_conflict * pMrgCSetEntryConflict) { if (!pMrgCSetEntryConflict) return; SG_VECTOR_I64_NULLFREE(pCtx, pMrgCSetEntryConflict->pVec_MrgCSetEntryNeq_Changes); SG_VECTOR_NULLFREE(pCtx, pMrgCSetEntryConflict->pVec_MrgCSetEntry_Changes); // we do not own the pointers within SG_VECTOR_NULLFREE(pCtx, pMrgCSetEntryConflict->pVec_MrgCSet_Deletes); // we do not own the pointers within // for the collapsable rbUnique's we own the vectors in the rbtree-values, but not the pointers within the vector SG_RBTREE_NULLFREE_WITH_ASSOC(pCtx, pMrgCSetEntryConflict->prbUnique_AttrBits, (SG_free_callback *)SG_vector__free); SG_RBTREE_NULLFREE_WITH_ASSOC(pCtx, pMrgCSetEntryConflict->prbUnique_Entryname, (SG_free_callback *)SG_vector__free); SG_RBTREE_NULLFREE_WITH_ASSOC(pCtx, pMrgCSetEntryConflict->prbUnique_GidParent, (SG_free_callback *)SG_vector__free); SG_RBTREE_NULLFREE_WITH_ASSOC(pCtx, pMrgCSetEntryConflict->prbUnique_Symlink_HidBlob, (SG_free_callback *)SG_vector__free); SG_RBTREE_NULLFREE_WITH_ASSOC(pCtx, pMrgCSetEntryConflict->prbUnique_Submodule_HidBlob, (SG_free_callback *)SG_vector__free); SG_RBTREE_NULLFREE_WITH_ASSOC(pCtx, pMrgCSetEntryConflict->prbUnique_File_HidBlob, (SG_free_callback *)SG_vector__free); SG_VECTOR_NULLFREE(pCtx, pMrgCSetEntryConflict->pVec_MrgCSetEntry_OtherDirsInCycle); // we do not own the pointers within SG_STRING_NULLFREE(pCtx, pMrgCSetEntryConflict->pStringPathCycleHint); SG_FILETOOL_NULLFREE(pCtx, pMrgCSetEntryConflict->pMergeTool); SG_PATHNAME_NULLFREE(pCtx, pMrgCSetEntryConflict->pPathTempDirForFile); SG_PATHNAME_NULLFREE(pCtx, pMrgCSetEntryConflict->pPathTempFile_Ancestor); SG_PATHNAME_NULLFREE(pCtx, pMrgCSetEntryConflict->pPathTempFile_Result); SG_PATHNAME_NULLFREE(pCtx, pMrgCSetEntryConflict->pPathTempFile_Baseline); SG_PATHNAME_NULLFREE(pCtx, pMrgCSetEntryConflict->pPathTempFile_Other); SG_NULLFREE(pCtx, pMrgCSetEntryConflict->pszHidDisposable); SG_NULLFREE(pCtx, pMrgCSetEntryConflict->pszHidGenerated); SG_NULLFREE(pCtx, pMrgCSetEntryConflict); }
void SG_workingdir__generate_and_create_temp_dir_for_purpose(SG_context * pCtx, const SG_pathname * pPathWorkingDirectoryTop, const char * pszPurpose, SG_pathname ** ppPathTempDir) { SG_pathname * pPathTempRoot = NULL; SG_pathname * pPath = NULL; SG_string * pString = NULL; SG_int64 iTimeUTC; SG_time tmLocal; SG_uint32 kAttempt = 0; SG_NONEMPTYCHECK_RETURN(pszPurpose); SG_NULLARGCHECK_RETURN(ppPathTempDir); // get path to "<wd-top>/.sgtemp". SG_ERR_CHECK( SG_workingdir__get_temp_path(pCtx,pPathWorkingDirectoryTop,&pPathTempRoot) ); SG_ERR_CHECK( SG_time__get_milliseconds_since_1970_utc(pCtx,&iTimeUTC) ); SG_ERR_CHECK( SG_time__decode__local(pCtx,iTimeUTC,&tmLocal) ); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx,&pString) ); while (1) { // build path "<wd-top>/.sgtemp/<purpose>_20091201_0". // where <purpose> is something like "revert" or "merge". SG_ERR_CHECK( SG_string__sprintf(pCtx,pString,"%s_%04d%02d%02d_%d", pszPurpose, tmLocal.year,tmLocal.month,tmLocal.mday, kAttempt++) ); SG_ERR_CHECK( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx,&pPath,pPathTempRoot,SG_string__sz(pString)) ); // try to create a NEW temp directory. if this path already exists on disk, // loop and try again. if we have a hard errors, just give up. SG_fsobj__mkdir_recursive__pathname(pCtx,pPath); if (SG_context__has_err(pCtx) == SG_FALSE) goto success; if (SG_context__err_equals(pCtx,SG_ERR_DIR_ALREADY_EXISTS) == SG_FALSE) SG_ERR_RETHROW; SG_context__err_reset(pCtx); SG_PATHNAME_NULLFREE(pCtx,pPath); } success: *ppPathTempDir = pPath; SG_STRING_NULLFREE(pCtx, pString); SG_PATHNAME_NULLFREE(pCtx, pPathTempRoot); return; fail: SG_STRING_NULLFREE(pCtx, pString); SG_PATHNAME_NULLFREE(pCtx, pPathTempRoot); SG_PATHNAME_NULLFREE(pCtx, pPath); }
STDMETHODIMP CVeracityOverlay_Ignored::IsMemberOf(LPCWSTR pwszPath, DWORD dwAttrib) { pwszPath; dwAttrib; HRESULT returnVal = S_FALSE; //return returnVal; SG_context* pCtx = GetAContext(); SG_pathname * pPathCwd = NULL; SG_pathname * pPathTop = NULL; if (InAWorkingFolder(pCtx, pwszPath, &pPathCwd, &pPathTop) ) { SG_wc_status_flags status = GetStatus(pCtx, SG_pathname__sz(pPathCwd), SG_pathname__sz(pPathTop), NULL); if (StatusHas(status, SG_WC_STATUS_FLAGS__U__IGNORED) || StatusHas(status, SG_WC_STATUS_FLAGS__R__RESERVED) ) returnVal = S_OK; else returnVal = S_FALSE; } else returnVal = S_FALSE; SG_PATHNAME_NULLFREE(pCtx, pPathCwd); SG_PATHNAME_NULLFREE(pCtx, pPathTop); SG_CONTEXT_NULLFREE(pCtx); return returnVal; }
void u0023_vcdiff__test_deltify(SG_context * pCtx) { FILE* fp; SG_pathname* pPath_version1 = NULL; SG_pathname* pPath_version2 = NULL; int i; VERIFY_ERR_CHECK_DISCARD( unittest__get_nonexistent_pathname(pCtx,&pPath_version1) ); VERIFY_ERR_CHECK_DISCARD( unittest__get_nonexistent_pathname(pCtx,&pPath_version2) ); fp = fopen(SG_pathname__sz(pPath_version1), "w"); for (i=0; i<500; i++) { fprintf(fp, "Ah, I should have known it from the very start This girl will leave me with a broken heart Now listen people what I'm telling you A-keep away from-a Runaround Sue\n"); } fclose(fp); fp = fopen(SG_pathname__sz(pPath_version2), "w"); for (i=0; i<100; i++) { fprintf(fp, "He rocks in the tree-top all a day long Hoppin' and a-boppin' and a-singin' the song All the little birds on J-Bird St. Love to hear the robin goin' tweet tweet tweet\n"); } fclose(fp); VERIFY_ERR_CHECK_DISCARD( u0023_vcdiff__do_test_deltify(pCtx, pPath_version1, pPath_version2) ); SG_ERR_IGNORE( SG_fsobj__remove__pathname(pCtx, pPath_version1) ); SG_ERR_IGNORE( SG_fsobj__remove__pathname(pCtx, pPath_version2) ); SG_PATHNAME_NULLFREE(pCtx, pPath_version1); SG_PATHNAME_NULLFREE(pCtx, pPath_version2); }
/** * Return a temporary pathname (in the "tmp" dir) for any purpose. * We DO NOT create an actual file system object; we just generate * the pathname. * * We create something like: * * <root>/.sgdrawer/tmp/t123456789.tmp * */ void sg_wc_db__path__get_unique_temp_path(SG_context * pCtx, const sg_wc_db * pDb, SG_pathname ** ppPathTemp) { SG_pathname * pPathTempDir = NULL; SG_pathname * pPath = NULL; char bufTid[SG_TID_MAX_BUFFER_LENGTH + 20]; SG_bool bExists; SG_ERR_CHECK( sg_wc_db__path__get_temp_dir(pCtx, pDb, &pPathTempDir) ); while (1) { SG_ERR_CHECK( SG_tid__generate2__suffix(pCtx, bufTid, sizeof(bufTid), 9, "tmp") ); SG_ERR_CHECK( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPath, pPathTempDir, bufTid) ); SG_ERR_CHECK( SG_fsobj__exists__pathname(pCtx, pPath, &bExists, NULL, NULL) ); if (!bExists) break; SG_PATHNAME_NULLFREE(pCtx, pPath); } *ppPathTemp = pPath; pPath = NULL; fail: SG_PATHNAME_NULLFREE(pCtx, pPathTempDir); SG_PATHNAME_NULLFREE(pCtx, pPath); }
void u0023_vcdiff__test_deltify_from_zerolength(SG_context * pCtx) { FILE* fp; SG_pathname* pPath_version1 = NULL; SG_pathname* pPath_version2 = NULL; int i; VERIFY_ERR_CHECK_DISCARD( unittest__get_nonexistent_pathname(pCtx, &pPath_version1) ); VERIFY_ERR_CHECK_DISCARD( unittest__get_nonexistent_pathname(pCtx, &pPath_version2) ); fp = fopen(SG_pathname__sz(pPath_version1), "w"); fclose(fp); fp = fopen(SG_pathname__sz(pPath_version2), "w"); for (i=0; i<500000; i++) { fputc(i % 256, fp); } fclose(fp); VERIFY_ERR_CHECK_DISCARD( u0023_vcdiff__do_test_deltify(pCtx, pPath_version1, pPath_version2) ); SG_ERR_IGNORE( SG_fsobj__remove__pathname(pCtx, pPath_version1) ); SG_ERR_IGNORE( SG_fsobj__remove__pathname(pCtx, pPath_version2) ); SG_PATHNAME_NULLFREE(pCtx, pPath_version1); SG_PATHNAME_NULLFREE(pCtx, pPath_version2); }
void u0023_vcdiff__test_deltify_run(SG_context * pCtx) { FILE* fp; SG_pathname* pPath_version1 = NULL; SG_pathname* pPath_version2 = NULL; int i; VERIFY_ERR_CHECK_DISCARD( unittest__get_nonexistent_pathname(pCtx, &pPath_version1) ); VERIFY_ERR_CHECK_DISCARD( unittest__get_nonexistent_pathname(pCtx, &pPath_version2) ); fp = fopen(SG_pathname__sz(pPath_version1), "w"); fprintf(fp, "Ah, I should havq known it from thq vqry start This girl will lqavq mq with a brokqn hqart Now listqn pqoplq what I'm tqlling you A-kqqp away from-a Runaround Suq\n"); fclose(fp); fp = fopen(SG_pathname__sz(pPath_version2), "w"); for (i=0; i<500000; i++) { fputc('e', fp); } fclose(fp); VERIFY_ERR_CHECK_DISCARD( u0023_vcdiff__do_test_deltify(pCtx, pPath_version1, pPath_version2) ); SG_ERR_IGNORE( SG_fsobj__remove__pathname(pCtx, pPath_version1) ); SG_ERR_IGNORE( SG_fsobj__remove__pathname(pCtx, pPath_version2) ); SG_PATHNAME_NULLFREE(pCtx, pPath_version1); SG_PATHNAME_NULLFREE(pCtx, pPath_version2); }
void u0023_vcdiff__test_deltify_small_files(SG_context * pCtx) { FILE* fp; SG_pathname* pPath_version1; SG_pathname* pPath_version2; VERIFY_ERR_CHECK_DISCARD( unittest__get_nonexistent_pathname(pCtx, &pPath_version1) ); VERIFY_ERR_CHECK_DISCARD( unittest__get_nonexistent_pathname(pCtx, &pPath_version2) ); fp = fopen(SG_pathname__sz(pPath_version1), "w"); fprintf(fp, "e"); fclose(fp); fp = fopen(SG_pathname__sz(pPath_version2), "w"); fprintf(fp, "a"); fclose(fp); VERIFY_ERR_CHECK_DISCARD( u0023_vcdiff__do_test_deltify(pCtx, pPath_version1, pPath_version2) ); SG_ERR_IGNORE( SG_fsobj__remove__pathname(pCtx, pPath_version1) ); SG_ERR_IGNORE( SG_fsobj__remove__pathname(pCtx, pPath_version2) ); SG_PATHNAME_NULLFREE(pCtx, pPath_version1); SG_PATHNAME_NULLFREE(pCtx, pPath_version2); }
void u0038_test_wdmapping(SG_context * pCtx) { SG_vhash* pvh = NULL; SG_closet_descriptor_handle* ph = NULL; SG_pathname* pPath = NULL; SG_pathname* pMappedPath = NULL; SG_string* pstrRepoDescriptorName = NULL; char* pszidGid = NULL; char buf_tid[SG_TID_MAX_BUFFER_LENGTH]; VERIFY_ERR_CHECK_DISCARD( SG_tid__generate2__suffix(pCtx, buf_tid, sizeof(buf_tid), 32, "u0038") ); VERIFY_ERR_CHECK_DISCARD( SG_PATHNAME__ALLOC__SZ(pCtx, &pPath, buf_tid) ); VERIFY_ERR_CHECK_DISCARD( SG_fsobj__mkdir__pathname(pCtx, pPath) ); SG_ERR_IGNORE( SG_closet__descriptors__remove(pCtx, "r1") ); VERIFY_ERR_CHECK_DISCARD( SG_closet__descriptors__add_begin(pCtx, "r1", NULL, NULL, NULL, NULL, &pvh, &ph) ); VERIFY_ERR_CHECK_DISCARD( SG_closet__descriptors__add_commit(pCtx, &ph, pvh, SG_REPO_STATUS__NORMAL) ); SG_VHASH_NULLFREE(pCtx, pvh); VERIFY_ERR_CHECK_DISCARD( SG_workingdir__set_mapping(pCtx, pPath, "r1", NULL) ); VERIFY_ERR_CHECK_DISCARD( SG_workingdir__find_mapping(pCtx, pPath, &pMappedPath, &pstrRepoDescriptorName, &pszidGid) ); VERIFY_COND("ridesc match", (0 == strcmp("r1", SG_string__sz(pstrRepoDescriptorName)))); VERIFY_ERR_CHECK_DISCARD( SG_pathname__append__from_sz(pCtx, pPath, "foo") ); VERIFY_ERR_CHECK_DISCARD( SG_pathname__append__from_sz(pCtx, pPath, "bar") ); VERIFY_ERR_CHECK_DISCARD( SG_pathname__append__from_sz(pCtx, pPath, "plok") ); SG_STRING_NULLFREE(pCtx, pstrRepoDescriptorName); SG_PATHNAME_NULLFREE(pCtx, pMappedPath); VERIFY_ERR_CHECK_DISCARD( SG_workingdir__find_mapping(pCtx, pPath, &pMappedPath, &pstrRepoDescriptorName, &pszidGid) ); SG_STRING_NULLFREE(pCtx, pstrRepoDescriptorName); SG_PATHNAME_NULLFREE(pCtx, pMappedPath); SG_PATHNAME_NULLFREE(pCtx, pPath); }
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); }
void u0038_test_wdmapping(SG_context * pCtx) { SG_vhash* pvh = NULL; SG_pathname* pPath = NULL; SG_pathname* pMappedPath = NULL; SG_string* pstrRepoDescriptorName = NULL; char* pszidGid = NULL; VERIFY_ERR_CHECK_DISCARD( SG_PATHNAME__ALLOC(pCtx, &pPath) ); VERIFY_ERR_CHECK_DISCARD( SG_pathname__set__from_cwd(pCtx, pPath) ); VERIFY_ERR_CHECK_DISCARD( SG_VHASH__ALLOC(pCtx, &pvh) ); VERIFY_ERR_CHECK_DISCARD( SG_vhash__add__string__sz(pCtx, pvh, "hello", "world") ); VERIFY_ERR_CHECK_DISCARD( SG_vhash__add__string__sz(pCtx, pvh, "hola", "mundo") ); SG_ERR_IGNORE( SG_closet__descriptors__remove(pCtx, "r1") ); VERIFY_ERR_CHECK_DISCARD( SG_closet__descriptors__add(pCtx, "r1", pvh) ); VERIFY_ERR_CHECK_DISCARD( SG_workingdir__set_mapping(pCtx, pPath, "r1", NULL) ); VERIFY_ERR_CHECK_DISCARD( SG_workingdir__find_mapping(pCtx, pPath, &pMappedPath, &pstrRepoDescriptorName, &pszidGid) ); VERIFY_COND("ridesc match", (0 == strcmp("r1", SG_string__sz(pstrRepoDescriptorName)))); VERIFY_ERR_CHECK_DISCARD( SG_pathname__append__from_sz(pCtx, pPath, "foo") ); VERIFY_ERR_CHECK_DISCARD( SG_pathname__append__from_sz(pCtx, pPath, "bar") ); VERIFY_ERR_CHECK_DISCARD( SG_pathname__append__from_sz(pCtx, pPath, "plok") ); SG_STRING_NULLFREE(pCtx, pstrRepoDescriptorName); SG_PATHNAME_NULLFREE(pCtx, pMappedPath); VERIFY_ERR_CHECK_DISCARD( SG_workingdir__find_mapping(pCtx, pPath, &pMappedPath, &pstrRepoDescriptorName, &pszidGid) ); SG_STRING_NULLFREE(pCtx, pstrRepoDescriptorName); SG_PATHNAME_NULLFREE(pCtx, pMappedPath); SG_PATHNAME_NULLFREE(pCtx, pPath); SG_VHASH_NULLFREE(pCtx, pvh); }
static void _sg_workingdir__get_dir(SG_context* pCtx, SG_repo* pRepo, const SG_pathname* pPathLocal, const char* pszidHidTreeNode, SG_vhash * pvhTimestamps) { SG_uint32 count; SG_uint32 i; SG_pathname* pPathSub = NULL; SG_treenode* pTreenode = NULL; SG_ERR_CHECK( SG_treenode__load_from_repo(pCtx, pRepo, pszidHidTreeNode, &pTreenode) ); SG_ERR_CHECK( SG_treenode__count(pCtx, pTreenode, &count) ); for (i=0; i<count; i++) { const char * pszGid; const SG_treenode_entry* pEntry; const char* pszName; SG_ERR_CHECK( SG_treenode__get_nth_treenode_entry__ref(pCtx, pTreenode, i, &pszGid, &pEntry) ); SG_ERR_CHECK( SG_treenode_entry__get_entry_name(pCtx, pEntry, &pszName) ); SG_ERR_CHECK( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPathSub, pPathLocal, pszName) ); SG_ERR_CHECK( _sg_workingdir__get_entry(pCtx, pRepo, pPathSub, pszGid, pEntry, pvhTimestamps) ); SG_PATHNAME_NULLFREE(pCtx, pPathSub); } fail: SG_TREENODE_NULLFREE(pCtx, pTreenode); SG_PATHNAME_NULLFREE(pCtx, pPathSub); }
void u0051_hidlookup_test__1(SG_context * pCtx, SG_pathname* pPathTopDir) { char bufName[SG_TID_MAX_BUFFER_LENGTH]; SG_pathname* pPathWorkingDir = NULL; SG_pathname* pPathFile = NULL; SG_dagnode* pdn = NULL; const char* psz_hid_cs = NULL; SG_repo* pRepo = NULL; char buf_partial[256]; char* psz_result = NULL; SG_audit q; VERIFY_ERR_CHECK( SG_tid__generate2(pCtx, bufName, sizeof(bufName), 32) ); /* create the working dir */ VERIFY_ERR_CHECK( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPathWorkingDir, pPathTopDir, bufName) ); VERIFY_ERR_CHECK( SG_fsobj__mkdir__pathname(pCtx, pPathWorkingDir) ); /* add stuff */ VERIFY_ERR_CHECK( u0051_hidlookup__create_file__numbers(pCtx, pPathWorkingDir, "aaa", 20) ); /* create the repo */ VERIFY_ERR_CHECK( _ut_pt__new_repo(pCtx, bufName, pPathWorkingDir) ); VERIFY_ERR_CHECK( _ut_pt__addremove(pCtx, pPathWorkingDir) ); VERIFY_ERR_CHECK( u0051_hidlookup__commit_all(pCtx, pPathWorkingDir, &pdn) ); VERIFY_ERR_CHECK( SG_dagnode__get_id_ref(pCtx, pdn, &psz_hid_cs) ); VERIFY_ERR_CHECK( SG_repo__open_repo_instance(pCtx, bufName, &pRepo) ); VERIFY_ERR_CHECK( SG_audit__init(pCtx, &q, pRepo, SG_AUDIT__WHEN__NOW, SG_AUDIT__WHO__FROM_SETTINGS) ); VERIFY_ERR_CHECK( SG_vc_tags__add(pCtx, pRepo, psz_hid_cs, "remember", &q) ); VERIFY_ERR_CHECK( SG_strcpy(pCtx, buf_partial, sizeof(buf_partial), psz_hid_cs) ); buf_partial[10] = 0; VERIFY_ERR_CHECK( SG_repo__hidlookup__dagnode(pCtx, pRepo, SG_DAGNUM__VERSION_CONTROL, buf_partial, &psz_result) ); VERIFY_COND("found", (0 == strcmp(psz_result, psz_hid_cs))); SG_NULLFREE(pCtx, psz_result); VERIFY_ERR_CHECK( SG_repo__hidlookup__blob(pCtx, pRepo, buf_partial, &psz_result) ); VERIFY_COND("found", (0 == strcmp(psz_result, psz_hid_cs))); SG_NULLFREE(pCtx, psz_result); VERIFY_ERR_CHECK( SG_vc_tags__lookup__tag(pCtx, pRepo, "remember", &psz_result) ); VERIFY_COND("found", (0 == strcmp(psz_result, psz_hid_cs))); SG_NULLFREE(pCtx, psz_result); fail: SG_NULLFREE(pCtx, psz_result); SG_REPO_NULLFREE(pCtx, pRepo); SG_DAGNODE_NULLFREE(pCtx, pdn); SG_PATHNAME_NULLFREE(pCtx, pPathWorkingDir); SG_PATHNAME_NULLFREE(pCtx, pPathFile); }
static void _resolve__step_pathnames__free(SG_context * pCtx, _resolve__step_pathnames * pStepPathnames) { if (!pStepPathnames) return; SG_PATHNAME_NULLFREE(pCtx, pStepPathnames->pPath_Mine); SG_PATHNAME_NULLFREE(pCtx, pStepPathnames->pPath_Other); SG_PATHNAME_NULLFREE(pCtx, pStepPathnames->pPath_Ancestor); SG_PATHNAME_NULLFREE(pCtx, pStepPathnames->pPath_Result); SG_NULLFREE(pCtx, pStepPathnames); }
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); }
void sg_wc_tx__apply__move_rename(SG_context * pCtx, SG_wc_tx * pWcTx, const SG_vhash * pvh) { SG_bool bAfterTheFact; SG_bool bUseIntermediate; SG_bool bSrcIsSparse; const char * pszRepoPath_Src; const char * pszRepoPath_Dest; SG_pathname * pPath_Src = NULL; SG_pathname * pPath_Dest = NULL; SG_pathname * pPath_Temp = NULL; SG_ERR_CHECK( SG_vhash__get__bool(pCtx, pvh, "after_the_fact", &bAfterTheFact) ); SG_ERR_CHECK( SG_vhash__get__bool(pCtx, pvh, "use_intermediate", &bUseIntermediate) ); SG_ERR_CHECK( SG_vhash__get__bool(pCtx, pvh, "src_sparse", &bSrcIsSparse) ); SG_ERR_CHECK( SG_vhash__get__sz(pCtx, pvh, "src", &pszRepoPath_Src) ); SG_ERR_CHECK( SG_vhash__get__sz(pCtx, pvh, "dest", &pszRepoPath_Dest) ); #if TRACE_WC_TX_APPLY SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, ("sg_wc_tx__apply__move_rename: [after-the-fact %d][use-intermediate %d][src-sparse %d] '%s' --> '%s'\n"), bAfterTheFact, bUseIntermediate, bSrcIsSparse, pszRepoPath_Src, pszRepoPath_Dest) ); #endif if (bAfterTheFact || bSrcIsSparse) // user already did the move/rename. return; SG_ERR_CHECK( sg_wc_db__path__sz_repopath_to_absolute(pCtx, pWcTx->pDb, pszRepoPath_Src, &pPath_Src ) ); SG_ERR_CHECK( sg_wc_db__path__sz_repopath_to_absolute(pCtx, pWcTx->pDb, pszRepoPath_Dest, &pPath_Dest) ); if (bUseIntermediate) { // need to use a temp file because of transient // collisions ('vv rename foo FOO' on Windows). SG_ERR_CHECK( sg_wc_db__path__get_unique_temp_path(pCtx, pWcTx->pDb, &pPath_Temp) ); SG_ERR_CHECK( SG_fsobj__move__pathname_pathname(pCtx, pPath_Src, pPath_Temp) ); SG_ERR_CHECK( SG_fsobj__move__pathname_pathname(pCtx, pPath_Temp, pPath_Dest) ); } else { SG_ERR_CHECK( SG_fsobj__move__pathname_pathname(pCtx, pPath_Src, pPath_Dest) ); } fail: SG_PATHNAME_NULLFREE(pCtx, pPath_Src); SG_PATHNAME_NULLFREE(pCtx, pPath_Dest); SG_PATHNAME_NULLFREE(pCtx, pPath_Temp); }
void SG_jscore__shutdown(SG_context * pCtx) { if(gpJSCoreGlobalState!=NULL) { if (gpJSCoreGlobalState->rt) JS_DestroyRuntime(gpJSCoreGlobalState->rt); JS_ShutDown(); SG_PATHNAME_NULLFREE(pCtx, gpJSCoreGlobalState->pPathToDispatchDotJS); SG_PATHNAME_NULLFREE(pCtx, gpJSCoreGlobalState->pPathToCore); SG_PATHNAME_NULLFREE(pCtx, gpJSCoreGlobalState->pPathToModules); SG_RBTREE_NULLFREE_WITH_ASSOC(pCtx, gpJSCoreGlobalState->prbJSMutexes, _free_js_mutex_cb); SG_NULLFREE(pCtx, gpJSCoreGlobalState); } }
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); }
void sg_wc_db__path__sz_repopath_to_absolute(SG_context * pCtx, const sg_wc_db * pDb, const char * pszRepoPath, SG_pathname ** ppPathItem) { SG_pathname * pPath = NULL; // TODO 2012/01/23 This code was written before the extended-prefix repo-path // TODO stuff, but it is still valid to require a live/wd-relative // TODO repo-path when building an absolute pathname (because it // TODO probably doesn't make sense to convert an arbitrary-context // TODO repo-path (without someone doing the implied context conversion)). // TODO // TODO So I'm going to leave this as an assert for now. SG_ASSERT_RELEASE_FAIL( ((pszRepoPath[0]=='@') && (pszRepoPath[1]=='/')) ); SG_ERR_CHECK( SG_PATHNAME__ALLOC__COPY(pCtx, &pPath, pDb->pPathWorkingDirectoryTop) ); SG_ERR_CHECK( SG_pathname__add_final_slash(pCtx, pPath) ); if (pszRepoPath[2]) SG_ERR_CHECK( SG_pathname__append__from_sz(pCtx, pPath, &pszRepoPath[2]) ); *ppPathItem = pPath; return; fail: SG_PATHNAME_NULLFREE(pCtx, pPath); }
void sg_wc_tx__apply__delete_issue(SG_context * pCtx, SG_wc_tx * pWcTx, const SG_vhash * pvh) { SG_pathname * pPath = NULL; const char * pszRepoPathTempDir = NULL; // During the APPLY phase, our only task is to delete // the item's private tempdir, if it had one. Only items // with file-edit conflicts will actually have one. SG_ERR_CHECK( SG_vhash__check__sz(pCtx, pvh, "repopath_tempdir", &pszRepoPathTempDir) ); #if TRACE_WC_MERGE SG_ERR_IGNORE( SG_console(pCtx, SG_CS_STDERR, "sg_wc_tx__apply__delete_issue: tempdir '%s'\n", ((pszRepoPathTempDir) ? pszRepoPathTempDir : "(null)")) ); #endif if (pszRepoPathTempDir) { SG_ERR_CHECK( sg_wc_db__path__sz_repopath_to_absolute(pCtx, pWcTx->pDb, pszRepoPathTempDir, &pPath) ); // actually deleting the tempdir can fail for any number of reasons, // but that should not abort the COMMIT. so we use _IGNORE() here // rather than _CHECK(). SG_ERR_IGNORE( SG_fsobj__rmdir_recursive__pathname(pCtx, pPath) ); } fail: SG_PATHNAME_NULLFREE(pCtx, pPath); }
MyMain() { SG_repo * pRepo = NULL; SG_pathname * pPathnameTempDir = NULL; TEMPLATE_MAIN_START; VERIFY_ERR_CHECK( MyFn(create_repo)(pCtx,&pRepo) ); VERIFY_ERR_CHECK( MyFn(create_tmp_src_dir)(pCtx,&pPathnameTempDir) ); BEGIN_TEST( MyFn(create_some_blobs_from_bytes)(pCtx, pRepo) ); BEGIN_TEST( MyFn(create_some_blobs_from_files)(pCtx, pRepo,pPathnameTempDir) ); BEGIN_TEST( MyFn(create_zero_byte_blob)(pCtx, pRepo) ); ////////////////////////////////////////////////////////////////// // TODO delete repo directory and everything we created under it. // TODO delete temp directory and everything we created under it. // fall-thru to common cleanup fail: SG_REPO_NULLFREE(pCtx, pRepo); SG_PATHNAME_NULLFREE(pCtx, pPathnameTempDir); TEMPLATE_MAIN_END; }
void vv2__do_cmd_cat(SG_context * pCtx, const SG_option_state * pOptSt, const SG_stringarray * psaArgs) { SG_pathname* pPathOutputFile = NULL; if (pOptSt->psz_output_file) { SG_ERR_CHECK( SG_pathname__alloc__sz(pCtx, &pPathOutputFile, pOptSt->psz_output_file) ); SG_ERR_CHECK( SG_vv2__cat__to_pathname(pCtx, pOptSt->psz_repo, pOptSt->pRevSpec, psaArgs, pPathOutputFile) ); } else { // TODO 2012/12/21 For now, just splat the contents of each file // TODO to the console without anything fancy. // TODO // TODO We support multiple files in one command, but // TODO only without bells or whistles. // TODO Do we need to print headers or breaks between // TODO them or should we just behave like '/bin/cat'? // TODO // TODO Do we want to have a '/bin/cat -v' like mode? SG_ERR_CHECK( SG_vv2__cat__to_console(pCtx, pOptSt->psz_repo, pOptSt->pRevSpec, psaArgs) ); } fail: SG_PATHNAME_NULLFREE(pCtx, pPathOutputFile); }
static void _getDescriptorName( SG_context *pCtx, const _request_headers *pRequestHeaders, SG_string **ppRepoName) { SG_pathname *pPathCwd = NULL; if (_startsWith("repos/", pRequestHeaders->pUri) && (strlen(pRequestHeaders->pUri) > 6)) { const char *nameStart = pRequestHeaders->pUri + 6; const char *nameEnd = strchr(nameStart, '/'); SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, ppRepoName) ); if (nameEnd == NULL) SG_ERR_CHECK( SG_string__set__sz(pCtx, *ppRepoName, nameStart) ); else SG_ERR_CHECK( SG_string__set__buf_len(pCtx, *ppRepoName, (const SG_byte *)nameStart, (nameEnd - nameStart) * sizeof(char)) ); } else { SG_ERR_CHECK( SG_PATHNAME__ALLOC(pCtx, &pPathCwd) ); SG_ERR_CHECK( SG_pathname__set__from_cwd(pCtx, pPathCwd) ); SG_ERR_CHECK( SG_workingdir__find_mapping(pCtx, pPathCwd, NULL, ppRepoName, NULL) ); } fail: SG_PATHNAME_NULLFREE(pCtx, pPathCwd); }
/** * Create a pathname in the per-file temp-dir for one * version of the file. * * We use the ancestor version of the entryname * to avoid issues with pending renames. * */ void _sg_mrg__create_pathname_for_conflict_file(SG_context * pCtx, SG_mrg * pMrg, SG_mrg_cset_entry_conflict * pMrgCSetEntryConflict, const char * pszPrefix, SG_pathname ** ppPathReturned) { SG_pathname * pPath = NULL; SG_string * pString = NULL; SG_ERR_CHECK( _sg_mrg__ensure_temp_dir_for_file_conflict(pCtx, pMrg, pMrgCSetEntryConflict) ); // create something like: "<sgtemp>/<gid7>_YYYYMMDD_<k>/<prefix>~<entryname>" SG_ERR_CHECK( SG_STRING__ALLOC(pCtx, &pString) ); SG_ERR_CHECK( SG_string__sprintf(pCtx, pString, "%s~%s", pszPrefix, SG_string__sz(pMrgCSetEntryConflict->pMrgCSetEntry_Ancestor->pStringEntryname)) ); SG_ERR_CHECK( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPath, pMrgCSetEntryConflict->pPathTempDirForFile, SG_string__sz(pString)) ); SG_STRING_NULLFREE(pCtx, pString); *ppPathReturned = pPath; return; fail: SG_STRING_NULLFREE(pCtx, pString); SG_PATHNAME_NULLFREE(pCtx, pPath); }
/** * Return a pathname set to the location of the "tmp" * directory for this working directory. * * We create something like: * * <root>/.sgdrawer/tmp/ * * Note that the main "tmp" directory is long-lived and * may be used by multiple tasks at the same time. So * for significant tasks, create a private sub-directory * within it. * */ void sg_wc_db__path__get_temp_dir(SG_context * pCtx, const sg_wc_db * pDb, SG_pathname ** ppPathTempDir) { SG_pathname * pPath = NULL; SG_ERR_CHECK( SG_workingdir__get_drawer_path(pCtx, pDb->pPathWorkingDirectoryTop, &pPath) ); SG_ERR_CHECK( SG_pathname__append__from_sz(pCtx, pPath, "tmp") ); SG_ERR_CHECK( SG_pathname__add_final_slash(pCtx, pPath) ); // the "tmp" dir could get deleted by routine housekeeping, // so re-create it if someone even thinks about using temp-based // pathnames. i'm going to skip the usual "if (!exists) mkdir" // stuff and just try to create it and ignore the error. SG_fsobj__mkdir__pathname(pCtx, pPath); if (SG_CONTEXT__HAS_ERR(pCtx)) { if (!SG_context__err_equals(pCtx, SG_ERR_DIR_ALREADY_EXISTS)) SG_ERR_RETHROW; SG_context__err_reset(pCtx); } *ppPathTempDir = pPath; return; fail: SG_PATHNAME_NULLFREE(pCtx, pPath); }
/** * Convert relative path to absolute, but make * sure that normalization doesn't take it outside * of the working directory. * * This is just pathname/string parsing; we DO NOT * confirm that the path exists or could exist. * */ void sg_wc_db__path__relative_to_absolute(SG_context * pCtx, const sg_wc_db * pDb, const SG_string * pStringRelativePath, SG_pathname ** ppPathItem) { SG_pathname * pPathWDT = NULL; SG_pathname * pPath = NULL; SG_uint32 lenWDT; // choke if they give us a repo-path. SG_ARGCHECK_RETURN( (SG_string__sz(pStringRelativePath)[0] != '@'), pStringRelativePath ); // choke if this WC TX isn't cwd-based. SG_ERR_CHECK( _check_if_relative_paths_allowed(pCtx, pDb) ); // clone WDT so that we can force a trailing slash. SG_ERR_CHECK( SG_PATHNAME__ALLOC__COPY(pCtx, &pPathWDT, pDb->pPathWorkingDirectoryTop) ); SG_ERR_CHECK( SG_pathname__add_final_slash(pCtx, pPathWDT) ); lenWDT = SG_pathname__length_in_bytes(pPathWDT); // allocate and normalize a new path with the net // result rather than writing on the clone (so that // we can do the following prefix test safely). SG_ERR_CHECK( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPath, pPathWDT, SG_string__sz(pStringRelativePath)) ); if (strncmp(SG_pathname__sz(pPath), SG_pathname__sz(pPathWDT), lenWDT) != 0) { SG_ERR_THROW2( SG_ERR_PATH_NOT_IN_WORKING_COPY, (pCtx, "The path '%s' is not inside the working copy rooted at '%s'.", SG_string__sz(pStringRelativePath), SG_pathname__sz(pDb->pPathWorkingDirectoryTop)) ); } SG_PATHNAME_NULLFREE(pCtx, pPathWDT); *ppPathItem = pPath; return; fail: SG_PATHNAME_NULLFREE(pCtx, pPathWDT); SG_PATHNAME_NULLFREE(pCtx, pPath); }
void SG_sync__make_temp_path(SG_context* pCtx, const char* psz_name, SG_pathname** ppPath) { SG_pathname* pPath_tempdir = NULL; SG_pathname* pPath_staging = NULL; SG_ERR_CHECK( SG_PATHNAME__ALLOC__USER_TEMP_DIRECTORY(pCtx, &pPath_tempdir) ); SG_ERR_CHECK( SG_PATHNAME__ALLOC__PATHNAME_SZ(pCtx, &pPath_staging, pPath_tempdir, psz_name) ); *ppPath = pPath_staging; pPath_staging = NULL; /* fallthru */ fail: SG_PATHNAME_NULLFREE(pCtx, pPath_tempdir); SG_PATHNAME_NULLFREE(pCtx, pPath_staging); }
void _sg_mrg__copy_wc_to_temp_file(SG_context * pCtx, SG_mrg * pMrg, SG_mrg_cset_entry * pMrgCSetEntry, const SG_pathname * pPathTempFile) { sg_wc_liveview_item * pLVI; SG_string * pStringRepoPath = NULL; SG_pathname * pPathInWC = NULL; SG_bool bExists; SG_bool bKnown; 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 copy of WC version to [%s]\n", SG_pathname__sz(pPathTempFile)) ); #endif return; } // Find the absolute path of the WD version of the file. SG_ERR_CHECK( sg_wc_tx__liveview__fetch_random_item(pCtx, pMrg->pWcTx, pMrgCSetEntry->uiAliasGid, &bKnown, &pLVI) ); SG_ASSERT_RELEASE_FAIL( (bKnown) ); SG_ERR_CHECK( sg_wc_tx__liveview__compute_live_repo_path(pCtx, pMrg->pWcTx, pLVI, &pStringRepoPath) ); SG_ERR_CHECK( sg_wc_db__path__repopath_to_absolute(pCtx, pMrg->pWcTx->pDb, pStringRepoPath, &pPathInWC) ); #if TRACE_WC_MERGE SG_ERR_IGNORE( SG_console(pCtx,SG_CS_STDERR, "Copying WC version [%s] to [%s]\n", SG_string__sz(pStringRepoPath), 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_fsobj__copy_file(pCtx, pPathInWC, pPathTempFile, 0400) ); fail: SG_STRING_NULLFREE(pCtx, pStringRepoPath); SG_PATHNAME_NULLFREE(pCtx, pPathInWC); }
void _set_curl_options(SG_context* pCtx, CURL* pCurl) { char * szServerFiles = NULL; char * szVerifyCerts = NULL; SG_pathname *pServerFiles = NULL; CURLcode rc = CURLE_OK; #ifdef WINDOWS SG_bool bExists = SG_FALSE; SG_bool bVerifyCerts = SG_TRUE; #endif SG_ERR_CHECK( SG_localsettings__get__sz(pCtx, SG_LOCALSETTING__VERIFY_SSL_CERTS, NULL, &szVerifyCerts, NULL) ); if (szVerifyCerts != NULL && (SG_strcmp__null(szVerifyCerts, "false") == 0 || SG_strcmp__null(szVerifyCerts, "FALSE") == 0)) { #ifdef WINDOWS bVerifyCerts = SG_FALSE; #endif rc = curl_easy_setopt(pCurl, CURLOPT_SSL_VERIFYPEER, SG_FALSE); } if (rc) SG_ERR_THROW(SG_ERR_LIBCURL(rc)); #ifdef WINDOWS if (bVerifyCerts) { SG_ERR_CHECK( SG_localsettings__get__sz(pCtx, SG_LOCALSETTING__SERVER_FILES, NULL, &szServerFiles, NULL) ); if (szServerFiles) { SG_ERR_CHECK( SG_pathname__alloc__sz(pCtx, &pServerFiles, szServerFiles) ); SG_ERR_CHECK( SG_pathname__append__from_sz(pCtx, pServerFiles, "ssl") ); SG_ERR_CHECK( SG_pathname__append__from_sz(pCtx, pServerFiles, "curl-ca-bundle.crt") ); SG_ERR_CHECK( SG_fsobj__exists__pathname(pCtx, pServerFiles, &bExists, NULL, NULL) ); } if (bExists) { rc = curl_easy_setopt(pCurl, CURLOPT_CAINFO, SG_pathname__sz(pServerFiles)); if (rc) SG_ERR_THROW(SG_ERR_LIBCURL(rc)); } else { if (pServerFiles) SG_ERR_CHECK( SG_log__report_warning(pCtx, "Could not find root certificate file. Looked for it at: %s. SSL connections will not work.", SG_pathname__sz(pServerFiles)) ); else SG_ERR_CHECK( SG_log__report_warning(pCtx, "Could not find root certificate file: no server/files path is configured. SSL connections will not work.") ); } } #endif fail: SG_PATHNAME_NULLFREE(pCtx, pServerFiles); SG_NULLFREE(pCtx, szServerFiles); SG_NULLFREE(pCtx, szVerifyCerts); }
static void _clean_up_logging( SG_context * pCtx, SG_log_console__data * pcLogStdData, SG_log_text__data * pcLogFileData, SG_log_text__writer__daily_path__data * pcLogFileWriterData) { SG_ERR_IGNORE( SG_log_text__unregister(pCtx, pcLogFileData) ); SG_ERR_IGNORE( SG_log_console__unregister(pCtx, pcLogStdData) ); SG_PATHNAME_NULLFREE(pCtx, pcLogFileWriterData->pBasePath); }