]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/process.c
2 * "$Id: process.c 5049 2006-02-02 14:50:57Z mike $"
4 * Process management routines for the Common UNIX Printing System (CUPS).
6 * Copyright 1997-2006 by Easy Software Products, all rights reserved.
8 * These coded instructions, statements, and computer programs are the
9 * property of Easy Software Products and are protected by Federal
10 * copyright law. Distribution and use rights are outlined in the file
11 * "LICENSE.txt" which should have been included with this file. If this
12 * file is missing or damaged please contact Easy Software Products
15 * Attn: CUPS Licensing Information
16 * Easy Software Products
17 * 44141 Airport View Drive, Suite 204
18 * Hollywood, Maryland 20636 USA
20 * Voice: (301) 373-9600
21 * EMail: cups-info@cups.org
22 * WWW: http://www.cups.org
26 * cupsdEndProcess() - End a process.
27 * cupsdFinishProcess() - Finish a process and get its name.
28 * cupsdStartProcess() - Start a process.
29 * compare_procs() - Compare two processes.
33 * Include necessary headers...
38 #if defined(__APPLE__) && __GNUC__ < 4
40 #endif /* __APPLE__ && __GNUC__ < 4 */
44 * Process structure...
49 int pid
; /* Process ID */
50 char name
[1]; /* Name of process */
58 static cups_array_t
*process_array
= NULL
;
65 static int compare_procs(cupsd_proc_t
*a
, cupsd_proc_t
*b
);
69 * 'cupsdEndProcess()' - End a process.
72 int /* O - 0 on success, -1 on failure */
73 cupsdEndProcess(int pid
, /* I - Process ID */
74 int force
) /* I - Force child to die */
77 return (kill(pid
, SIGKILL
));
79 return (kill(pid
, SIGTERM
));
84 * 'cupsdFinishProcess()' - Finish a process and get its name.
87 const char * /* O - Process name */
88 cupsdFinishProcess(int pid
, /* I - Process ID */
89 char *name
, /* I - Name buffer */
90 int namelen
) /* I - Size of name buffer */
92 cupsd_proc_t key
, /* Search key */
93 *proc
; /* Matching process */
98 if ((proc
= (cupsd_proc_t
*)cupsArrayFind(process_array
, &key
)) != NULL
)
100 strlcpy(name
, proc
->name
, namelen
);
101 cupsArrayRemove(process_array
, proc
);
112 * 'cupsdStartProcess()' - Start a process.
115 int /* O - Process ID or 0 */
117 const char *command
, /* I - Full path to command */
118 char *argv
[], /* I - Command-line arguments */
119 char *envp
[], /* I - Environment */
120 int infd
, /* I - Standard input file descriptor */
121 int outfd
, /* I - Standard output file descriptor */
122 int errfd
, /* I - Standard error file descriptor */
123 int backfd
, /* I - Backchannel file descriptor */
124 int root
, /* I - Run as root? */
125 int *pid
) /* O - Process ID */
127 cupsd_proc_t
*proc
; /* New process record */
128 #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
129 struct sigaction action
; /* POSIX signal handler */
130 #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
131 #if defined(__APPLE__) && __GNUC__ < 4
132 int envc
; /* Number of environment variables */
133 char processPath
[1024], /* CFProcessPath environment variable */
134 linkpath
[1024]; /* Link path for symlinks... */
135 int linkbytes
; /* Bytes for link path */
136 #endif /* __APPLE__ && __GNUC__ < 4 */
139 cupsdLogMessage(CUPSD_LOG_DEBUG2
,
140 "cupsdStartProcess(\"%s\", %p, %p, %d, %d, %d)",
141 command
, argv
, envp
, infd
, outfd
, errfd
);
143 #if defined(__APPLE__) && __GNUC__ < 4
145 * Add special voodoo magic for MacOS X 10.3 and earlier - this allows
146 * MacOS X programs to access their bundle resources properly...
149 for (envc
= 0; envc
< MAX_ENV
&& envp
[envc
]; envc
++);
150 /* All callers pass in a MAX_ENV element array of environment strings */
152 if (envc
< (MAX_ENV
- 1))
155 * We have room, try to read the symlink path for this command...
158 if ((linkbytes
= readlink(command
, linkpath
, sizeof(linkpath
) - 1)) > 0)
161 * Yes, this is a symlink to the actual program, nul-terminate and
165 linkpath
[linkbytes
] = '\0';
167 if (linkpath
[0] == '/')
168 snprintf(processPath
, sizeof(processPath
), "CFProcessPath=%s",
171 snprintf(processPath
, sizeof(processPath
), "CFProcessPath=%s/%s",
172 dirname(command
), linkpath
);
175 snprintf(processPath
, sizeof(processPath
), "CFProcessPath=%s", command
);
177 envp
[envc
++] = processPath
;
180 #endif /* __APPLE__ && __GNUC__ > 3 */
183 * Block signals before forking...
188 if ((*pid
= fork()) == 0)
191 * Child process goes here...
193 * Update stdin/stdout/stderr as needed...
202 open("/dev/null", O_RDONLY
);
210 open("/dev/null", O_WRONLY
);
218 open("/dev/null", O_WRONLY
);
226 open("/dev/null", O_RDWR
);
227 fcntl(3, F_SETFL
, O_NDELAY
);
231 * Change the priority of the process based on the FilterNice setting.
232 * (this is not done for backends...)
239 * Change user to something "safe"...
242 if (!root
&& !RunUser
)
245 * Running as root, so change to non-priviledged user...
251 if (setgroups(1, &Group
))
260 * Reset group membership to just the main one we belong to.
264 setgroups(1, &Group
);
268 * Change umask to restrict permissions on created files...
274 * Unblock signals before doing the exec...
278 sigset(SIGTERM
, SIG_DFL
);
279 sigset(SIGCHLD
, SIG_DFL
);
280 #elif defined(HAVE_SIGACTION)
281 memset(&action
, 0, sizeof(action
));
283 sigemptyset(&action
.sa_mask
);
284 action
.sa_handler
= SIG_DFL
;
286 sigaction(SIGTERM
, &action
, NULL
);
287 sigaction(SIGCHLD
, &action
, NULL
);
289 signal(SIGTERM
, SIG_DFL
);
290 signal(SIGCHLD
, SIG_DFL
);
291 #endif /* HAVE_SIGSET */
293 cupsdReleaseSignals();
296 * Execute the command; if for some reason this doesn't work,
297 * return the error code...
301 execve(command
, argv
, envp
);
303 execv(command
, argv
);
312 * Error - couldn't fork a new process!
315 cupsdLogMessage(CUPSD_LOG_ERROR
, "Unable to fork %s - %s.", command
,
323 process_array
= cupsArrayNew((cups_array_func_t
)compare_procs
, NULL
);
327 if ((proc
= calloc(1, sizeof(cupsd_proc_t
) + strlen(command
))) != NULL
)
330 strcpy(proc
->name
, command
);
332 cupsArrayAdd(process_array
, proc
);
337 cupsdReleaseSignals();
344 * 'compare_procs()' - Compare two processes.
347 static int /* O - Result of comparison */
348 compare_procs(cupsd_proc_t
*a
, /* I - First process */
349 cupsd_proc_t
*b
) /* I - Second process */
351 return (a
->pid
- b
->pid
);
356 * End of "$Id: process.c 5049 2006-02-02 14:50:57Z mike $".