2013-02-04 25 views
16

Tôi có thể thiết lập RTS với ioctl trong một ứng dụng Terminal nhỏ, nhưng không phải trong mã trình cắm Mac của tôi, mặc dù cả hai đều chạy cùng một mã. Trong plugin tôi chỉ có thể "có được" các cổng nối tiếp cờ/chân, nhưng không "đặt" chúng. Trong ứng dụng đầu cuối, tôi có thể nhận được thông báo lỗi là 19 và thông báo là "Thao tác không được hỗ trợ bởi thiết bị."Làm cách nào để đặt RTS với ioctl() trong trình cắm Mac?

Nếu đây là vấn đề bảo mật (đang ở trong bối cảnh của một trình duyệt) là có một cách để có được sự cho phép để sửa đổi cờ với ioctl? Tôi có một thiết bị nối tiếp gắn vào một cổng usb .. Đang sử dụng trình điều khiển FTDI vcp (cổng com ảo). .. bên Btw, tôi nhận được kết quả tương tự sử dụng cả Safari và Firefox Dưới đây là mã của tôi:

int disableRTS() 
{ 
    char fd, ret, flags; 

    // open device 
    if ((fd = open("/dev/cu.mydevice", O_RDWR | O_NDELAY)) < 0) 
    { 
     fprintf(stderr, "failed to open device"); 
     return -1; 
    } 

    // Get the current state of the bits 
    ioctl(fd, TIOCMGET, &flags); 
    fprintf(stderr, "Flags are %x.\n", flags);  

    flags &= ~TIOCM_RTS; // Disable the RTS bit 
    ret = ioctl(fd, TIOCMSET, &flags); 

    if (ret == -1) 
     fprintf(stderr, "TIOCMSET failed\n"); 
    else 
     fprintf(stderr, "TIOCMSET succeeded. flags: %x.\n", flags); 

    return 0; 
} 

=========

cập nhật

Nếu tôi làm mới trang trình duyệt, buộc mã được thực hiện lại, ioctl() trả về 0, cho biết thành công. Thật không may, tôi cần nó để làm việc lần đầu tiên. Ngay cả khi tôi viết một vòng lặp và tạm dừng trong giây lát, sử dụng phương thức usleep() và thực hiện các lần thử tiếp theo, nó sẽ thất bại. Nhưng sau đó, khi tôi làm mới nó thành công. Tôi cũng đã sao chép vấn đề này trong một dự án thứ hai, độc quyền NPAPI "BasicPlugin.xcodeproj", do Mozilla cung cấp. Dự án plugin đầu tiên của tôi là dự án Firebreath. Cả hai đều thất bại lúc đầu, sau đó thành công khi tải lại trang. Tôi cũng có 2 ứng dụng Mac riêng biệt hoạt động bình thường. Một là SerialTools, và nó sử dụng chính xác cùng một phương pháp thiết lập RTS on (và DTR off) như ứng dụng Terminal của tôi và các plugin.

========

Cập nhật 2

tôi đã có thể để có được mã cấp hỗ trợ của Apple về vấn đề này, do đó, một giải pháp có thể được tới. Các kỹ sư cho biết nó là "kỳ lạ" rằng mã chạy khác nhau trong một plugin hơn bên ngoài của một, và đang nói chuyện với các kỹ sư plugin Safari.

+0

Thay đổi trường hợp lỗi 'fprintf' thành cuộc gọi đến' perror ("TIOCMSET") 'và xem lỗi nói. –

+0

Tôi xin lỗi, tôi quên đề cập đến. Thông báo lỗi là "Thao tác không được thiết bị hỗ trợ". Đó là số lỗi là 19. ENODEV. – Alyoshak

+0

Đối với tiền thưởng sắp hết hạn mà không có câu trả lời đúng, tôi không biết phải làm gì. Tôi đoán tôi sẽ mất nó mặc dù một kỹ sư của Apple đã chấp nhận vấn đề này và đang cố gắng tìm một giải pháp. Cho biết đó là "kỳ quái" mà mã plugin hoạt động khác với mã không phải plugin. Ít nhất tôi sẽ có thể thêm một câu trả lời đúng cho bất kỳ câu trả lời nào có thể có ích. – Alyoshak

Trả lời

1

Câu trả lời là bất cứ khi nào TIOCMSET hoặc TIOCMGET được sử dụng trong một cuộc gọi đến ioctl() tham số thứ 3 phải là int. Tôi đã sử dụng một char. Duh. Không thể tin rằng tôi đã bỏ lỡ điều này. TIOCMSET và TIOCMGET được định nghĩa như sau:

#define TIOCMSET _IOW('t', 109, int) /* set all modem bits */ 
    … 
    #define TIOCMGET _IOR('t', 106, int) /* get all modem bits */ 

và vì vậy nó không phải là khó để tưởng tượng rằng việc sử dụng một char như các loại cho tôi "cờ" var có thể gây ra hành vi không thể đoán trước.

1

Bạn có thể tạo một plugin AppleScript, plugin này sẽ tự động chạy vào những thời điểm cụ thể hoặc trong quá trình đăng nhập của bạn hoặc liên tục ở chế độ nền.

AppleScript có thể chạy mã đầu cuối. Vì vậy, bạn có thể dễ dàng có nó tự động chạy mã get/set mà bạn hiện đang chạy trong Terminal.

Mã cho plugin AppleScript sẽ là một cái gì đó như thế này ::

tell application "Finder" 
    display dialog explanation buttons {"GET", "SET"} default button "GET" 
    if result = {button returned:"GET"} then 
     tell application "Terminal" 
       set status to (do shell script "terminal code for getting the RTS here") 
      end tell 
    else if result = {button returned:"SET"} then 
      tell application "Terminal" 
       set status to (do shell script "terminal code for setting the RTS here") 
      end tell 
    end if 
end tell