PCSC那事儿(二十九--PCSCD)

 

绕来绕去,回到 pcscdaemon.c

346                 else

347                 {

348                         if (HotPlug)

349                         {

350                                  Log1(PCSC_LOG_CRITICAL, "file " PCSCLITE_RUN_PID " do not exist");

351                                 Log1(PCSC_LOG_CRITICAL, "Hotplug failed");

352                                 return EXIT_FAILURE;

353                         }

354

355                         Log1(PCSC_LOG_CRITICAL,

356                                 "file " PCSCLITE_PUBSHM_FILE " already exists.");

357                         Log1(PCSC_LOG_CRITICAL,

358                                 "Maybe another pcscd is running?");

359                         Log1(PCSC_LOG_CRITICAL,

360                                 "I can't read process pid from " PCSCLITE_RUN_PID);

361                         Log1(PCSC_LOG_CRITICAL,

362                                 "Remove " PCSCLITE_PUBSHM_FILE " and " PCSCLITE_CSOCK_NAME);

363                         Log1(PCSC_LOG_CRITICAL,

364                                 "if pcscd is not running to clear this message.");

365                         return EXIT_FAILURE;

366                  }

346~366 行,如果从 PCSCLITE_RUN_PID 无法正确读取 pid, 则打印一大堆错误。

367         }

368         else

369                 if (HotPlug)

370                 {

371                         Log1(PCSC_LOG_CRITICAL, "Hotplug failed: pcscd is not running");

372                          return EXIT_FAILURE;

373                 }

369~373 行,如果共享内存文件不存在,则命令行有 HotPlug 则错误直接退出。

当然也可以采用不退出,继续创建必要的文件,并启动 pcscd. 但是这里采用了前者的方法。 

374

375         /*

376          * If this is set to one the user has asked it not to fork

377          */

378         if (!setToForeground)

379         {

380                 if (SYS_Daemon(0, 0))

381                         Log2(PCSC_LOG_CRITICAL, "SYS_Daemon() failed: %s",

382                                 strerror(errno));

383         }

 

374~383 行,如果不是前台运行模式,也就是采用后台运行模式,则采用 daemon 方式启动 pcscd.

384

385         /*

386          * cleanly remove /var/run/pcscd/files when exiting

387          */

388         (void)signal(SIGQUIT, signal_trap);

389         (void)signal(SIGTERM, signal_trap);

390          (void)signal(SIGINT, signal_trap);

391         (void)signal(SIGHUP, signal_trap);

392

 

384~392 行,系统信号处理。

SIGQUIT 可以从控制终端发 SIGQUIT 给进程, 请求进程 dump core

SIGTERM kill 命令引发的信号。

SIGINT 按下 ctrl+c 引发的信号。

SIGHUP 在用户终端连接 ( 正常或非正常 ) 结束时发出,通常是在终端的控制进程结束时,

通知同一 session 内的各个作业,这时它们与控制终端不再关联。

 

OK. 关于信号的内容很多很多。适可而止。

上面重定向了这 4 个信号。采用统一个处理函数, 整齐划一,泯灭个性。 这个处理函数是 signal_trap.

也在 pcscdaemon.c 中实现。

581 static void signal_trap(/*@unused@*/ int sig)

582 {

583         (void)sig;

584

585         /* the signal handler is called several times for the same Ctrl-C */

586         if (AraKiri == FALSE)

587         {

588                 Log1(PCSC_LOG_INFO, "Preparing for suicide");

589                 AraKiri = TRUE;

590

591                 /* if still in the init/loading phase the AraKiri will not be

592                  * seen by the main event loop

593                  */

594                 if (Init)

595                 {

596                         Log1(PCSC_LOG_INFO, "Suicide during init");

597                         at_exit();

598                 }

599         }

600 }

 

 

Init 是个特殊标志,代表 pcscd 是否处于初始化阶段。

main 函数的

517         Init = FALSE;

之后,就代表过了初始化阶段。仅仅而已。

 

这个处理过程,仅仅变动了一个标志 AraKiri. 这个标志的目的,等吧 ... 等以后解释。

不能等,那么就看看 175 页吧。答应了,就一定会说到做到的。

 

at_exit 也实现在同一个文件中,

535 static void at_exit(void)

536 {

537         Log1(PCSC_LOG_INFO, "cleaning " PCSCLITE_IPC_DIR);

538

539         clean_temp_files();

540

541         SYS_Exit(ExitValue);

542 }

535~542 行,清除上面提到的4组临时文件,进程退出 .

