/* VM_RESERVESPACE -- Reserve VM space for file data. This directive is * useful if VM is being used but the VM space could not be preallocated * at file access time, e.g., when opening a new file. */ int vm_reservespace (long nbytes) { char buf[SZ_CMDBUF]; int status; if (!vm_initialized) vm_initialize(); if (!vm_enabled || vm_dioenabled) return (-1); if (vm_connect() < 0) return (-1); /* Format and send the file access directive to the VMcache daemon. * The status from the server is returned as an ascii integer value * on the same socket. */ sprintf (buf, "reservespace %ld\n", nbytes); if (vm_debug) fprintf (stderr, "vmclient (%s): %s", vm_client, buf); if (vm_write (vm_server, buf, strlen(buf)) < 0) { vm_shutdown(); return (-1); } if (read (vm_server, buf, SZ_CMDBUF) <= 0) { if (vm_debug) fprintf (stderr, "vmclient (%s): server not responding\n", vm_client); vm_shutdown(); return (-1); } status = atoi (buf); return (status); }
int main(int argc, char* argv[]) { if (!cmdLine.parse(argc, argv)) return 1; if (cmdLine.used("help")) { printHelp(); return 0; } //Establishing connection; if (cmdLine.used("host")) { const std::string param = cmdLine["host"]; std::string h=getDelimitedSubStr(param, 0, ':'); const std::string p=getDelimitedSubStr(param, 1, ':'); if (trim(h).empty()) h="localhost"; size_t port; if (!trim(p).empty()) { if (!checkTypeUnsignedInt(p)) { std::cerr << ERROR_PREFIX << "\'" << trim(p) << "\' is not a valid port number." << std::endl; return 1; } port = parseAsUnsignedInt(p); } else port=VOICEMAN_DEFAULT_PORT; con = vm_connect_inet((char*)h.c_str(), port); if (con == VOICEMAN_BAD_CONNECTION) { std::cerr << ERROR_PREFIX << "ERROR:Could not connect to host \'" << trim(h) << "\' with port " << port << "." << std::endl; return 1; } } else if (cmdLine.used("socket")) { std::string p = cmdLine["socket"]; if (trim(p).empty()) { std::cerr << ERROR_PREFIX << "Missed name of UNIX domain socket." << std::endl; return 1; } if (trim(p) == "-") p = VOICEMAN_DEFAULT_SOCKET; con = vm_connect_unix((char*)p.c_str()); if (con == VOICEMAN_BAD_CONNECTION) { std::cerr << ERROR_PREFIX << "Could not connect to server via UNIX domain socket \'" << p << "\'." << std::endl; return 1; } } else { con = vm_connect(); if (con == VOICEMAN_BAD_CONNECTION) { std::cerr << ERROR_PREFIX << "Could not connect to voicemand with default settings." << std::endl; return 1; } } ConnectionAutoClosing autoClosing(con); struct sigaction sa; sigaction(SIGPIPE, NULL, &sa); sa.sa_handler = sigPipeHandler; sa.sa_flags |= SA_RESTART; sigaction(SIGPIPE, &sa, NULL); //INitial connection parameters; assert(con != VOICEMAN_BAD_CONNECTION); if (cmdLine.used("stop")) vm_stop(con); if (cmdLine.used("pitch")) { const std::string value = trim(cmdLine["pitch"]); if (!checkTypeUnsignedInt(value)) { std::cerr << ERROR_PREFIX << "\'" << value << "\' is not a valid pitch value" << std::endl; return 1; } vm_pitch(con, parseAsUnsignedInt(value)); } if (cmdLine.used("rate")) { const std::string value = trim(cmdLine["rate"]); if (!checkTypeUnsignedInt(value)) { std::cerr << ERROR_PREFIX << "\'" << value << "\' is not a valid rate value" << std::endl; return 1; } vm_rate(con, parseAsUnsignedInt(value)); } if (cmdLine.used("volume")) { const std::string value = trim(cmdLine["volume"]); if (!checkTypeUnsignedInt(value)) { std::cerr << ERROR_PREFIX << "\'" << value << "\' is not a valid volume value" << std::endl; return 1; } vm_volume(con, parseAsUnsignedInt(value)); } if (cmdLine.used("family")) { //Neither trim() nor toLower() functions must be applied to teh value; //Let do it by the server itself; const std::string value = cmdLine["family"]; if (trim(value).empty()) { std::cerr << ERROR_PREFIX << "voice family specification has an empty string value" << std::endl; return 1; } for(std::string::size_type i = 0;i < value.length();i++) if (value[i] == ':' || value[i] == '\n') { std::cerr << ERROR_PREFIX << "voice family specification cannot contain \':\' and new line characters" << std::endl; return 1; } vm_family(con, VOICEMAN_LANG_NONE, (char*)value.c_str()); } if (cmdLine.used("punc")) { const std::string value = trim(toLower(cmdLine["punc"])); if (value == "all") vm_procmode(con, VOICEMAN_PROCMODE_ALL); else if (value == "some") vm_procmode(con, VOICEMAN_PROCMODE_SOME); else if (value == "none") vm_procmode(con, VOICEMAN_PROCMODE_NONE); else { std::cerr << ERROR_PREFIX << "punctuation mode can be only \'all\', \'some\' or \'none\'" << std::endl; return 1; } } if (cmdLine.used("say")) { std::string value; for(size_t i = 0;i < cmdLine.files.size();i++) attachStringWithSpace(value, cmdLine.files[i]); vm_text(con, (char*)encodeUTF8(IO2WString(trim(value))).c_str()); return 0; } if (cmdLine.used("stop")) return 0; std::cout << "VOICEMAN speech system. Version: " << PACKAGE_VERSION << "." << std::endl; std::cout << "Type \'quit\' or press Ctrl+D to leave this prompt." << std::endl; while(1) { std::string l; bool toQuit = 0; std::cout << "voiceman>"; while(1) { char c; if (!std::cin.get(c)) { toQuit = 1; break; } if (c == '\r') continue; if (c == '\n') break; l += c; } if (toQuit || trim(toLower(l)) == "quit") break; process(l); } std::cout << std::endl; std::cout << "Bye!!!" << std::endl; return 0; }
/* VM_INITIALIZE -- Called once per process to open a connection to the * vmcache daemon. The connection is kept open and is used for all * subsequent vmcache requests by the process. */ static void vm_initialize (void) { register int ch; register char *ip, *op; char token[SZ_FNAME], value[SZ_FNAME]; extern char os_process_name[]; char *argp, buf[SZ_FNAME]; /* Extract the process name minus the file path. */ for (ip=os_process_name, op=vm_client; (*op++ = (ch = *ip)); ip++) { if (ch == '/') op = vm_client; } /* Get the server socket port if set in the user environment. */ if ((argp = getenv (ENV_VMPORT))) vm_port = atoi (argp); /* Get the VM client parameters if an initialization string is * defined in the user environment. */ if ((argp = getenv (ENV_VMCLIENT))) { while (getstr (&argp, buf, SZ_FNAME, ',') > 0) { char *modchar, *cp = buf; int haveval; /* Parse "token[=value]" */ if (getstr (&cp, token, SZ_FNAME, '=') <= 0) continue; haveval = (getstr (&cp, value, SZ_FNAME, ',') > 0); if (strcmp (token, "enable") == 0) { vm_enabled = 1; } else if (strcmp (token, "disable") == 0) { vm_enabled = 0; } else if (strcmp (token, "debug") == 0) { vm_debug = 1; if (haveval) vm_debug = strtol (value, &modchar, 10); } else if (strcmp (token, "threshold") == 0 && haveval) { vm_threshold = strtol (value, &modchar, 10); if (*modchar == 'k' || *modchar == 'K') vm_threshold *= 1024; else if (*modchar == 'm' || *modchar == 'M') vm_threshold *= (1024 * 1024); } else if (strcmp (token, "directio") == 0) { vm_dioenabled = 1; if (haveval) { dio_threshold = strtol (value, &modchar, 10); if (*modchar == 'k' || *modchar == 'K') dio_threshold *= 1024; else if (*modchar == 'm' || *modchar == 'M') dio_threshold *= (1024 * 1024); } } } } if (vm_debug) { fprintf (stderr, "vmclient (%s): vm=%d dio=%d ", vm_client, vm_enabled, vm_dioenabled); fprintf (stderr, "vmth=%d dioth=%d port=%d\n", vm_threshold, dio_threshold, vm_port); } /* Attempt to open a connection to the VMcache server. */ if (vm_enabled && !vm_dioenabled) vm_connect(); atexit (vm_shutdown); vm_initialized++; }
/* VM_DELETE -- Delete any VM space used by a file, e.g., because the file * is being physically deleted. This should be called before the file is * actually deleted so that the cache can determine its device and inode * values. */ int vm_delete (char *fname, int force) { struct stat st; char buf[SZ_COMMAND]; char pathname[SZ_PATHNAME]; int status = 0; /* One-time process initialization. */ if (!vm_initialized) vm_initialize(); if (stat (fname, &st) < 0) { status = -1; goto done; } /* If VMcache is not being used we are done. */ if (vm_dioenabled && (st.st_size >= dio_threshold)) goto done; else if (!vm_enabled || st.st_size < vm_threshold) goto done; /* Don't delete the VM space used by the file if it has hard links * and only a link is being deleted (force flag will override). */ if (st.st_nlink > 1 && !force) goto done; /* Connect to the VMcache server if not already connected. */ if (!vm_server) if (vm_connect() < 0) { status = -1; goto done; } /* Format and send the delete directive to the VMcache daemon. * The status from the server is returned as an ascii integer value * on the same socket. */ sprintf (buf, "delete %s\n", realpath(fname,pathname)); if (vm_write (vm_server, buf, strlen(buf)) < 0) { vm_shutdown(); status = -1; goto done; } if (read (vm_server, buf, SZ_CMDBUF) <= 0) { if (vm_debug) fprintf (stderr, "vmclient (%s): server not responding\n", vm_client); vm_shutdown(); status = -1; goto done; } status = atoi (buf); done: if (vm_debug) fprintf (stderr, "vmclient (%s): delete `%s' -> %d\n", vm_client, fname, status); return (status < 0 ? -1 : status); }
/* VM_ACCESS -- Access a file via the VM subsystem. A return value of 1 * indicates that the file is (or will be) "cached" in virtual memory, i.e., * that normal virtual memory file system (normal file i/o) should be used * to access the file. A return value of 0 indicates that direct i/o should * be used to access the file, bypassing the virtual memory file system. */ int vm_access (char *fname, int mode) { struct stat st; char *modestr = NULL, buf[SZ_COMMAND]; char pathname[SZ_PATHNAME]; int status; /* One-time process initialization. */ if (!vm_initialized) vm_initialize(); if (stat (fname, &st) < 0) { status = DEF_ACCESSVAL; goto done; } /* If directio is enabled and the file exceeds the directio threshold * use directio to access the file (access=0). If vmcache is * disabled use normal VM-based i/o to access the file (access=1). * If VMcache is enabled we still only use it if the file size * exceeds vm_threshold. */ if (vm_dioenabled) { status = (st.st_size >= dio_threshold) ? 0 : 1; goto done; } else if (!vm_enabled || st.st_size < vm_threshold) { status = DEF_ACCESSVAL; goto done; } /* Use of VMcache is enabled and the file equals or exceeds the * minimum size threshold. Initialization has already been performed. * Open a VMcache daemon server connection if we don't already have * one. If the server connection fails we are done, but we will try * to open a connection again in the next file access. */ if (!vm_server) if (vm_connect() < 0) { status = DEF_ACCESSVAL; goto done; } /* Compute the mode string for the server request. */ switch (mode) { case READ_ONLY: modestr = "ro"; break; case NEW_FILE: case READ_WRITE: case APPEND: modestr = "rw"; break; } /* Format and send the file access directive to the VMcache daemon. * The status from the server is returned as an ascii integer value * on the same socket. */ sprintf (buf, "access %s %s\n", realpath(fname,pathname), modestr); if (vm_write (vm_server, buf, strlen(buf)) < 0) { vm_shutdown(); status = DEF_ACCESSVAL; goto done; } if (read (vm_server, buf, SZ_CMDBUF) <= 0) { if (vm_debug) fprintf (stderr, "vmclient (%s): server not responding\n", vm_client); vm_shutdown(); status = DEF_ACCESSVAL; goto done; } status = atoi (buf); done: if (vm_debug) fprintf (stderr, "vmclient (%s): access `%s' -> %d\n", vm_client, fname, status); return (status < 0 ? DEF_ACCESSVAL : status); }