1 /* 2 * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 #include <stdio.h> 7 #include <string.h> 8 9 #include <OS.h> 10 11 #include "external_commands.h" 12 #include "fs_shell_command_beos.h" 13 14 15 static port_id sReplyPort = -1; 16 17 18 static port_id 19 get_command_port() 20 { 21 static port_id port = -1; 22 static bool initialized = false; 23 24 if (!initialized) { 25 port = create_port(10, kFSShellCommandPort); 26 initialized = true; 27 } 28 29 return port; 30 } 31 32 33 bool 34 FSShell::get_external_command(char *input, int len) 35 { 36 // get/create the port 37 port_id port = get_command_port(); 38 if (port < 0) { 39 fprintf(stderr, "Error: Failed to create command port: %s\n", 40 strerror(port)); 41 return false; 42 } 43 44 while (true) { 45 // read a message 46 char _message[sizeof(external_command_message) + kMaxCommandLength]; 47 external_command_message* message = (external_command_message*)_message; 48 ssize_t bytesRead; 49 do { 50 int32 code; 51 bytesRead = read_port(port, &code, message, sizeof(_message)); 52 } while (bytesRead == B_INTERRUPTED); 53 54 if (bytesRead < 0) { 55 fprintf(stderr, "Error: Reading from port failed: %s\n", 56 strerror(bytesRead)); 57 return false; 58 } 59 60 // get the len of the command 61 int commandLen = _message + bytesRead - message->command; 62 if (commandLen <= 1) { 63 fprintf(stderr, "Error: No command given.\n"); 64 continue; 65 } 66 if (commandLen > len) { 67 fprintf(stderr, "Error: Command too long. Ignored.\n"); 68 continue; 69 } 70 71 // copy the command 72 memcpy(input, message->command, commandLen); 73 input[len - 1] = '\0'; // always NULL-terminate 74 sReplyPort = message->reply_port; 75 return true; 76 } 77 } 78 79 80 void 81 FSShell::reply_to_external_command(int result) 82 { 83 if (sReplyPort >= 0) { 84 // prepare the message 85 external_command_reply reply; 86 reply.error = result; 87 88 // send the reply 89 status_t error; 90 do { 91 error = write_port(sReplyPort, 0, &reply, sizeof(reply)); 92 } while (error == B_INTERRUPTED); 93 sReplyPort = -1; 94 95 if (error != B_OK) { 96 fprintf(stderr, "Error: Failed to send command result to reply " 97 "port: %s\n", strerror(error)); 98 } 99 } 100 } 101 102 103 void 104 FSShell::external_command_cleanup() 105 { 106 // The port will be deleted automatically when the team exits. 107 } 108