1/* 2 * Copyright 2005, Ingo Weinhold, bonefish@users.sf.net. 3 * Distributed under the terms of the MIT License. 4 */ 5 6#include <errno.h> 7#include <stdio.h> 8#include <string.h> 9#include <unistd.h> 10#include <sys/socket.h> 11#include <sys/un.h> 12 13#include "fs_shell_command.h" 14#include "fs_shell_command_unix.h" 15 16int 17send_external_command(const char *command, int *result) 18{ 19 external_command_message message; 20 strncpy(message.command, command, sizeof(message.command)); 21 22 // create a socket 23 int fd = socket(AF_UNIX, SOCK_STREAM, 0); 24 if (fd < 0) 25 return errno; 26 27 // connect to the fs_shell 28 sockaddr_un addr; 29 addr.sun_family = AF_UNIX; 30 strcpy(addr.sun_path, kFSShellCommandSocketAddress); 31 int addrLen = addr.sun_path + strlen(addr.sun_path) + 1 - (char*)&addr; 32 if (connect(fd, (sockaddr*)&addr, addrLen) < 0) { 33 close(fd); 34 return errno; 35 } 36 37 // send the command message 38 int toWrite = sizeof(message); 39 const char *messageBuffer = (char*)&message; 40 ssize_t bytesWritten; 41 do { 42 bytesWritten = write(fd, messageBuffer, toWrite); 43 if (bytesWritten > 0) { 44 messageBuffer += bytesWritten; 45 toWrite -= bytesWritten; 46 } 47 } while (toWrite > 0 && !(bytesWritten < 0 && errno != EINTR)); 48 49 // close connection on error 50 if (bytesWritten < 0) { 51 fprintf(stderr, "Writing to fs_shell failed: %s\n", strerror(errno)); 52 close(fd); 53 return errno; 54 } 55 56 // read the reply 57 external_command_reply reply; 58 int toRead = sizeof(reply); 59 char *replyBuffer = (char*)&reply; 60 while (toRead > 0) { 61 int bytesRead = read(fd, replyBuffer, toRead); 62 if (bytesRead < 0) { 63 if (errno == EINTR) { 64 continue; 65 } else { 66 fprintf(stderr, "Failed to read reply from fs_shell: %s\n", 67 strerror(errno)); 68 close(fd); 69 return errno; 70 } 71 } 72 73 if (bytesRead == 0) { 74 fprintf(stderr, "Unexpected end of fs_shell reply. Was still " 75 "expecting %d bytes\n", toRead); 76 return EPIPE; 77 } 78 79 replyBuffer += bytesRead; 80 toRead -= bytesRead; 81 } 82 83 *result = reply.error; 84 return 0; 85} 86 87