int spool_open_temp(uschar *temp_name) { int fd = Uopen(temp_name, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE); /* If the file already exists, something has gone wrong. This process may well have previously created the file if it is delivering more than one address, but it should have renamed it almost immediately. A file could, however, be left around as a result of a system crash, and by coincidence this process might have the same pid. We therefore have one go at unlinking it before giving up. */ if (fd < 0 && errno == EEXIST) { DEBUG(D_any) debug_printf("%s exists: unlinking\n", temp_name); Uunlink(temp_name); fd = Uopen(temp_name, O_RDWR|O_CREAT|O_EXCL, SPOOL_MODE); } /* If the file has been opened, make sure the file's group is the Exim gid, and double-check the mode because the group setting doesn't always get set automatically. */ if (fd >= 0) if (fchown(fd, exim_uid, exim_gid) || fchmod(fd, SPOOL_MODE)) { DEBUG(D_any) debug_printf("failed setting perms on %s\n", temp_name); (void) close(fd); fd = -1; Uunlink(temp_name); } return fd; }
static BOOL break_link(uschar *dir, uschar *subdir, uschar *id, uschar *suffix, uschar *from, BOOL noentok) { uschar f[256]; sprintf(CS f, "%s/%s%s/%s/%s%s", spool_directory, from, dir, subdir, id, suffix); if (Uunlink(f) < 0 && (!noentok || errno != ENOENT)) { log_write(0, LOG_MAIN|LOG_PANIC, "unlink(\"%s\") failed while moving " "message: %s", f, strerror(errno)); return FALSE; } return TRUE; }
static int spool_write_error(int where, uschar **errmsg, uschar *s, uschar *temp_name, FILE *f) { uschar *msg = (where == SW_RECEIVING)? string_sprintf("spool file %s error while receiving from %s: %s", s, (sender_fullhost != NULL)? sender_fullhost : sender_ident, strerror(errno)) : string_sprintf("spool file %s error while %s: %s", s, (where == SW_DELIVERING)? "delivering" : "modifying", strerror(errno)); if (temp_name != NULL) Uunlink(temp_name); if (f != NULL) (void)fclose(f); if (errmsg == NULL) log_write(0, LOG_MAIN|LOG_PANIC_DIE, "%s", msg); else *errmsg = msg; return -1; }
A2(PUBLIC, OSErr, ROMlib_serialopen, ParmBlkPtr, pbp, /* INTERNAL */ DCtlPtr, dcp) { OSErr err; auto DCtlPtr otherp; /* auto due to old compiler bug */ hiddenh h; #if defined (LINUX) || defined (NEXTSTEP) const char *devname, *tempname; LONGINT fd, ourpid, theirpid, newfd, oumask; #endif err = noErr; if (!(dcp->dCtlFlags & CWC(OPENBIT))) { h = (hiddenh) NewHandle(sizeof(hidden)); dcp->dCtlStorage = (Handle) RM(h); otherp = otherdctl(pbp); if (otherp && (otherp->dCtlFlags & CWC(OPENBIT))) { *STARH(h) = *STARH((hiddenh) (long) MR(otherp->dCtlStorage)); dcp->dCtlFlags |= CWC(OPENBIT); } else { #if defined (LINUX) || defined (NEXTSTEP) err = permErr; if ((devname = specialname(pbp, &lockname, &tempname))) { oumask = umask(0); if (!tempname) err = noErr; else if ((fd = Uopen(tempname, O_BINARY|O_CREAT|O_WRONLY, 0666L)) >= 0) { ourpid = getpid(); if (write(fd, &ourpid, sizeof(ourpid)) == sizeof(ourpid)) { if (Ulink(tempname, lockname) == 0) err = noErr; else { if ((newfd = Uopen(lockname, O_BINARY|O_RDWR, 0)) >= 0) { if (read(newfd, &theirpid, sizeof(theirpid)) == sizeof(theirpid)) if ((kill(theirpid, 0) != 0) && errno == ESRCH) { err = noErr; Uunlink(lockname); Ulink(tempname, lockname); } close(newfd); } } Uunlink(tempname); } close(fd); } umask(oumask); } #endif if (err == noErr) { #if defined (LINUX) || defined (NEXTSTEP) HxX(h, fd) = ROMlib_priv_open(devname, O_BINARY|O_RDWR); if (HxX(h, fd) < 0) err = HxX(h, fd); /* error return piggybacked */ else { #if defined(TERMIO) err = ioctl(HxX(h, fd), TCGETA, &HxX(h, state)) < 0 ? ROMlib_maperrno() : noErr; #else if (ioctl(HxX(h, fd), TIOCGETP, &HxX(h, sgttyb)) < 0 || ioctl(HxX(h, fd), TIOCGETC, &HxX(h, tchars)) < 0 || ioctl(HxX(h, fd), TIOCLGET, &HxX(h, lclmode)) < 0) err = ROMlib_maperrno(); #endif #else HxX(h, fd) = (CW(pbp->cntrlParam.ioCRefNum) == AINREFNUM || CW(pbp->cntrlParam.ioCRefNum) == AOUTREFNUM) ? 0 : 1; #endif dcp->dCtlFlags |= CWC(OPENBIT); SerReset(CW(pbp->cntrlParam.ioCRefNum), (CW(pbp->cntrlParam.ioCRefNum) == AINREFNUM || CW(pbp->cntrlParam.ioCRefNum) == AOUTREFNUM) ? CW(SPPortA) : CW(SPPortB)); #if defined (LINUX) || defined (NEXTSTEP) } #endif } } } #if defined(SERIALDEBUG) warning_trace_info("serial open returning %d", (LONGINT) err); #endif DOCOMPLETION(pbp, err); }