lib/pidfile.c

説明を見る。
00001 /* this code is broken - there is a race condition with the unlink (tridge) */
00002 
00003 /* 
00004    Unix SMB/CIFS implementation.
00005    pidfile handling
00006    Copyright (C) Andrew Tridgell 1998
00007    
00008    This program is free software; you can redistribute it and/or modify
00009    it under the terms of the GNU General Public License as published by
00010    the Free Software Foundation; either version 2 of the License, or
00011    (at your option) any later version.
00012    
00013    This program is distributed in the hope that it will be useful,
00014    but WITHOUT ANY WARRANTY; without even the implied warranty of
00015    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016    GNU General Public License for more details.
00017    
00018    You should have received a copy of the GNU General Public License
00019    along with this program; if not, write to the Free Software
00020    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
00021 */
00022 
00023 #include "includes.h"
00024 
00025 #ifndef O_NONBLOCK
00026 #define O_NONBLOCK
00027 #endif
00028 
00029 /* return the pid in a pidfile. return 0 if the process (or pidfile)
00030    does not exist */
00031 pid_t pidfile_pid(const char *name)
00032 {
00033         int fd;
00034         char pidstr[20];
00035         pid_t pid;
00036         unsigned int ret;
00037         pstring pidFile;
00038 
00039         slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_piddir(), name);
00040 
00041         fd = sys_open(pidFile, O_NONBLOCK | O_RDONLY, 0644);
00042         if (fd == -1) {
00043                 return 0;
00044         }
00045 
00046         ZERO_ARRAY(pidstr);
00047 
00048         if (read(fd, pidstr, sizeof(pidstr)-1) <= 0) {
00049                 goto noproc;
00050         }
00051 
00052         ret = atoi(pidstr);
00053 
00054         if (ret == 0) {
00055                 /* Obviously we had some garbage in the pidfile... */
00056                 DEBUG(1, ("Could not parse contents of pidfile %s\n",
00057                           pidFile));
00058                 goto noproc;
00059         }
00060         
00061         pid = (pid_t)ret;
00062         if (!process_exists_by_pid(pid)) {
00063                 goto noproc;
00064         }
00065 
00066         if (fcntl_lock(fd,SMB_F_SETLK,0,1,F_RDLCK)) {
00067                 /* we could get the lock - it can't be a Samba process */
00068                 goto noproc;
00069         }
00070 
00071         close(fd);
00072         return (pid_t)ret;
00073 
00074  noproc:
00075         close(fd);
00076         unlink(pidFile);
00077         return 0;
00078 }
00079 
00080 /* create a pid file in the pid directory. open it and leave it locked */
00081 void pidfile_create(const char *program_name)
00082 {
00083         int     fd;
00084         char    buf[20];
00085         char    *short_configfile;
00086         pstring name;
00087         pstring pidFile;
00088         pid_t pid;
00089 
00090         /* Add a suffix to the program name if this is a process with a
00091          * none default configuration file name. */
00092         if (strcmp( CONFIGFILE, dyn_CONFIGFILE) == 0) {
00093                 strncpy( name, program_name, sizeof( name)-1);
00094         } else {
00095                 short_configfile = strrchr( dyn_CONFIGFILE, '/');
00096                 if (short_configfile == NULL) {
00097                         /* conf file in current directory */
00098                         short_configfile = dyn_CONFIGFILE;
00099                 } else {
00100                         /* full/relative path provided */
00101                         short_configfile++;
00102                 }
00103                 slprintf( name, sizeof( name)-1, "%s-%s", program_name,
00104                           short_configfile );
00105         }
00106 
00107         slprintf(pidFile, sizeof(pidFile)-1, "%s/%s.pid", lp_piddir(), name);
00108 
00109         pid = pidfile_pid(name);
00110         if (pid != 0) {
00111                 DEBUG(0,("ERROR: %s is already running. File %s exists and process id %d is running.\n", 
00112                          name, pidFile, (int)pid));
00113                 exit(1);
00114         }
00115 
00116         fd = sys_open(pidFile, O_NONBLOCK | O_CREAT | O_WRONLY | O_EXCL, 0644);
00117         if (fd == -1) {
00118                 DEBUG(0,("ERROR: can't open %s: Error was %s\n", pidFile, 
00119                          strerror(errno)));
00120                 exit(1);
00121         }
00122 
00123         if (fcntl_lock(fd,SMB_F_SETLK,0,1,F_WRLCK)==False) {
00124                 DEBUG(0,("ERROR: %s : fcntl lock of file %s failed. Error was %s\n",  
00125               name, pidFile, strerror(errno)));
00126                 exit(1);
00127         }
00128 
00129         memset(buf, 0, sizeof(buf));
00130         slprintf(buf, sizeof(buf) - 1, "%u\n", (unsigned int) sys_getpid());
00131         if (write(fd, buf, strlen(buf)) != (ssize_t)strlen(buf)) {
00132                 DEBUG(0,("ERROR: can't write to file %s: %s\n", 
00133                          pidFile, strerror(errno)));
00134                 exit(1);
00135         }
00136         /* Leave pid file open & locked for the duration... */
00137 }

Sambaに対してSat Aug 29 21:22:58 2009に生成されました。  doxygen 1.4.7