proc.c revision 3f54fd611f536639ec30dd53c48e5ec1897cc7d9
/***********************************************************************
* *
* This software is part of the BSD package *
*Copyright (c) 1978-2009 The Regents of the University of California an*
* *
* Redistribution and use in source and binary forms, with or *
* without modification, are permitted provided that the following *
* conditions are met: *
* *
* 1. Redistributions of source code must retain the above *
* copyright notice, this list of conditions and the *
* following disclaimer. *
* *
* 2. Redistributions in binary form must reproduce the above *
* copyright notice, this list of conditions and the *
* materials provided with the distribution. *
* *
* 3. Neither the name of The Regents of the University of California*
* names of its contributors may be used to endorse or *
* promote products derived from this software without *
* specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND *
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, *
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF *
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE *
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS *
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, *
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED *
* TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, *
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON *
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY *
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE *
* POSSIBILITY OF SUCH DAMAGE. *
* *
* Redistribution and use in source and binary forms, with or without *
* modification, are permitted provided that the following conditions *
* are met: *
* 1. Redistributions of source code must retain the above copyright *
* notice, this list of conditions and the following disclaimer. *
* 2. Redistributions in binary form must reproduce the above copyright *
* notice, this list of conditions and the following disclaimer in *
* distribution. *
* 3. Neither the name of the University nor the names of its *
* contributors may be used to endorse or promote products derived *
* from this software without specific prior written permission. *
* *
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" *
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED *
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS *
* OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, *
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT *
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF *
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND *
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, *
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT *
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF *
* SUCH DAMAGE. *
* *
* Kurt Shoens (UCB) *
* gsf *
* *
***********************************************************************/
#pragma prototyped
/*
* Mail -- a mail program
*
* Process control.
*/
#include "mailx.h"
#define READ 0
#define WRITE 1
static void
{
}
/*
* return std stream for file,mode
* 0 if no match
*/
FILE*
{
if (*mode == 'r') {
return stdin;
}
else if (*mode == 'w') {
return stdout;
return stderr;
}
return 0;
}
/*
* fopen() with some extra mode prefixes:
*
* E enable error messages
* I don't register_file (fclose to close)
* M umask(~MAILMODE)
* R file must be S_ISREG()
* X expand() file name before open
*
* Open fd is set close-on-exec.
*/
FILE*
{
int n;
int ignore = 0;
int mask = 0;
int regular = 0;
int verbose = 0;
for (;; mode++) {
switch (*mode) {
case 'E':
verbose = 1;
continue;
case 'I':
ignore = 1;
continue;
case 'M':
mask = 1;
continue;
case 'R':
regular = 1;
continue;
case 'X':
return 0;
continue;
}
break;
}
return fp;
if (mask)
if (mask) {
umask(n);
}
if (fp) {
if (verbose)
return 0;
}
if (verbose)
return 0;
}
if (verbose)
return 0;
}
if (!ignore)
register_file(fp, 0);
#if 0 && MORE_DISCIPLINE
#endif
}
else if (verbose)
return fp;
}
/*
* fdopen() that calls register_file()
*/
FILE*
{
register_file(fp, 0);
}
return fp;
}
/*
* Generate temp file name.
* If fd>0 then create it and return file pointer.
* If fd>0 and buf==0 then remove after create.
*/
FILE*
{
register char* s;
register char* b;
register char* e;
if (!(b = buf)) {
if (fd <= 0)
return 0;
}
e = b + size - 1;
s = strncopy(s, "Mail", e - s);
if (s < e)
*s++ = type;
strncopy(s, "XXXXXX", e - s);
if (fd) {
if (!buf && *b)
remove(b);
if (fd >= 0)
}
}
else
mktemp(b);
if (!*b)
return fp;
}
/*
* Call this after fileopen() or filefd().
*/
int
{
int r;
struct file* p;
return 0;
r = 0;
if (!(p = *pp)) {
return 0;
}
r = p->pid;
free(p);
break;
}
}
if (r) {
holdsigs();
r = wait_command(r);
relsesigs();
}
else
return r;
}
/*
* fileclose() all registered files.
*/
void
fileclear(void)
{
}
/*
* Copy n chars from from file ip to file op.
* If in is specified then input error messages enabled.
* If on is specified then output error messages enabled.
* If lines!=0 then it will point to the copied line count.
* If chars!=0 then it will point to the copied char count.
* If n==0 then all chars copied.
* If n>0 then exactly that many chars are copied.
*
* 0 returned on success.
*/
int
filecopy(const char* in, FILE* ip, const char* on, FILE* op, FILE* ap, register off_t n, register off_t* lines, off_t* chars, unsigned long flags)
{
register off_t c;
register char* s;
int r = 0;
while (n >= 0) {
if (c < 0) {
r = -1;
if (in) {
in = 0;
}
}
break;
}
if (n) {
if (n > c)
n -= c;
else {
c = n;
n = -1;
}
}
r = -1;
if (on) {
on = 0;
}
break;
}
cc += c;
if (ap)
if (lines)
}
r = -1;
if (on)
}
if (n > 0) {
r = -1;
if (in)
}
if (lines)
if (chars)
return r;
}
/*
* Respond to a broken pipe signal --
* probably caused by quitting more.
*/
static void
{
}
/*
* popen() via register_file()
*/
FILE*
{
int myside;
int hisside;
int fd0;
int fd1;
int pid;
int p[2];
int background = 0;
int jump = 0;
if (pipe(p) < 0)
goto bad;
for (;; mode++) {
switch (*mode) {
case 'J':
jump = 1;
continue;
case 'N':
background = 1;
continue;
}
break;
}
if (*mode == 'r') {
fd0 = -1;
}
else {
fd1 = -1;
}
goto bad;
}
goto bad;
if (jump && !background)
return fp;
bad:
return 0;
}
/*
* Run a command without a shell, with optional arguments and splicing
* of stdin and stdout. The command name can be a sequence of words.
* Signals must be handled by the caller.
* critical will mask interesting signals in the new process.
* SIGINT is enabled if critical==0.
*/
int
{
int pid;
int code;
return -1;
return -1;
}
return 0;
}
int
{
int pid;
int savein;
int saveout;
char** args;
char** p;
else {
if (a0) {
if (a1) {
if (a2)
}
}
}
return -1;
}
return -1;
}
}
else infd = -1;
return -1;
}
return -1;
}
}
else
outfd = -1;
for (p = args; *p; p++)
printf(" \"%s\"", *p);
printf("\n");
}
if (critical)
if (critical)
sigcritical(0);
return -1;
}
}
return -1;
}
}
return pid;
}
static struct child*
{
;
}
return *cpp;
}
static void
{
}
/*
* Wait for a specific child to die.
*/
int
wait_command(int pid)
{
int status = -1;
holdsigs();
relsesigs();
return status;
}
/*
* Mark a command as don't care.
*/
void
free_command(int pid)
{
else
}