Advanced Programming in the UNIX® Environment

(lily) #1
ptg10805159

Section 21.5 Source Code 827


449 nw=write(fd, &req, sizeof(struct printreq));
450 if (nw != sizeof(struct printreq)) {
451 res.jobid=0;
452 if (nw < 0)
453 res.retcode =htonl(errno);
454 else
455 res.retcode =htonl(EIO);
456 log_msg("client_thread: can’t write %s: %s", name,
457 strerror(res.retcode));
458 close(fd);
459 strncpy(res.msg, strerror(res.retcode), MSGLEN_MAX);
460 writen(sockfd, &res, sizeof(struct printresp));
461 unlink(name);
462 sprintf(name, "%s/%s/%d", SPOOLDIR, DATADIR, jobid);
463 unlink(name);
464 pthread_exit((void *)1);
465 }
466 close(fd);
467 /*
468 * Send response to client.
469 */
470 res.retcode=0;
471 res.jobid=htonl(jobid);
472 sprintf(res.msg, "request ID %d", jobid);
473 writen(sockfd, &res, sizeof(struct printresp));
474 /*
475 * Notify the printer thread, clean up, and exit.
476 */
477 log_msg("adding job %d to queue", jobid);
478 add_job(&req, jobid);
479 pthread_cleanup_pop(1);
480 return((void *)0);
481 }

[449 – 465] We write theprintreqstructure to the control file. On error, we log a
message, close the descriptor for the control file, send a failureresponse back
to the client, remove the data and control files, and terminate the thread.
[466 – 473] We close the file descriptor for the control file and send a message containing
the job ID and a successful status (retcodeset to 0) back to the client.
[474 – 481] We calladd_jobto add the received job to the list of pending print jobs and
call pthread_cleanup_pop to complete the cleanup processing. The
thread terminates when we return.
Note that beforethe thread exits, we must close any file descriptors we no
longer need. Unlike with process termination, file descriptors arenot closed
automatically when a thread ends if other threads exist in the process. If we
didn’t close unneeded file descriptors, we’d eventually run out of resources.
Free download pdf