2017-04-26 8 views
1

XCB를 사용하여 X11 창에 다른 속성 중에서 해당 프로세스의 PID를 묻습니다.존재하지 않는 _NET_WM_PID에 대해 xcb_get_property_reply에서 오류를 가져올 수 없습니다.

xcb_window_t wid; 
xcb_connection_t * conn; 

template <typename T> 
T get_property(xcb_atom_t property, xcb_atom_t type, size_t len = sizeof(T)) { 
    xcb_generic_error_t *err = nullptr; // can't use unique_ptr here because get_property_reply overwrites pointer value 

    /* 
    Specifies how many 32-bit multiples of data should be retrieved 
    (e.g. if you set long_length to 4, you will receive 16 bytes of data). 
    */ 
    uint32_t ret_size = 
     len/sizeof(uint32_t) /*integer division, like floor()*/ + 
     !!(len%sizeof(uint32_t)) /*+1 if there was a remainder*/; 

    xcb_get_property_cookie_t cookie = xcb_get_property(
     conn, 0, wid, property, type, 0, ret_size 
    ); 

    std::unique_ptr<xcb_get_property_reply_t,decltype(&free)> reply {xcb_get_property_reply(conn, cookie, &err),&free}; 
    if (!reply) { 
     free(err); 
     throw std::runtime_error("xcb_get_property returned error"); 
    } 

    return *reinterpret_cast<T*>(
     xcb_get_property_value(
      reply.get() 
     ) 
    ); 
} 

xcb_atom_t NET_WM_PID; // initialized using xcb_intern_atom 
// according to libxcb-ewmh, CARDINALs are uint32_t 
pid_t pid = get_property<uint32_t>(NET_WM_PID, XCB_ATOM_CARDINAL); 

오류 처리가 xcb-requests(3)에서 재현 다음과 같이 내 코드는 다양한 문자열이 아닌 속성입니다을 얻을 수 있습니다. 창에 _NET_WM_PID 속성 집합이없는 경우 문제가 발생합니다 (예 : 작업자 파일 관리자). 이 경우 을 xcb_get_property_reply에서 null이 아닌 err으로 변경하는 대신 XCB 요청의 시퀀스 번호와 동일한 숫자 답을 얻습니다. _NET_WM_PID 또는 CARDINAL 유형의 다른 속성이 창에 설정되어 있지 않은지 제대로 확인하려면 어떻게합니까?

답변

1

속성의 부재는 오류가 아닙니다. 속성이 설정되지 않은 경우 응답의 형식, 유형 및 길이는 모두 0입니다. 아마 모든 것을 검사하고 그들이 기대하는 값을 가지고 있는지 확인하기를 원할 것입니다.

+0

고맙습니다! 내 템플릿 함수에서 이제는 요청 된 길이와'xcb_get_property_value_length (reply.get())'가 0이 아닌지 확인하고 그렇지 않으면 던져 버린다. – aitap