2013-05-21 70 views
1

我試圖使用BSD複製文件(...)將文件複製到已安裝的AFP共享(/ Volumes/exchange )像這樣一個OBJ-C++代碼:Mac OS 10.7.5 BSD copyfile()EINVAL複製名稱中帶有雙引號的文件

小例子:

#include <string> 
#include <string.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <unistd.h> 
#include <errno.h> 
#include <copyfile.h> 
#include <stdio.h> 

#import <Cocoa/Cocoa.h> 

int copyfile_callback(int what, int stage, copyfile_state_t state, const char * src, const char * dst, void * ctx); 
void copy_file(const std::string& src, const std::string& dst); 
NSString* StringToNSString (const std::string& Str); 

int main() 
{ 
    [NSAutoreleasePool new]; 
    [NSApplication sharedApplication]; 
    [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; 
    id menubar = [[NSMenu new] autorelease]; 
    id appMenuItem = [[NSMenuItem new] autorelease]; 
    [menubar addItem:appMenuItem]; 
    [NSApp setMainMenu:menubar]; 
    id appMenu = [[NSMenu new] autorelease]; 
    id appName = [[NSProcessInfo processInfo] processName]; 
    id quitTitle = [@"Quit " stringByAppendingString:appName]; 
    id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:quitTitle 
     action:@selector(terminate:) keyEquivalent:@"q"] autorelease]; 
    [appMenu addItem:quitMenuItem]; 
    [appMenuItem setSubmenu:appMenu]; 
    id window = [[[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, 200, 200) 
     styleMask:NSTitledWindowMask backing:NSBackingStoreBuffered defer:NO] 
      autorelease]; 
    [window cascadeTopLeftFromPoint:NSMakePoint(20,20)]; 
    [window setTitle:appName]; 
    [window makeKeyAndOrderFront:nil]; 

    copy_file(
     "copyfile.mm", 
     "/Volumes/exchange/filename(\"[[email protected]#$%^&*,.']\").MP4" 
    ); 

    [NSApp activateIgnoringOtherApps:YES]; 
    [NSApp run]; 
    return 0; 
} 

void copy_file(const std::string& fromPath, const std::string& toPath) 
{ 
    NSLog(@"copyfile: %s -> %s", fromPath.c_str(), toPath.c_str()); 
    copyfile_state_t s = copyfile_state_alloc(); 
    copyfile_state_set(s, COPYFILE_STATE_STATUS_CB, (void*)&copyfile_callback); 
    int returnCode = copyfile(fromPath.c_str(), toPath.c_str(), s, COPYFILE_ALL); 
    if(returnCode) { 
     NSLog(@"copyfile error code: %d, errno=%d", returnCode, errno); 
    } 
    copyfile_state_free(s); 
} 

int copyfile_callback(int what, int stage, copyfile_state_t state, const char * src, const char * dst, void * ctx) 
{ 
    bool bContinue = true; 
    switch(what) { 
     case COPYFILE_COPY_DATA: 
      if(stage == COPYFILE_PROGRESS) { 
       int src_fd; 
       off_t bytes_completed = 0L, total_bytes = 0L; 
       copyfile_state_get(state, COPYFILE_STATE_COPIED, (void*)&bytes_completed); 
       copyfile_state_get(state, COPYFILE_STATE_SRC_FD, (void*)&src_fd); 
       struct stat fstat_info; 
       if(src_fd > 0 && 0 == fstat(src_fd, &fstat_info)) { 
        total_bytes = fstat_info.st_size; 
       } 
       NSLog(@"copyfile_callback: Copied %lld/%lld bytes so far.", bytes_completed, total_bytes); 

      } else if(stage == COPYFILE_ERR) { 
       NSLog(@"copyfile: COPYFILE_COPY_DATA COPYFILE_ERR"); 
       bContinue = false; 
      } 
      break; 
     case COPYFILE_ERR: 
      bContinue = false; 
      break; 
    } 
    return bContinue ? COPYFILE_CONTINUE : COPYFILE_QUIT; 
} 

NSString* StringToNSString (const std::string& Str) 
{ 
    NSString *pString = [NSString stringWithCString:Str.c_str() 
              encoding:[NSString defaultCStringEncoding] 
         ]; 
    return pString; 
} 

保存這個例子作爲copyfile.mm和編譯:

g++ -framework Cocoa -x objective-c++ copyfile.mm -o copyfile 

它正常工作,除非我的目標文件名(toPath)包含一個雙引號符號。然後我得到

returnCode == -1; 
errno == 22; // EINVAL 

它也適用於正常的C++,但與Obj-C++失敗。所有與obj-C++ - 我也看到在SYSTEM.LOG以下消息:

5/21/13 11:47:51.314 PM myAppName: open on /Volumes/exchange/filename("[[email protected]#$%^&*,.']").MP4: Invalid argument 

的Mac OS 10.7.5和gcc 4.2.1:

$ g++ -v 
Using built-in specs. 
Target: i686-apple-darwin11 
Configured with: /private/var/tmp/llvmgcc42/llvmgcc42-2336.11~148/src/configure --disable-checking --enable-werror --prefix=/Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2 --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-prefix=llvm- --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin11 --enable-llvm=/private/var/tmp/llvmgcc42/llvmgcc42-2336.11~148/dst-llvmCore/Developer/usr/local --program-prefix=i686-apple-darwin11- --host=x86_64-apple-darwin11 --target=i686-apple-darwin11 --with-gxx-include-dir=/usr/include/c++/4.2.1 
Thread model: posix 
gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00) 
+0

當我嘗試它'的CopyFile( 「XC」, 「文件名(\」 它的工作原理[〜!@#$%^&* ,.'] \ 「).MP4」,s,COPYFILE_ALL)'在AFP捲上。你應該展示一個[自成一體的可編譯示例](http://sscce.org)。 –

+0

@EricPostpischil,我試着用g ++編譯的SSCCE C++文件,它也適用於我。當我從Obj-C++調用這個時出現問題。 'xcodebuild'不太好,所以需要一些時間才能提供正確的SSCCE ... – 2can

+0

@EricPostpischil我已經添加了最少的示例,請檢查 – 2can

回答

0

正如有人指出由Eric Postpischil(感謝!) - 這是網絡共享的問題。升級到最新的netatalk版本並將正確的設置設置爲netatalk配置後,我的代碼無需任何更改。

(對不起,遲到的答覆,你們:)