]>
git.ipfire.org Git - thirdparty/cups.git/blob - scheduler/process.c
2 * "$Id: process.c 5046 2006-02-01 22:11:58Z 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...
41 * Process structure...
46 int pid
; /* Process ID */
47 char name
[1]; /* Name of process */
55 static cups_array_t
*process_array
= NULL
;
62 static int compare_procs(cupsd_proc_t
*a
, cupsd_proc_t
*b
);
66 * 'cupsdEndProcess()' - End a process.
69 int /* O - 0 on success, -1 on failure */
70 cupsdEndProcess(int pid
, /* I - Process ID */
71 int force
) /* I - Force child to die */
74 return (kill(pid
, SIGKILL
));
76 return (kill(pid
, SIGTERM
));
81 * 'cupsdFinishProcess()' - Finish a process and get its name.
84 const char * /* O - Process name */
85 cupsdFinishProcess(int pid
, /* I - Process ID */
86 char *name
, /* I - Name buffer */
87 int namelen
) /* I - Size of name buffer */
89 cupsd_proc_t key
, /* Search key */
90 *proc
; /* Matching process */
95 if ((proc
= (cupsd_proc_t
*)cupsArrayFind(process_array
, &key
)) != NULL
)
97 strlcpy(name
, proc
->name
, namelen
);
98 cupsArrayRemove(process_array
, proc
);
109 * 'cupsdStartProcess()' - Start a process.
112 int /* O - Process ID or 0 */
114 const char *command
, /* I - Full path to command */
115 char *argv
[], /* I - Command-line arguments */
116 char *envp
[], /* I - Environment */
117 int infd
, /* I - Standard input file descriptor */
118 int outfd
, /* I - Standard output file descriptor */
119 int errfd
, /* I - Standard error file descriptor */
120 int backfd
, /* I - Backchannel file descriptor */
121 int root
, /* I - Run as root? */
122 int *pid
) /* O - Process ID */
124 cupsd_proc_t
*proc
; /* New process record */
125 #if defined(HAVE_SIGACTION) && !defined(HAVE_SIGSET)
126 struct sigaction action
; /* POSIX signal handler */
127 #endif /* HAVE_SIGACTION && !HAVE_SIGSET */
128 #if defined(__APPLE__) && __GNUC__ < 4
129 int envc
; /* Number of environment variables */
130 char processPath
[1024], /* CFProcessPath environment variable */
131 linkpath
[1024]; /* Link path for symlinks... */
132 int linkbytes
; /* Bytes for link path */
133 #endif /* __APPLE__ && __GNUC__ < 4 */
136 cupsdLogMessage(CUPSD_LOG_DEBUG2
,
137 "cupsdStartProcess(\"%s\", %p, %p, %d, %d, %d)",
138 command
, argv
, envp
, infd
, outfd
, errfd
);
140 #if defined(__APPLE__) && __GNUC__ < 4
142 * Add special voodoo magic for MacOS X 10.3 and earlier - this allows
143 * MacOS X programs to access their bundle resources properly...
146 for (envc
= 0; envc
< MAX_ENV
&& envp
[envc
]; envc
++);
147 /* All callers pass in a MAX_ENV element array of environment strings */
149 if (envc
< (MAX_ENV
- 1))
152 * We have room, try to read the symlink path for this command...
155 if ((linkbytes
= readlink(linkpath
, sizeof(linkpath
) - 1)) > 0)
158 * Yes, this is a symlink to the actual program, nul-terminate and
162 linkpath
[linkbytes
] = '\0';
164 if (linkpath
[0] == '/')
165 snprintf(processPath
, sizeof(processPath
), "CFProcessPath=%s",
168 snprintf(processPath
, sizeof(processPath
), "CFProcessPath=%s/%s",
169 dirname(command
), linkpath
);
172 snprintf(processPath
, sizeof(processPath
), "CFProcessPath=%s", command
);
174 envp
[envc
++] = processPath
;
177 #endif /* __APPLE__ && __GNUC__ > 3 */
180 * Block signals before forking...
185 if ((*pid
= fork()) == 0)
188 * Child process goes here...
190 * Update stdin/stdout/stderr as needed...
199 open("/dev/null", O_RDONLY
);
207 open("/dev/null", O_WRONLY
);
215 open("/dev/null", O_WRONLY
);
223 open("/dev/null", O_RDWR
);
224 fcntl(3, F_SETFL
, O_NDELAY
);
228 * Change the priority of the process based on the FilterNice setting.
229 * (this is not done for backends...)
236 * Change user to something "safe"...
239 if (!root
&& !RunUser
)
242 * Running as root, so change to non-priviledged user...
248 if (setgroups(1, &Group
))
257 * Reset group membership to just the main one we belong to.
261 setgroups(1, &Group
);
265 * Change umask to restrict permissions on created files...
271 * Unblock signals before doing the exec...
275 sigset(SIGTERM
, SIG_DFL
);
276 sigset(SIGCHLD
, SIG_DFL
);
277 #elif defined(HAVE_SIGACTION)
278 memset(&action
, 0, sizeof(action
));
280 sigemptyset(&action
.sa_mask
);
281 action
.sa_handler
= SIG_DFL
;
283 sigaction(SIGTERM
, &action
, NULL
);
284 sigaction(SIGCHLD
, &action
, NULL
);
286 signal(SIGTERM
, SIG_DFL
);
287 signal(SIGCHLD
, SIG_DFL
);
288 #endif /* HAVE_SIGSET */
290 cupsdReleaseSignals();
293 * Execute the command; if for some reason this doesn't work,
294 * return the error code...
298 execve(command
, argv
, envp
);
300 execv(command
, argv
);
309 * Error - couldn't fork a new process!
312 cupsdLogMessage(CUPSD_LOG_ERROR
, "Unable to fork %s - %s.", command
,
320 process_array
= cupsArrayNew((cups_array_func_t
)compare_procs
, NULL
);
324 if ((proc
= calloc(1, sizeof(cupsd_proc_t
) + strlen(command
))) != NULL
)
327 strcpy(proc
->name
, command
);
329 cupsArrayAdd(process_array
, proc
);
334 cupsdReleaseSignals();
341 * 'compare_procs()' - Compare two processes.
344 static int /* O - Result of comparison */
345 compare_procs(cupsd_proc_t
*a
, /* I - First process */
346 cupsd_proc_t
*b
) /* I - Second process */
348 return (a
->pid
- b
->pid
);
353 * End of "$Id: process.c 5046 2006-02-01 22:11:58Z mike $".