ExitValue 有两个自解释的枚举值:

EXIT_SUCCESS

EXIT_FAILURE

 

 

通过上面的分析知道,共享文件不存在的情况下,则需要创建包括共享文件在内的上面

提到的临时文件。包括

PCSCLITE_RUN_PID 文件 (/var/run/pcscd/pcscd.pid)

PCSCLITE_EVENTS_DIR 目录 (/var/run/pcscd/pcscd.events)

 

下面创建存放 PCSCLITE_RUN_PID 文件的目录

393         /*

394          * If PCSCLITE_IPC_DIR does not exist then create it

395          */

396         rv = SYS_Stat(PCSCLITE_IPC_DIR, &fStatBuf);

397         if (rv < 0)

398         {

399                 int mode = S_IROTH | S_IXOTH | S_IRGRP | S_IXGRP | S_IRWXU;

400

401                 rv = SYS_Mkdir(PCSCLITE_IPC_DIR, mode);

402                 if (rv != 0)

403                 {

404                         Log2(PCSC_LOG_CRITICAL,

405                                 "cannot create " PCSCLITE_IPC_DIR ": %s", strerror(errno));

406                         return EXIT_FAILURE;

407                 }

408

409                 /* set mode so that the directory is world readable and

410                  * executable even is umask is restrictive

411                  * The directory containes files used by libpcsclite */

412                 (void)SYS_Chmod(PCSCLITE_IPC_DIR, mode);

413         }

414

415         /*

416          * Record our pid to make it easier

417          * to kill the correct pcscd

418          */

419         {

420                 int f;

421                 int mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH;

422

423                 if ((f = SYS_OpenFile(PCSCLITE_RUN_PID, O_RDWR | O_CREAT, mode)) != -1)

424                 {

425                         char pid[PID_ASCII_SIZE];

426

427                          (void)snprintf(pid, sizeof(pid), "%u/n", (unsigned) getpid());

428                         (void)SYS_WriteFile(f, pid, strlen(pid));

429                         (void)SYS_CloseFile(f);

430

431                         /* set mode so that the file is world readable even is umask is

432                          * restrictive

433                          * The file is used by libpcsclite */

434                         (void)SYS_Chmod(PCSCLITE_RUN_PID, mode);

435                 }

436                 else

437                         Log2(PCSC_LOG_CRITICAL, "cannot create " PCSCLITE_RUN_PID ": %s",

438                                 strerror(errno));

439         }

414~439 行,创建 PCSCLITE_RUN_PID 文件,并往文件中写入当前进程的 pid.

这样其它的进程,包括后续启动的 pcscd 可以方便地得到这个 pcscd 的进程 pid.

 

440

441         /*

442          * If PCSCLITE_EVENTS does not exist then create it

443          */

444         rv = SYS_Stat(PCSCLITE_EVENTS_DIR, &fStatBuf);

445          if (rv < 0)

446         {

447                 /* 1733 : world writable + sticky bit */

448                 int mode = S_IRWXU | S_IWGRP | S_IXGRP | S_IWOTH | S_IXOTH | S_ISVTX;

449

450                 rv = SYS_Mkdir(PCSCLITE_EVENTS_DIR, mode);

451                  if (rv != 0)

452                 {

453                         Log2(PCSC_LOG_CRITICAL,

454                                 "cannot create " PCSCLITE_EVENTS_DIR ": %s", strerror(errno));

455                         return EXIT_FAILURE;

456                 }

457                 (void)SYS_Chmod(PCSCLITE_EVENTS_DIR, mode);

458         }

440~458 行,创建 PCSCLITE_EVENTS_DIR 目录,方便 APPLICATION pcscd 的事件通讯。

 

459

460         /* cleanly remove /var/run/pcscd/pcsc.* files when exiting */

461          if (atexit(at_exit))

462                 Log2(PCSC_LOG_CRITICAL, "atexit() failed: %s", strerror(errno));

463

atexit 设置程序正常结束前调用的函数。

当程序通过 exit 或从 main 中返回,参数 function 所指定的函数会先被调用,

然后真正由 exit 结束程序。

也就是说,如果程序正常退出,则调用 at_exit. 很像析构吧。

at_exit 在上面解释了。移除 /var/run/pcscd/ 下, pcsc 开头的 3 个文件和一个目录。

3 个文件是:

/var/run/pcscd/pcscd.pub

/var/run/pcscd/pcscd.comm

/var/run/pcscd/pcscd.pid

1 个目录是:

/var/run/pcscd/pcscd.events

 

 

继续,继续。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值