Commit 28ac456c3de0a6650d31571963de6248738bfdad
1 parent
4a436cde
Exists in
master
and in
1 other branch
Working on IPC api.
Showing
8 changed files
with
373 additions
and
14 deletions
Show diff stats
client/src/core/abstract.cc
| ... | ... | @@ -101,12 +101,17 @@ |
| 101 | 101 | } |
| 102 | 102 | |
| 103 | 103 | /// @brief Converte charset. |
| 104 | - std::string Abstract::Session::convertCharset(iconv_t &converter, const char *str) { | |
| 104 | + std::string Abstract::Session::convertCharset(iconv_t &converter, const char *str, int length) { | |
| 105 | 105 | |
| 106 | 106 | std::string rc; |
| 107 | 107 | |
| 108 | 108 | #ifdef HAVE_ICONV |
| 109 | - size_t in = strlen(str); | |
| 109 | + size_t in; | |
| 110 | + | |
| 111 | + if(length < 0) | |
| 112 | + in = (size_t) strlen(str); | |
| 113 | + else | |
| 114 | + in = (size_t) length; | |
| 110 | 115 | |
| 111 | 116 | if(in && converter != (iconv_t)(-1)) { |
| 112 | 117 | |
| ... | ... | @@ -136,13 +141,13 @@ |
| 136 | 141 | } |
| 137 | 142 | |
| 138 | 143 | /// @brief Converte string recebida do host para o charset atual. |
| 139 | - std::string Abstract::Session::convertFromHost(const char *str) const { | |
| 140 | - return convertCharset(const_cast<Abstract::Session *>(this)->converter.local,str); | |
| 144 | + std::string Abstract::Session::convertFromHost(const char *str, int length) const { | |
| 145 | + return convertCharset(const_cast<Abstract::Session *>(this)->converter.local,str,length); | |
| 141 | 146 | } |
| 142 | 147 | |
| 143 | 148 | /// @brief Converte string do charset atual para o charset do host. |
| 144 | - std::string Abstract::Session::convertToHost(const char *str) const { | |
| 145 | - return convertCharset(const_cast<Abstract::Session *>(this)->converter.host,str); | |
| 149 | + std::string Abstract::Session::convertToHost(const char *str, int length) const { | |
| 150 | + return convertCharset(const_cast<Abstract::Session *>(this)->converter.host,str,length); | |
| 146 | 151 | } |
| 147 | 152 | |
| 148 | 153 | ... | ... |
client/src/core/host.cc
| ... | ... | @@ -37,6 +37,13 @@ |
| 37 | 37 | */ |
| 38 | 38 | |
| 39 | 39 | #include <ipc-client-internals.h> |
| 40 | + #include <string> | |
| 41 | + #include <cstring> | |
| 42 | + #include <iostream> | |
| 43 | + | |
| 44 | + using std::string; | |
| 45 | + using std::clog; | |
| 46 | + using std::endl; | |
| 40 | 47 | |
| 41 | 48 | /*---[ Implement ]----------------------------------------------------------------------------------*/ |
| 42 | 49 | |
| ... | ... | @@ -199,6 +206,276 @@ |
| 199 | 206 | return *this; |
| 200 | 207 | } |
| 201 | 208 | |
| 209 | + /// @brief Request print | |
| 210 | + Host & Host::print(LIB3270_CONTENT_OPTION option) { | |
| 211 | + throw std::system_error(ENOTSUP, std::system_category()); | |
| 212 | + } | |
| 213 | + | |
| 214 | + void Host::input(const char *text, size_t sz) { | |
| 215 | + | |
| 216 | +#ifdef DEBUG | |
| 217 | + { | |
| 218 | + string str = string(text,sz); | |
| 219 | + clog << __FUNCTION__ << "(\"" << str << "\")" << endl; | |
| 220 | + } | |
| 221 | +#endif // DEBUG | |
| 222 | + | |
| 223 | + this->session->input(text, sz); | |
| 224 | + | |
| 225 | + } | |
| 226 | + | |
| 227 | + | |
| 228 | + Host & Host::input(const char *text, const char control_char) { | |
| 229 | + | |
| 230 | + for(const char * ptr = strchr(text,control_char); ptr; ptr = strchr(text,control_char)) { | |
| 231 | + | |
| 232 | + input(text,(size_t) (ptr-text) ); | |
| 233 | + | |
| 234 | + switch(*(++ptr)) { | |
| 235 | + case 'P': // Print | |
| 236 | + print(); | |
| 237 | + break; | |
| 238 | + | |
| 239 | + case 'E': // Enter | |
| 240 | + push(ENTER); | |
| 241 | + break; | |
| 242 | + | |
| 243 | + case 'F': // Erase EOF | |
| 244 | + push(ERASE_EOF); | |
| 245 | + break; | |
| 246 | + | |
| 247 | + case '1': // PF1 | |
| 248 | + push(PF_1); | |
| 249 | + break; | |
| 250 | + | |
| 251 | + case '2': // PF2 | |
| 252 | + push(PF_2); | |
| 253 | + break; | |
| 254 | + | |
| 255 | + case '3': // PF3 | |
| 256 | + push(PF_3); | |
| 257 | + break; | |
| 258 | + | |
| 259 | + case '4': // PF4 | |
| 260 | + push(PF_4); | |
| 261 | + break; | |
| 262 | + | |
| 263 | + case '5': // PF5 | |
| 264 | + push(PF_5); | |
| 265 | + break; | |
| 266 | + | |
| 267 | + case '6': // PF6 | |
| 268 | + push(PF_6); | |
| 269 | + break; | |
| 270 | + | |
| 271 | + case '7': // PF7 | |
| 272 | + push(PF_7); | |
| 273 | + break; | |
| 274 | + | |
| 275 | + case '8': // PF8 | |
| 276 | + push(PF_8); | |
| 277 | + break; | |
| 278 | + | |
| 279 | + case '9': // PF9 | |
| 280 | + push(PF_9); | |
| 281 | + break; | |
| 282 | + | |
| 283 | + case 'a': // PF10 | |
| 284 | + push(PF_10); | |
| 285 | + break; | |
| 286 | + | |
| 287 | + case 'b': // PF11 | |
| 288 | + push(PF_11); | |
| 289 | + break; | |
| 290 | + | |
| 291 | + case 'c': // PF12 | |
| 292 | + push(PF_12); | |
| 293 | + break; | |
| 294 | + | |
| 295 | + case 'd': // PF13 | |
| 296 | + push(PF_13); | |
| 297 | + break; | |
| 298 | + | |
| 299 | + case 'e': // PF14 | |
| 300 | + push(PF_14); | |
| 301 | + break; | |
| 302 | + | |
| 303 | + case 'f': // PF15 | |
| 304 | + push(PF_15); | |
| 305 | + break; | |
| 306 | + | |
| 307 | + case 'g': // PF16 | |
| 308 | + push(PF_16); | |
| 309 | + break; | |
| 310 | + | |
| 311 | + case 'h': // PF17 | |
| 312 | + push(PF_17); | |
| 313 | + break; | |
| 314 | + | |
| 315 | + case 'i': // PF18 | |
| 316 | + push(PF_18); | |
| 317 | + break; | |
| 318 | + | |
| 319 | + case 'j': // PF19 | |
| 320 | + push(PF_19); | |
| 321 | + break; | |
| 322 | + | |
| 323 | + case 'k': // PF20 | |
| 324 | + push(PF_20); | |
| 325 | + break; | |
| 326 | + | |
| 327 | + case 'l': // PF21 | |
| 328 | + push(PF_21); | |
| 329 | + break; | |
| 330 | + | |
| 331 | + case 'm': // PF22 | |
| 332 | + push(PF_22); | |
| 333 | + break; | |
| 334 | + | |
| 335 | + case 'n': // PF23 | |
| 336 | + push(PF_23); | |
| 337 | + break; | |
| 338 | + | |
| 339 | + case 'o': // PF24 | |
| 340 | + push(PF_24); | |
| 341 | + break; | |
| 342 | + | |
| 343 | + case '@': // Send '@' character | |
| 344 | + input("@",(size_t) 1); | |
| 345 | + break; | |
| 346 | + | |
| 347 | + case 'x': // PA1 | |
| 348 | + push(PA_1); | |
| 349 | + break; | |
| 350 | + | |
| 351 | + case 'y': // PA2 | |
| 352 | + push(PA_2); | |
| 353 | + break; | |
| 354 | + | |
| 355 | + case 'z': // PA3 | |
| 356 | + push(PA_3); | |
| 357 | + break; | |
| 358 | + | |
| 359 | + case 'B': // PC_LEFTTAB = "@B" | |
| 360 | + break; | |
| 361 | + | |
| 362 | + case 'T': // PC_RIGHTTAB = "@T" | |
| 363 | + break; | |
| 364 | + | |
| 365 | + case 'N': // PC_NEWLINE = "@N" | |
| 366 | + push(NEWLINE); | |
| 367 | + break; | |
| 368 | + | |
| 369 | + case 'C': // PC_CLEAR = "@C" | |
| 370 | + push(CLEAR); | |
| 371 | + break; | |
| 372 | + | |
| 373 | + case 'D': // PC_DELETE = "@D" | |
| 374 | + push(CHAR_DELETE); | |
| 375 | + break; | |
| 376 | + | |
| 377 | + case 'H': // PC_HELP = "@H" | |
| 378 | + break; | |
| 379 | + | |
| 380 | + case 'I': // PC_INSERT = "@I" | |
| 381 | + break; | |
| 382 | + | |
| 383 | + case 'L': // PC_CURSORLEFT = "@L" | |
| 384 | + break; | |
| 385 | + | |
| 386 | + case 'R': // PC_RESET = "@R" | |
| 387 | + push(KYBD_RESET); | |
| 388 | + break; | |
| 389 | + | |
| 390 | + case 'U': // PC_CURSORUP = "@U" | |
| 391 | + break; | |
| 392 | + | |
| 393 | + case 'V': // PC_CURSORDOWN = "@V" | |
| 394 | + break; | |
| 395 | + | |
| 396 | + case 'Z': // PC_CURSORRIGHT = "@Z" | |
| 397 | + break; | |
| 398 | + | |
| 399 | + case '0': // PC_HOME = "@0" | |
| 400 | + break; | |
| 401 | + | |
| 402 | + case 'p': // PC_PLUSKEY = "@p" | |
| 403 | + break; | |
| 404 | + | |
| 405 | + case 'q': // PC_END = "@q" | |
| 406 | + break; | |
| 407 | + | |
| 408 | + case 's': // PC_SCRLK = "@s" | |
| 409 | + break; | |
| 410 | + | |
| 411 | + case 't': // PC_NUMLOCK = "@t" | |
| 412 | + break; | |
| 413 | + | |
| 414 | + case 'u': // PC_PAGEUP = "@u" | |
| 415 | + break; | |
| 416 | + | |
| 417 | + case 'v': // PC_PAGEDOWN = "@v" | |
| 418 | + break; | |
| 419 | + | |
| 420 | + case '/': // PC_OVERRUNOFQUEUE = "@/" ' Queue overflow, used in Get Key only | |
| 421 | + break; | |
| 422 | + | |
| 423 | + case '$': // PC_ALTCURSOR = "@$" ' Presentation Manager only, unused in VB environment | |
| 424 | + break; | |
| 425 | + | |
| 426 | + case '<': // PC_BACKSPACE = "@<" | |
| 427 | + push(BACKSPACE); | |
| 428 | + break; | |
| 429 | + | |
| 430 | + | |
| 431 | + // Global Const PC_TEST = "@A@C" | |
| 432 | + // Global Const PC_WORDDELETE = "@A@D" | |
| 433 | + // Global Const PC_FIELDEXIT = "@A@E" | |
| 434 | + // Global Const PC_ERASEINPUT = "@A@F" | |
| 435 | + // Global Const PC_SYSTEMREQUEST = "@A@H" | |
| 436 | + // Global Const PC_INSERTTOGGLE = "@A@I" | |
| 437 | + // Global Const PC_CURSORSELECT = "@A@J" | |
| 438 | + // Global Const PC_CURSLEFTFAST = "@A@L" | |
| 439 | + // Global Const PC_GETCURSOR = "@A@N" | |
| 440 | + // Global Const PC_LOCATECURSOR = "@A@O" | |
| 441 | + // Global Const PC_ATTENTION = "@A@Q" | |
| 442 | + // Global Const PC_DEVICECANCEL = "@A@R" | |
| 443 | + // Global Const PC_PRINTPS = "@A@T" | |
| 444 | + // Global Const PC_CURSUPFAST = "@A@U" | |
| 445 | + // Global Const PC_CURSDOWNFAST = "@A@V" | |
| 446 | + // Global Const PC_HEX = "@A@X" | |
| 447 | + // Global Const PC_FUNCTIONKEY = "@A@Y" | |
| 448 | + // Global Const PC_CURSRIGHTFAST = "@A@Z" | |
| 449 | + | |
| 450 | + // Global Const PC_REVERSEVIDEO = "@A@9" | |
| 451 | + // Global Const PC_UNDERSCORE = "@A@b" | |
| 452 | + // Global Const PC_BLINK = "@A@c" | |
| 453 | + // Global Const PC_RED = "@A@d"BACKSPACE | |
| 454 | + // Global Const PC_PINK = "@A@e" | |
| 455 | + // Global Const PC_GREEN = "@A@f" | |
| 456 | + // Global Const PC_YELLOW = "@A@g" | |
| 457 | + // Global Const PC_BLUE = "@A@h" | |
| 458 | + // Global Const PC_TURQOISE = "@A@i" | |
| 459 | + // Global Const PC_WHITE = "@A@j" | |
| 460 | + // Global Const PC_RSTHOSTCOLORS = "@A@l" | |
| 461 | + // Global Const PC_PRINTPC = "@A@t" | |
| 462 | + | |
| 463 | + // Global Const PC_FIELDMINUS = "@A@-" | |
| 464 | + // Global Const PC_FIELDPLUS = "@A@+" | |
| 465 | + } | |
| 466 | + | |
| 467 | + text = (ptr+1); | |
| 468 | + } | |
| 469 | + | |
| 470 | + if(*text) { | |
| 471 | + input(text,strlen(text)); | |
| 472 | + } | |
| 473 | + | |
| 474 | + return *this; | |
| 475 | + | |
| 476 | + } | |
| 477 | + | |
| 478 | + | |
| 202 | 479 | |
| 203 | 480 | } |
| 204 | 481 | ... | ... |
client/src/include/ipc-client-internals.h
| ... | ... | @@ -121,7 +121,7 @@ |
| 121 | 121 | #endif |
| 122 | 122 | |
| 123 | 123 | /// @brief Converte charset. |
| 124 | - static std::string convertCharset(iconv_t &converter, const char *str); | |
| 124 | + static std::string convertCharset(iconv_t &converter, const char *str, int length); | |
| 125 | 125 | |
| 126 | 126 | protected: |
| 127 | 127 | |
| ... | ... | @@ -135,10 +135,10 @@ |
| 135 | 135 | void setCharSet(const char *remote, const char *local = SYSTEM_CHARSET); |
| 136 | 136 | |
| 137 | 137 | /// @brief Converte string recebida do host para o charset atual. |
| 138 | - std::string convertFromHost(const char *str) const; | |
| 138 | + std::string convertFromHost(const char *str, int length = -1) const; | |
| 139 | 139 | |
| 140 | 140 | /// @brief Converte string do charset atual para o charset do host. |
| 141 | - std::string convertToHost(const char *str) const; | |
| 141 | + std::string convertToHost(const char *str, int length = -1) const; | |
| 142 | 142 | |
| 143 | 143 | }; |
| 144 | 144 | |
| ... | ... | @@ -199,6 +199,8 @@ |
| 199 | 199 | TN3270::Session & pfkey(unsigned short value); |
| 200 | 200 | TN3270::Session & pakey(unsigned short value); |
| 201 | 201 | |
| 202 | + TN3270::Session & input(const char *text, size_t length) override; | |
| 203 | + | |
| 202 | 204 | /// @brief Set field at current posicion, jumps to next writable field. |
| 203 | 205 | TN3270::Session & push(const char *text) override; |
| 204 | 206 | |
| ... | ... | @@ -367,6 +369,8 @@ |
| 367 | 369 | TN3270::Session & pfkey(unsigned short value); |
| 368 | 370 | TN3270::Session & pakey(unsigned short value); |
| 369 | 371 | |
| 372 | + TN3270::Session & input(const char *text, size_t length) override; | |
| 373 | + | |
| 370 | 374 | /// @brief Set field at current posicion, jumps to next writable field. |
| 371 | 375 | TN3270::Session & push(const char *text) override; |
| 372 | 376 | ... | ... |
client/src/session/local/session.cc
| ... | ... | @@ -228,16 +228,51 @@ |
| 228 | 228 | /// @brief Set field at current position, jumps to next writable field. |
| 229 | 229 | TN3270::Session & Local::Session::push(const char *text) { |
| 230 | 230 | std::lock_guard<std::mutex> lock(sync); |
| 231 | + | |
| 232 | + string converted = convertToHost(text); | |
| 233 | + | |
| 234 | + int rc = lib3270_input_string(this->hSession, (unsigned char *) converted.c_str(), converted.size()); | |
| 235 | + if(rc) { | |
| 236 | + throw std::system_error(errno, std::system_category()); | |
| 237 | + } | |
| 238 | + | |
| 239 | + return *this; | |
| 240 | + } | |
| 241 | + | |
| 242 | + TN3270::Session & Local::Session::input(const char *text, size_t length) { | |
| 243 | + std::lock_guard<std::mutex> lock(sync); | |
| 244 | + | |
| 245 | + string converted = convertToHost(text,length); | |
| 246 | + | |
| 247 | + int rc = lib3270_input_string(this->hSession, (unsigned char *) converted.c_str(), converted.size()); | |
| 248 | + if(rc) { | |
| 249 | + throw std::system_error(errno, std::system_category()); | |
| 250 | + } | |
| 251 | + | |
| 231 | 252 | return *this; |
| 232 | 253 | } |
| 233 | 254 | |
| 234 | 255 | TN3270::Session & Local::Session::push(int baddr, const std::string &text) { |
| 235 | 256 | std::lock_guard<std::mutex> lock(sync); |
| 257 | + | |
| 258 | + string converted = convertToHost(text.c_str(),text.size()); | |
| 259 | + | |
| 260 | + if(lib3270_set_string_at_address(this->hSession,baddr,(unsigned char *) converted.c_str(),converted.length()) < 0) { | |
| 261 | + throw std::system_error(errno, std::system_category()); | |
| 262 | + } | |
| 263 | + | |
| 236 | 264 | return *this; |
| 237 | 265 | } |
| 238 | 266 | |
| 239 | 267 | TN3270::Session & Local::Session::push(int row, int col, const std::string &text) { |
| 240 | 268 | std::lock_guard<std::mutex> lock(sync); |
| 269 | + | |
| 270 | + string converted = convertToHost(text.c_str(),text.size()); | |
| 271 | + | |
| 272 | + if(lib3270_set_string_at(this->hSession,row,col,(unsigned char *) converted.c_str())) { | |
| 273 | + throw std::system_error(errno, std::system_category()); | |
| 274 | + } | |
| 275 | + | |
| 241 | 276 | return *this; |
| 242 | 277 | } |
| 243 | 278 | ... | ... |
client/src/session/remote/session.cc
| ... | ... | @@ -125,6 +125,11 @@ |
| 125 | 125 | |
| 126 | 126 | } |
| 127 | 127 | |
| 128 | + TN3270::Session & IPC::Session::input(const char *text, size_t length) { | |
| 129 | + | |
| 130 | + return *this; | |
| 131 | + } | |
| 132 | + | |
| 128 | 133 | /// @brief Set field at current position, jumps to next writable field. |
| 129 | 134 | TN3270::Session & IPC::Session::push(const char *text) { |
| 130 | 135 | ... | ... |
client/src/testprogram/testprogram.cc
| ... | ... | @@ -39,7 +39,6 @@ |
| 39 | 39 | #include <getopt.h> |
| 40 | 40 | #include <cstdlib> |
| 41 | 41 | #include <lib3270/ipc.h> |
| 42 | - #include <delayimp.h> | |
| 43 | 42 | |
| 44 | 43 | using namespace std; |
| 45 | 44 | |
| ... | ... | @@ -87,11 +86,16 @@ |
| 87 | 86 | << "\tProgram message is " << host.getProgramMessage() |
| 88 | 87 | << std::endl; |
| 89 | 88 | |
| 90 | - // host.connect(getenv("LIB3270_DEFAULT_HOST")); | |
| 89 | + | |
| 90 | + // host.input("test@0another line"); | |
| 91 | + | |
| 92 | + /* | |
| 93 | + host.connect(); | |
| 91 | 94 | |
| 92 | 95 | if(host) { |
| 93 | 96 | cout << host << endl; |
| 94 | 97 | } |
| 98 | + */ | |
| 95 | 99 | |
| 96 | 100 | } catch(const std::exception &e) { |
| 97 | 101 | ... | ... |
common/src/include/lib3270/ipc.h
| ... | ... | @@ -154,7 +154,19 @@ |
| 154 | 154 | PF_9, |
| 155 | 155 | PF_10, |
| 156 | 156 | PF_11, |
| 157 | - PF_12 | |
| 157 | + PF_12, | |
| 158 | + PF_13, | |
| 159 | + PF_14, | |
| 160 | + PF_15, | |
| 161 | + PF_16, | |
| 162 | + PF_17, | |
| 163 | + PF_18, | |
| 164 | + PF_19, | |
| 165 | + PF_20, | |
| 166 | + PF_21, | |
| 167 | + PF_22, | |
| 168 | + PF_23, | |
| 169 | + PF_24 | |
| 158 | 170 | }; |
| 159 | 171 | |
| 160 | 172 | /// @brief PF Keys |
| ... | ... | @@ -264,6 +276,9 @@ |
| 264 | 276 | return push(text.c_str()); |
| 265 | 277 | } |
| 266 | 278 | |
| 279 | + /// @brief Input string. | |
| 280 | + virtual Session & input(const char *text, size_t length) = 0; | |
| 281 | + | |
| 267 | 282 | /// @brief Set cursor address. |
| 268 | 283 | virtual TN3270::Session & setCursorPosition(unsigned short addr) = 0; |
| 269 | 284 | |
| ... | ... | @@ -276,7 +291,7 @@ |
| 276 | 291 | /// @brief Send PF. |
| 277 | 292 | virtual Session & pfkey(unsigned short value) = 0; |
| 278 | 293 | |
| 279 | - /// @brief Send PF. | |
| 294 | + /// @brief Send PA. | |
| 280 | 295 | virtual Session & pakey(unsigned short value) = 0; |
| 281 | 296 | |
| 282 | 297 | virtual Session & push(int baddr, const std::string &text) = 0; |
| ... | ... | @@ -327,6 +342,8 @@ |
| 327 | 342 | /// @brief Write error to log file. |
| 328 | 343 | void error(const char *fmt, ...) const; |
| 329 | 344 | |
| 345 | + void input(const char *text, size_t sz); | |
| 346 | + | |
| 330 | 347 | public: |
| 331 | 348 | Host(const char *id = nullptr, const char *url = nullptr, time_t timeout = DEFAULT_TIMEOUT); |
| 332 | 349 | ~Host(); |
| ... | ... | @@ -404,8 +421,20 @@ |
| 404 | 421 | /// @brief Send PA. |
| 405 | 422 | Host & pakey(unsigned short value); |
| 406 | 423 | |
| 424 | + /// @brief Request print | |
| 425 | + Host & print(LIB3270_CONTENT_OPTION option = LIB3270_CONTENT_ALL); | |
| 426 | + | |
| 407 | 427 | // Set contents. |
| 408 | 428 | |
| 429 | + /// @brief Input string. | |
| 430 | + /// | |
| 431 | + /// Input the supplied string processing commands delimited by the control char in | |
| 432 | + /// the same way of the old HLLAPI. | |
| 433 | + /// | |
| 434 | + /// @param text String with the text to input. | |
| 435 | + /// @param control_char Control character used to identify commands. | |
| 436 | + Host & input(const char *text, const char control_char = '@'); | |
| 437 | + | |
| 409 | 438 | /// @brief Set field at current posicion, jumps to next writable field. |
| 410 | 439 | inline Host & push(const char *text) { |
| 411 | 440 | session->push(text); | ... | ... |
server/src/core/methods.c
| ... | ... | @@ -62,7 +62,7 @@ GVariant * ipc3270_method_call(GObject *object, const gchar *method_name, GVaria |
| 62 | 62 | g_variant_get(parameters, "(&s)", &text); |
| 63 | 63 | |
| 64 | 64 | g_autofree gchar * converted = ipc3270_convert_output_string(object, text, error); |
| 65 | - if(lib3270_input_string(hSession,(const unsigned char *) converted) < 0) | |
| 65 | + if(lib3270_input_string(hSession,(const unsigned char *) converted, -1)) | |
| 66 | 66 | { |
| 67 | 67 | // Failed! |
| 68 | 68 | debug("%s failed: %s",method_name,strerror(errno)); | ... | ... |