|
7 | 7 | *
|
8 | 8 | *
|
9 | 9 | * IDENTIFICATION
|
10 |
| - * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.37 1999/11/24 16:52:42 momjian Exp $ |
| 10 | + * $Header: /cvsroot/pgsql/src/backend/utils/init/miscinit.c,v 1.38 2000/01/09 12:15:57 ishii Exp $ |
11 | 11 | *
|
12 | 12 | *-------------------------------------------------------------------------
|
13 | 13 | */
|
14 | 14 | #include<sys/param.h>
|
15 | 15 | #include<sys/types.h>
|
| 16 | +#include<signal.h> |
16 | 17 | #include<sys/stat.h>
|
17 | 18 | #include<sys/file.h>
|
18 | 19 | #include<unistd.h>
|
@@ -462,3 +463,156 @@ SetUserId()
|
462 | 463 | ShadowRelationName);
|
463 | 464 | UserId= (Oid) ((Form_pg_shadow)GETSTRUCT(userTup))->usesysid;
|
464 | 465 | }
|
| 466 | + |
| 467 | +/*------------------------------------------------------------------------- |
| 468 | + * |
| 469 | + * posmaster pid file stuffs. $DATADIR/postmaster.pid is created when: |
| 470 | + * |
| 471 | + *(1) postmaster starts. In this case pid > 0. |
| 472 | + *(2) postgres starts in standalone mode. In this case |
| 473 | + * pid < 0 |
| 474 | + * |
| 475 | + * to gain an interlock. |
| 476 | + * |
| 477 | + *SetPidFname(datadir) |
| 478 | + *Remember the the pid file name. This is neccesary |
| 479 | + *UnlinkPidFile() is called from proc_exit(). |
| 480 | + * |
| 481 | + *GetPidFname(datadir) |
| 482 | + *Get the pid file name. SetPidFname() should be called |
| 483 | + *before GetPidFname() gets called. |
| 484 | + * |
| 485 | + *UnlinkPidFile() |
| 486 | + *This is called from proc_exit() and unlink the pid file. |
| 487 | + * |
| 488 | + *SetPidFile(pid_t pid) |
| 489 | + *Create the pid file. On failure, it checks if the process |
| 490 | + *actually exists or not. SetPidFname() should be called |
| 491 | + *in prior to calling SetPidFile(). |
| 492 | + * |
| 493 | + *------------------------------------------------------------------------- |
| 494 | + */ |
| 495 | + |
| 496 | +/* |
| 497 | + * Path to pid file. proc_exit() remember it to unlink the file. |
| 498 | + */ |
| 499 | +staticcharPidFile[MAXPGPATH]; |
| 500 | + |
| 501 | +/* |
| 502 | + * Remove the pid file. This function is called from proc_exit. |
| 503 | + */ |
| 504 | +voidUnlinkPidFile(void) |
| 505 | +{ |
| 506 | +unlink(PidFile); |
| 507 | +} |
| 508 | + |
| 509 | +/* |
| 510 | + * Set path to the pid file |
| 511 | + */ |
| 512 | +voidSetPidFname(char*datadir) |
| 513 | +{ |
| 514 | +snprintf(PidFile,sizeof(PidFile),"%s/%s",datadir,PIDFNAME); |
| 515 | +} |
| 516 | + |
| 517 | +/* |
| 518 | + * Get path to the pid file |
| 519 | + */ |
| 520 | +char*GetPidFname(void) |
| 521 | +{ |
| 522 | +return(PidFile); |
| 523 | +} |
| 524 | + |
| 525 | +/* |
| 526 | + * Create the pid file |
| 527 | + */ |
| 528 | +intSetPidFile(pid_tpid) |
| 529 | +{ |
| 530 | +intfd; |
| 531 | +char*pidfile; |
| 532 | +charpidstr[32]; |
| 533 | +intlen; |
| 534 | +pid_tpost_pid; |
| 535 | +intis_postgres=0; |
| 536 | + |
| 537 | +/* |
| 538 | + * Creating pid file |
| 539 | + */ |
| 540 | +pidfile=GetPidFname(); |
| 541 | +fd=open(pidfile,O_RDWR |O_CREAT |O_EXCL,0600); |
| 542 | +if (fd<0) { |
| 543 | +/* |
| 544 | + * Couldn't create the pid file. Probably |
| 545 | + * it already exists. Read the file to see if the process |
| 546 | + * actually exists |
| 547 | + */ |
| 548 | +fd=open(pidfile,O_RDONLY,0600); |
| 549 | +if (fd<0) { |
| 550 | +fprintf(stderr,"Can't open pid file: %s\n",pidfile); |
| 551 | +fprintf(stderr,"Please check the permission and try again.\n"); |
| 552 | +return(-1); |
| 553 | +} |
| 554 | +if ((len=read(fd,pidstr,sizeof(pidstr)-1))<0) { |
| 555 | +fprintf(stderr,"Can't read pid file: %s\n",pidfile); |
| 556 | +fprintf(stderr,"Please check the permission and try again.\n"); |
| 557 | +close(fd); |
| 558 | +return(-1); |
| 559 | +} |
| 560 | +close(fd); |
| 561 | + |
| 562 | +/* |
| 563 | + * Check to see if the process actually exists |
| 564 | + */ |
| 565 | +pidstr[len]='\0'; |
| 566 | +post_pid= (pid_t)atoi(pidstr); |
| 567 | + |
| 568 | +/* if pid < 0, the pid is for postgres, not postmatser */ |
| 569 | +if (post_pid<0) { |
| 570 | +is_postgres++; |
| 571 | +post_pid=-post_pid; |
| 572 | +} |
| 573 | + |
| 574 | +if (post_pid==0|| (post_pid>0&&kill(post_pid,0)<0)) { |
| 575 | +/* |
| 576 | + * No, the process did not exist. Unlink |
| 577 | + * the file and try to create it |
| 578 | + */ |
| 579 | +if (unlink(pidfile)<0) { |
| 580 | +fprintf(stderr,"Can't remove pid file: %s\n",pidfile); |
| 581 | +fprintf(stderr,"The file seems accidently left, but I couldn't remove it.\n"); |
| 582 | +fprintf(stderr,"Please remove the file by hand and try again.\n"); |
| 583 | +return(-1); |
| 584 | +} |
| 585 | +fd=open(pidfile,O_RDWR |O_CREAT |O_EXCL,0600); |
| 586 | +if (fd<0) { |
| 587 | +fprintf(stderr,"Can't create pid file: %s\n",pidfile); |
| 588 | +fprintf(stderr,"Please check the permission and try again.\n"); |
| 589 | +return(-1); |
| 590 | +} |
| 591 | +}else { |
| 592 | +/* |
| 593 | + * Another postmaster is running |
| 594 | + */ |
| 595 | +fprintf(stderr,"Can't create pid file: %s\n",pidfile); |
| 596 | +if (is_postgres) { |
| 597 | +fprintf(stderr,"Is another postgres (pid: %d) running?\n",post_pid); |
| 598 | +} |
| 599 | +else |
| 600 | +{ |
| 601 | +fprintf(stderr,"Is another postmaster (pid: %s) running?\n",pidstr); |
| 602 | +} |
| 603 | +return(-1); |
| 604 | +} |
| 605 | +} |
| 606 | + |
| 607 | +sprintf(pidstr,"%d",pid); |
| 608 | +if (write(fd,pidstr,strlen(pidstr))!=strlen(pidstr)) { |
| 609 | +fprintf(stderr,"Write to pid file failed\n"); |
| 610 | +fprintf(stderr,"Please check the permission and try again.\n"); |
| 611 | +close(fd); |
| 612 | +unlink(pidfile); |
| 613 | +return(-1); |
| 614 | +} |
| 615 | +close(fd); |
| 616 | + |
| 617 | +return(0); |
| 618 | +} |