/* * $Id: main.cpp,v 1.15 2006/10/20 05:29:02 ozawa Exp $ * * Copyright 2003- ONGS Inc. All rights reserved. * * author: Masanori OZAWA (ozawa@ongs.co.jp) * version: $Revision: 1.15 $ * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY ONGS INC ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL ONGS INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * The views and conclusions contained in the software and documentation are * those of the authors and should not be interpreted as representing official * policies, either expressed or implied, of the ONGS Inc. * */ #include "include/fusenshi.h" #include "include/propertydata.h" #include "misc/resourceloader.h" #include "gdk/gdk.h" #include #include #include static int parseInt(const char *pVal, char **ppEndPos); static void print_usage(); /** * メイン処理 * * @author $Author: ozawa $ * @version $Revision: 1.15 $ */ int main(int argc, char *argv[]) { char opt = 0; char *tmp = NULL; int semid = -1; int fdes1[2] = {0, 0}; int fdes2[2] = {0, 0}; FIO_GLOBAL_PROP fioProp = { false }; WND_GLOBAL_PROP wndProp = { 0, 0, WND_TYPE_NORMAL }; #ifdef ENABLE_NLS bindtextdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR); bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8"); textdomain (GETTEXT_PACKAGE); #endif ResourceLoader::addPixmapDir(PACKAGE_DATA_DIR "/" PACKAGE "/pixmaps"); ResourceLoader::addPixmapDir("./pixmaps"); ResourceLoader::addPixmapDir("./"); // analysis command line while ((opt = getopt(argc, argv, "hHg:S:")) != -1) { switch (opt) { case 'g': // window poisition if (optarg) { /* X方向 */ wndProp.initWndPosX = parseInt(optarg, &tmp); /* Y方向 */ wndProp.initWndPosY = parseInt(tmp, NULL); } break; case 'S': // fusenshi window shape if (optarg) { if (strcasecmp("simple", optarg) == 0) { wndProp.wndType = WND_TYPE_SIMPLE; } else if (strcasecmp("normal", optarg) == 0) { wndProp.wndType = WND_TYPE_NORMAL; } else { print_usage(); exit(-1); } } break; case 'H': // hide when bootup fioProp.hideWhenBootup = true; break; case 'h': print_usage(); exit(0); break; default: print_usage(); exit(-1); break; } } // 付箋紙のプロパティファイルを準備 { bool bError = false; try { PropertyData::get(); } catch (...) { bError = true; } // プロパティファイルの構築 if (bError) { PropertyData property; PropertyData::set(property, true); } } // 2重起動の防止処理 { union semun arg; struct sembuf buf; // 既存のセマフォの取得 semid = semget(ftok(getPropertyFilePath().c_str(), '0'), 0, SEM_R | SEM_A); if (0 <= semid) { // 動作状態をチェック if (1 == semctl(semid, 0, GETVAL)) { fprintf(stderr, "%s: It has already started.\n", APP_NAME); exit(0); } else { // 既に終了しているため、解放します。 if (semctl(semid, 1, IPC_RMID)) { fprintf(stderr, "%s: warning: Unable to remove semaphore. (semid=%d)\n", APP_NAME, semid); } } } // 新しいセマフォの構築 semid = semget(ftok(getPropertyFilePath().c_str(), '0'), 1, IPC_CREAT | IPC_EXCL | SEM_R | SEM_A); if (0 > semid) { if (EEXIST == errno) { fprintf(stderr, "%s: It has already started.\n", APP_NAME); exit(0); } fprintf(stderr, "%s: Unable to create shared object.\n", APP_NAME); exit(-1); } fprintf(stdout, "%s: IPC semid=%d\n", APP_NAME, semid); arg.val = 0; if (semctl(semid, 0, SETVAL, arg)) { semctl(semid, 1, IPC_RMID); fprintf(stderr, "%s: semctl() failed.\n", APP_NAME); exit(-1); } // 終了時調整値の設定 buf.sem_num = 0; buf.sem_op = 1; buf.sem_flg = SEM_UNDO; if (semop(semid, &buf, 1)) { semctl(semid, 1, IPC_RMID); fprintf(stderr, "%s: semop() failed.\n", APP_NAME); exit(-1); } } // プロセス間通信用のパイプを準備 if (-1 == pipe(fdes1)) { fprintf(stderr, "%s: Can't create pipe.\n", APP_NAME); semctl(semid, 1, IPC_RMID); exit(-1); } if (-1 == pipe(fdes2)) { fprintf(stderr, "%s: Can't create pipe.\n", APP_NAME); semctl(semid, 1, IPC_RMID); exit(-1); } // ファイル管理プロセス(親)と、ウィンドウ管理プロセス(子)に分離する。 switch (fork()) { case -1: // error fprintf(stderr, "%s: fork() failed.\n", APP_NAME); semctl(semid, 1, IPC_RMID); exit(-1); break; case 0: // child process close(fdes1[1]); close(fdes2[0]); windowServiceStart(fdes1[0], fdes2[1], &wndProp); close(fdes1[0]); close(fdes2[1]); fprintf(stdout, "%s: Exit the WND process.\n", APP_NAME); break; default: // parent process close(fdes1[0]); close(fdes2[1]); fioServiceStart(fdes2[0], fdes1[1], &fioProp); close(fdes1[1]); close(fdes2[0]); semctl(semid, 1, IPC_RMID); fprintf(stdout, "%s: Exit the FIO process.\n", APP_NAME); break; } return 0; } /** * 文字列から整数値をパースします。 * * @param pVal 文字列 * @param ppEndPos 文字列の終端位置(不要な場合は NULL を指定可能) * @return 整数値 */ static int parseInt(const char *pVal, char **ppEndPos) { int result = 0; int rflag = 1; if ('+' == *pVal) { pVal++; } else if ('-' == *pVal) { pVal++; rflag = -1; } for (; *pVal >= '0' && *pVal <= '9'; pVal++) { result = result * 10 + (*pVal - '0'); } if (ppEndPos) { *ppEndPos = (char *)pVal; } return (result * rflag); } /** * 使い方を出力します。 */ static void print_usage() { printf("%s version %d.%d.%d%sby ONGS Inc.\n" "Usage: %s [-h] [-H] [-g geometry] [-S normal | simple]\n" "\t-h : show help\n" "\t-g : geometry ([+|-]x[+|-]y)\n" "\t-S : window shape (default: normal)\n" "\t-H : windows create with hide at bootup time.\n" "\n", APP_NAME, FUSENSHI_MAJOR_VERSION, FUSENSHI_MINOR_VERSION, FUSENSHI_MICRO_VERSION, #ifdef CURRENT_VERSION "-" CURRENT_VERSION " ", #else " ", #endif APP_NAME); }