ptg10805159
818 Communicating with a Network Printer Chapter 21
168 /*
169 * Initialize the job ID file. Use a record lock to prevent
170 * more than one printer daemon from running at a time.
171 *
172 * LOCKING: none, except for record-lock on job ID file.
173 */
174 void
175 init_request(void)
176 {
177 int n;
178 char name[FILENMSZ];
179 sprintf(name, "%s/%s", SPOOLDIR, JOBFILE);
180 jobfd=open(name, O_CREAT|O_RDWR, S_IRUSR|S_IWUSR);
181 if (write_lock(jobfd, 0, SEEK_SET, 0) < 0)
182 log_quit("daemon already running");
183 /*
184 * Reuse the name buffer for the job counter.
185 */
186 if ((n = read(jobfd, name, FILENMSZ)) < 0)
187 log_sys("can’t read job file");
188 if (n == 0)
189 nextjob=1;
190 else
191 nextjob=atol(name);
192 }
[168 – 182] Theinit_requestfunction does two things: it places a recordlock on the
job file,/var/spool/printer/jobno,and it reads the file to determine
the next job number to assign. We place a write lock on the entirefile to
indicate that the daemon is running. If someone tries to start additional
copies of the printer spooling daemon while one is already running, these
additional daemons will fail to obtain the write lock and will exit. Thus,
only one copy of the daemon can be running at a time. (Recall that we used
this technique in Figure13.6; we discussed the write_lock macroin
Section 14.3.)
[183 – 192] The job file contains an ASCII integer string representing the next job
number.Ifthe file was just created and therefore is empty, we setnextjob
to 1. Otherwise, we useatolto convert the string to an integer and use this
value as the next job number.Weleavejobfdopen to the job file so that we
can update the job number as jobs arecreated. Wecan’t close the file,
because this would release the write lock that we’ve placed on it.
On a system wherealong integer is 64 bits wide, we need a buffer at least 21
bytes in size to fit a string representing the largest possible long integer.We
can safely reuse the filename buffer,becauseFILENMSZis defined to be 64 in
print.h.