da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/***********************************************************************
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* This software is part of the ast package *
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner* Copyright (c) 1982-2010 AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* and is licensed under the *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Common Public License, Version 1.0 *
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin* by AT&T Intellectual Property *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* A copy of the License is available at *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* http://www.opensource.org/licenses/cpl1.0.txt *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* (with md5 checksum 059e8cd6165cb4c31e351f2b69388fd9) *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Information and Software Systems Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* AT&T Research *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* Florham Park NJ *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* David Korn <dgk@research.att.com> *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin* *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin***********************************************************************/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#pragma prototyped
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Input/output file processing
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * David Korn
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * AT&T Labs
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "defs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <fcin.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <ls.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <stdarg.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include <regex.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "variables.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "path.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "io.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "jobs.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "shnodes.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "history.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "edit.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "timeout.h"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/externs"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/dynamic"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#include "FEATURE/poll"
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef FNDELAY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef EAGAIN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if EAGAIN!=EWOULDBLOCK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# undef EAGAIN
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define EAGAIN EWOULDBLOCK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define EAGAIN EWOULDBLOCK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* EAGAIN */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifndef O_NONBLOCK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define O_NONBLOCK FNDELAY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* !O_NONBLOCK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* FNDELAY */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef O_SERVICE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define O_SERVICE O_NOCTTY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define RW_ALL (S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void *timeout;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int (*fdnotify)(int,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(_lib_socket) && defined(_sys_socket) && defined(_hdr_netinet_in)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include <sys/socket.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include <netdb.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# include <netinet/in.h>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if !defined(htons) && !_lib_htons
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define htons(x) (x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if !defined(htonl) && !_lib_htonl
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# define htonl(x) (x)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if _pipe_socketpair
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# ifndef SHUT_RD
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# define SHUT_RD 0
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# ifndef SHUT_WR
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# define SHUT_WR 1
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if _socketpair_shutdown_mode
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# define pipe(v) ((socketpair(AF_UNIX,SOCK_STREAM,0,v)<0||shutdown((v)[1],SHUT_RD)<0||fchmod((v)[1],S_IWUSR)<0||shutdown((v)[0],SHUT_WR)<0||fchmod((v)[0],S_IRUSR)<0)?(-1):0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin# define pipe(v) ((socketpair(AF_UNIX,SOCK_STREAM,0,v)<0||shutdown((v)[1],SHUT_RD)<0||shutdown((v)[0],SHUT_WR)<0)?(-1):0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if !_lib_getaddrinfo
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef EAI_SYSTEM
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define EAI_SYSTEM 1
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef addrinfo
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef getaddrinfo
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef freeaddrinfo
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define addrinfo local_addrinfo
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define getaddrinfo local_getaddrinfo
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define freeaddrinfo local_freeaddrinfo
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct addrinfo
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int ai_flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int ai_family;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int ai_socktype;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int ai_protocol;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin socklen_t ai_addrlen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct sockaddr* ai_addr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct addrinfo* ai_next;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chingetaddrinfo(const char* node, const char* service, const struct addrinfo* hint, struct addrinfo **addr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned long ip_addr = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin unsigned short ip_port = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct addrinfo* ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct hostent* hp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct sockaddr_in* ip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char* prot;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(hp = gethostbyname(node)) || hp->h_addrtype!=AF_INET || hp->h_length>sizeof(struct in_addr))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EADDRNOTAVAIL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return EAI_SYSTEM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ip_addr = (unsigned long)((struct in_addr*)hp->h_addr)->s_addr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((n = strtol(service, &prot, 10)) > 0 && n <= USHRT_MAX && !*prot)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ip_port = htons((unsigned short)n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct servent* sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char* protocol = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (hint)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (hint->ai_socktype)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case SOCK_STREAM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (hint->ai_protocol)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin protocol = "tcp";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef IPPROTO_SCTP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case IPPROTO_SCTP:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin protocol = "sctp";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case SOCK_DGRAM:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin protocol = "udp";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!protocol)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EPROTONOSUPPORT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sp = getservbyname(service, protocol))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ip_port = sp->s_port;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!ip_port)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EADDRNOTAVAIL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return EAI_SYSTEM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(ap = newof(0, struct addrinfo, 1, sizeof(struct sockaddr_in))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return EAI_SYSTEM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (hint)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *ap = *hint;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->ai_family = hp->h_addrtype;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->ai_addrlen = sizeof(struct sockaddr_in);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->ai_addr = (struct sockaddr *)(ap+1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ip = (struct sockaddr_in *)ap->ai_addr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ip->sin_family = AF_INET;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ip->sin_port = ip_port;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ip->sin_addr.s_addr = ip_addr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *addr = ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfreeaddrinfo(struct addrinfo* ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (ap)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(ap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * return <protocol>/<host>/<service> fd
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef int (*Inetintr_f)(struct addrinfo*, void*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chininetopen(const char* path, int server, Inetintr_f onintr, void* handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* s;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char* t;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int oerrno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct addrinfo hint;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct addrinfo* addr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct addrinfo* p;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(&hint, 0, sizeof(hint));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hint.ai_family = PF_UNSPEC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (path[0])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef IPPROTO_SCTP
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (path[1]!='c' || path[2]!='t' || path[3]!='p' || path[4]!='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = ENOTDIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hint.ai_socktype = SOCK_STREAM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hint.ai_protocol = IPPROTO_SCTP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path += 5;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 't':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (path[1]!='c' || path[2]!='p' || path[3]!='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = ENOTDIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hint.ai_socktype = SOCK_STREAM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path += 4;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'u':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (path[1]!='d' || path[2]!='p' || path[3]!='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = ENOTDIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin hint.ai_socktype = SOCK_DGRAM;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin path += 4;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = ENOTDIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!(s = strdup(path)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (t = strchr(s, '/'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *t++ = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (streq(s, "local"))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin s = "localhost";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = getaddrinfo(s, t, &hint, &addr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(s);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fd != EAI_SYSTEM)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = ENOTDIR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oerrno = errno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for (p = addr; p; p = p->ai_next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * some api's don't take the hint
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!p->ai_protocol)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->ai_protocol = hint.ai_protocol;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (!p->ai_socktype)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin p->ai_socktype = hint.ai_socktype;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while ((fd = socket(p->ai_family, p->ai_socktype, p->ai_protocol)) >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (server && !bind(fd, p->ai_addr, p->ai_addrlen) && !listen(fd, 5) || !server && !connect(fd, p->ai_addr, p->ai_addrlen))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (errno != EINTR || !onintr)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((*onintr)(addr, handle))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin done:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin freeaddrinfo(addr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fd >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = oerrno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef O_SERVICE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct fdsave
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int orig_fd; /* original file descriptor */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int save_fd; /* saved file descriptor */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int subshell; /* saved for subshell */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *tname; /* name used with >; */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int subexcept(Sfio_t*, int, void*, Sfdisc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int eval_exceptf(Sfio_t*, int, void*, Sfdisc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int slowexcept(Sfio_t*, int, void*, Sfdisc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int pipeexcept(Sfio_t*, int, void*, Sfdisc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic ssize_t piperead(Sfio_t*, void*, size_t, Sfdisc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic ssize_t slowread(Sfio_t*, void*, size_t, Sfdisc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic ssize_t subread(Sfio_t*, void*, size_t, Sfdisc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic ssize_t tee_write(Sfio_t*,const void*,size_t,Sfdisc_t*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int io_prompt(Sfio_t*,int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int io_heredoc(Shell_t*,register struct ionod*, const char*, int);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void sftrack(Sfio_t*,int,void*);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const Sfdisc_t eval_disc = { NULL, NULL, NULL, eval_exceptf, NULL};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Sfdisc_t tee_disc = {NULL,tee_write,NULL,NULL,NULL};
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Sfio_t *subopen(Shell_t *,Sfio_t*, off_t, long);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const Sfdisc_t sub_disc = { subread, 0, 0, subexcept, 0 };
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct subfile
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdisc_t disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *oldsp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off_t offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin long left;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct Eof
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namfun_t hdr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic Sfdouble_t nget_cur_eof(register Namval_t* np, Namfun_t *fp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct Eof *ep = (struct Eof*)fp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t end, cur =lseek(ep->fd, (Sfoff_t)0, SEEK_CUR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*np->nvname=='C')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((Sfdouble_t)cur);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cur<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((Sfdouble_t)-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin end =lseek(ep->fd, (Sfoff_t)0, SEEK_END);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lseek(ep->fd, (Sfoff_t)0, SEEK_CUR);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return((Sfdouble_t)end);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic const Namdisc_t EOF_disc = { sizeof(struct Eof), 0, 0, nget_cur_eof};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define MATCH_BUFF (64*1024)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct Match
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *base;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int matchf(void *handle, char *ptr, size_t size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct Match *mp = (struct Match*)handle;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mp->offset += (ptr-mp->base);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic struct fdsave *filemap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic short filemapsize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/* ======== input output and file copying ======== */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid sh_ioinit(Shell_t *shp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin filemapsize = 8;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin filemap = (struct fdsave*)malloc(filemapsize*sizeof(struct fdsave));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FASTPIPE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = shp->lim.open_max+2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = shp->lim.open_max;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FASTPIPE */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus = (unsigned char*)malloc((unsigned)n);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memset((char*)shp->fdstatus,0,n);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdptrs = (int**)malloc(n*sizeof(int*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memset((char*)shp->fdptrs,0,n*sizeof(int*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable = (Sfio_t**)malloc(n*sizeof(Sfio_t*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memset((char*)shp->sftable,0,n*sizeof(Sfio_t*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[0] = sfstdin;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[1] = sfstdout;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[2] = sfstderr;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfnotify(sftrack);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iostream(shp,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* all write steams are in the same pool and share outbuff */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->outpool = sfopen(NIL(Sfio_t*),NIL(char*),"sw"); /* pool identifier */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->outbuff = (char*)malloc(IOBSIZE+4);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->errbuff = (char*)malloc(IOBSIZE/4);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfsetbuf(sfstderr,shp->errbuff,IOBSIZE/4);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfsetbuf(sfstdout,shp->outbuff,IOBSIZE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfpool(sfstdout,shp->outpool,SF_WRITE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfpool(sfstderr,shp->outpool,SF_WRITE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(sfstdout,SF_LINE,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfset(sfstderr,SF_LINE,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfset(sfstdin,SF_SHARE|SF_PUBLIC,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin/*
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin * Handle output stream exceptions
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int outexcept(register Sfio_t *iop,int type,void *data,Sfdisc_t *handle)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin static int active = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin NOT_USED(handle);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(type==SF_DPOP || type==SF_FINAL)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin free((void*)handle);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(type==SF_WRITE && (*(ssize_t*)data)<0 && sffileno(iop)!=2)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin switch (errno)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case EINTR:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case EPIPE:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#ifdef ECONNRESET
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case ECONNRESET:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#ifdef ESHUTDOWN
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case ESHUTDOWN:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin default:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!active)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int mode = ((struct checkpt*)sh.jmplist)->mode;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int save = errno;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin active = 1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((struct checkpt*)sh.jmplist)->mode = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfpurge(iop);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfpool(iop,NIL(Sfio_t*),SF_WRITE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errno = save;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin errormsg(SH_DICT,ERROR_system(1),e_badwrite,sffileno(iop));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin active = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ((struct checkpt*)sh.jmplist)->mode = mode;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_exit(1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * create or initialize a stream corresponding to descriptor <fd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * a buffer with room for a sentinal is allocated for a read stream.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * A discipline is inserted when read stream is a tty or a pipe
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * For output streams, the buffer is set to sh.output and put into
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the sh.outpool synchronization pool
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April ChinSfio_t *sh_iostream(Shell_t *shp, register int fd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfio_t *iop;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register int status = sh_iocheckfd(shp,fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flags = SF_WRITE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *bp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Sfdisc_t *dp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FASTPIPE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fd>=shp->lim.open_max)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(shp->sftable[fd]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FASTPIPE */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(status==IOCLOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(fd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 0:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sfstdin);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 1:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sfstdout);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 2:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sfstderr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(Sfio_t*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(status&IOREAD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(bp = (char *)malloc(IOBSIZE+1)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(Sfio_t*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= SF_READ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(status&IOWRITE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= ~SF_WRITE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin bp = shp->outbuff;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(status&IODUP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= SF_SHARE|SF_PUBLIC;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((iop = shp->sftable[fd]) && sffileno(iop)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsetbuf(iop, bp, IOBSIZE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!(iop=sfnew((fd<=2?iop:0),bp,IOBSIZE,fd,flags)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(Sfio_t*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp = newof(0,Sfdisc_t,1,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(status&IOREAD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(iop,SF_MALLOC,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(status&IOWRITE))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfset(iop,SF_IOCHECK,1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp->exceptf = slowexcept;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(status&IOTTY)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp->readf = slowread;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(status&IONOSEEK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp->readf = piperead;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfset(iop, SF_IOINTR,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp->readf = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp->seekf = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp->writef = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dp->exceptf = outexcept;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfpool(iop,shp->outpool,SF_WRITE);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfdisc(iop,dp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[fd] = iop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * preserve the file descriptor or stream by moving it
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void io_preserve(Shell_t* shp, register Sfio_t *sp, register int f2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = sfsetfd(sp,10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = sh_fcntl(f2,F_DUPFD,10);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(f2==shp->infd)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->infd = fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd<0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->toomany = 1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ((struct checkpt*)shp->jmplist)->mode = SH_JMPERREXIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),e_toomany);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->fdptrs[fd]=shp->fdptrs[f2])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(f2==job.fd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.fd=fd;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *shp->fdptrs[fd] = fd;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdptrs[f2] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[fd] = sp;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[fd] = shp->fdstatus[f2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fcntl(f2,F_GETFD,0)&1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcntl(fd,F_SETFD,FD_CLOEXEC);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[fd] |= IOCLEX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[f2] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Given a file descriptor <f1>, move it to a file descriptor number <f2>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * If <f2> is needed move it, otherwise it is closed first.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The original stream <f1> is closed.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The new file descriptor <f2> is returned;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint sh_iorenumber(Shell_t *shp, register int f1,register int f2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Sfio_t *sp = shp->sftable[f2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(f1!=f2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* see whether file descriptor is in use */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_inuse(f2) || (f2>2 && sp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(shp->inuse_bits&(1<<f2)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin io_preserve(shp,sp,f2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(f2==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.ioset = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(f2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(f2<=2 && sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Sfio_t *spnew = sh_iostream(shp,f1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[f2] = (shp->fdstatus[f1]&~IOCLEX);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsetfd(spnew,f2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfswap(spnew,sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(sp,SF_SHARE|SF_PUBLIC,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[f2] = (shp->fdstatus[f1]&~IOCLEX);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((f2 = sh_fcntl(f1,F_DUPFD, f2)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),e_file+4);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(f2 <= 2)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iostream(shp,f2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[f1] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(f1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(f2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * close a file descriptor and update stream table and attributes
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_close(register int fd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfio_t *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int r = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(sp=sh.sftable[fd]) || sfclose(sp) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fdnotify)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fdnotify)(fd,SH_FDCLOSE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r=close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd>2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.sftable[fd] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[fd] = IOCLOSE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.fdptrs[fd])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *sh.fdptrs[fd] = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdptrs[fd] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd < 10)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.inuse_bits &= ~(1<<fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(r);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#ifdef O_SERVICE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinonintr(struct addrinfo* addr, void* handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Shell_t* sh = (Shell_t*)handle;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sh->trapnote&SH_SIGSET)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin freeaddrinfo(addr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exit(SH_EXITSIG);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (sh->trapnote)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_chktrap();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Mimic open(2) with checks for pseudo /dev/ files.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_open(register const char *path, int flags, ...)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int fd = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode_t mode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *e;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin va_list ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin va_start(ap, flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = (flags & O_CREAT) ? va_arg(ap, int) : 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin va_end(ap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*path==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = ENOENT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (path[0]=='/' && path[1]=='d' && path[2]=='e' && path[3]=='v' && path[4]=='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (path[5])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'f':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (path[6]=='d' && path[7]=='/')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = (int)strtol(path+8, &e, 10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (*e)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 's':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (path[6]=='t' && path[7]=='d')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch (path[8])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'e':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (path[9]=='r' && path[10]=='r' && !path[11])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = 2;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'i':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (path[9]=='n' && !path[10])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 'o':
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (path[9]=='u' && path[10]=='t' && !path[11])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef O_SERVICE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fd < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((fd = inetopen(path+5, !!(flags & O_SERVICE), onintr, &sh)) < 0 && errno != ENOTDIR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fd >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto ok;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if (fd >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int nfd= -1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (flags & O_CREAT)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz struct stat st;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if (stat(path,&st) >=0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nfd = open(path,flags,st.st_mode);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz nfd = open(path,flags);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(nfd>=0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fd = nfd;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz goto ok;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((mode=sh_iocheckfd(shp,fd))==IOCLOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= O_ACCMODE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(mode&IOWRITE) && ((flags==O_WRONLY) || (flags==O_RDWR)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(mode&IOREAD) && ((flags==O_RDONLY) || (flags==O_RDWR)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fd=dup(fd))<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz#if SHOPT_REGRESS
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz char buf[PATH_MAX];
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(strncmp(path,"/etc/",5)==0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfsprintf(buf, sizeof(buf), "%s%s", sh_regress_etc(path, __LINE__, __FILE__), path+4);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz path = buf;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz while((fd = open(path, flags, mode)) < 0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(errno!=EINTR || sh.trapnote)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz return(-1);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ok:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags &= O_ACCMODE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flags==O_WRONLY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = IOWRITE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flags==O_RDWR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = (IOREAD|IOWRITE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = IOREAD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[fd] = mode;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Open a file for reading
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * On failure, print message.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_chkopen(register const char *name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int fd = sh_open(name,O_RDONLY,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),e_open,name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * move open file descriptor to a number > 2
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_iomovefd(register int fdold)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int fdnew;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fdold<0 || fdold>2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fdold);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fdnew = sh_iomovefd(dup(fdold));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[fdnew] = (sh.fdstatus[fdold]&~IOCLEX);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin close(fdold);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[fdold] = IOCLOSE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fdnew);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * create a pipe and print message on failure
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_pipe(register int pv[])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fd[2];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pipe(fd)<0 || (pv[0]=fd[0])<0 || (pv[1]=fd[1])<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),e_pipe);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pv[0] = sh_iomovefd(pv[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pv[1] = sh_iomovefd(pv[1]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[pv[0]] = IONOSEEK|IOREAD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[pv[1]] = IONOSEEK|IOWRITE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_subsavefd(pv[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_subsavefd(pv[1]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int pat_seek(void *handle, const char *str, size_t sz)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char **bp = (char**)handle;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *bp = (char*)str;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int pat_line(const regex_t* rp, const char *buff, register size_t n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register const char *cp=buff, *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n>0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(sp=cp; n-->0 && *cp++ != '\n';);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(regnexec(rp,sp,cp-sp, 0, (regmatch_t*)0, 0)==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sp-buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(cp-buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int io_patseek(Shell_t *shp, regex_t *rp, Sfio_t* sp, int flags)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp, *match;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int r, fd=sffileno(sp), close_exec = shp->fdstatus[fd]&IOCLEX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int was_share,s=(PIPE_BUF>SF_BUFSIZE?SF_BUFSIZE:PIPE_BUF);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size_t n,m;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[sffileno(sp)] |= IOCLEX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin was_share = sfset(sp,SF_SHARE,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while((cp=sfreserve(sp, -s, SF_LOCKR)) || (cp=sfreserve(sp,SF_UNBOUND, SF_LOCKR)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = n = sfvalue(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(n>0 && cp[n-1]!='\n')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n--;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = regrexec(rp,cp,m,0,(regmatch_t*)0, 0, '\n', (void*)&match, pat_seek);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(r<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin m = match-cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(r==2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((m = pat_line(rp,cp,m)) < n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(m && (flags&IOCOPY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sfstdout,cp,m);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfread(sp,cp,m);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(r<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!close_exec)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[sffileno(sp)] &= ~IOCLEX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd==0 && !(was_share&SF_SHARE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(sp, SF_SHARE,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Sfoff_t file_offset(Shell_t *shp, int fn, char *fname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Sfio_t *sp = shp->sftable[fn];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t off;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct Eof endf;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *mp = nv_open("EOF",shp->var_tree,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Namval_t *pp = nv_open("CUR",shp->var_tree,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(&endf,0,sizeof(struct Eof));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin endf.fd = fn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin endf.hdr.disc = &EOF_disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin endf.hdr.nofree = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(mp, &endf.hdr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(pp, &endf.hdr);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin off = sh_strnum(fname, &cp, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(mp, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_stack(pp, NiL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(*cp?(Sfoff_t)-1:off);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * close a pipe
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_pclose(register int pv[])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pv[0]>=2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(pv[0]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(pv[1]>=2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(pv[1]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pv[0] = pv[1] = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic char *io_usename(char *name, int *perm, int mode)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin struct stat statb;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *tname, *sp, *ep;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int fd,len,n=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(mode==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((fd = sh_open(name,O_RDONLY,0)) > 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fstat(fd,&statb) < 0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!S_ISREG(statb.st_mode))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *perm = statb.st_mode&(RW_ALL|(S_IXUSR|S_IXGRP|S_IXOTH));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(fd < 0 && errno!=ENOENT)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tname = sp = (char*)stakalloc((len=strlen(name)) + 5);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(ep = strrchr(name,'/'))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memcpy(sp,name,n=++ep-name);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin len -=n;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp += n;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin ep = name;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin *sp++ = '.';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin memcpy(sp,ep,len);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin strcpy(sp+len,".tmp");
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin switch(mode)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 1:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin rename(tname,name);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin case 2:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin unlink(tname);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin break;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(tname);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin}
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * I/O redirection
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * flag = 0 if files are to be restored
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * flag = 2 if files are to be closed on exec
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * flag = 3 when called from $( < ...), just open file and return
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * flag = SH_SHOWME for trace only
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint sh_redirect(Shell_t *shp,struct ionod *iop, int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfoff_t off;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *fname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int fd, iof;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin const char *message = e_open;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int o_mode; /* mode flag for open */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static char io_op[7]; /* used for -x trace info */
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int trunc=0, clexec=0, fn, traceon;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int r, indx = shp->topfd, perm= -1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *tname=0, *after="", *trace = shp->st.trap[SH_DEBUGTRAP];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Namval_t *np=0;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz int isstring = shp->subshell?(sfset(sfstdout,0,0)&SF_STRING):0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin clexec = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin traceon = sh_trace(NIL(char**),0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(;iop;iop=iop->ionxt)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iof=iop->iofile;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fn = (iof&IOUFD);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(fn==1 && shp->subshell && !shp->subshare && (flag==2 || isstring))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_subfork();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[0] = '0'+(iof&IOUFD);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IOPUT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[1] = '>';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin o_mode = O_WRONLY|O_CREAT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[1] = '<';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin o_mode = O_RDONLY|O_NONBLOCK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[2] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[3] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[4] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fname = iop->ioname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(iof&IORAW))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IOLSEEK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct argnod *ap = (struct argnod*)stakalloc(ARGVAL+strlen(iop->ioname));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin memset(ap, 0, ARGVAL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ap->argflag = ARG_MAC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(ap->argval,iop->ioname);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fname=sh_macpat(shp,ap,(iof&IOARITH)?ARG_ARITH:ARG_EXP);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if(iof&IOPROCSUB)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz struct argnod *ap = (struct argnod*)stakalloc(ARGVAL+strlen(iop->ioname));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz memset(ap, 0, ARGVAL);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(iof&IOPUT)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ap->argflag = ARG_RAW;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ap->argchn.ap = (struct argnod*)fname;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ap = sh_argprocsub(shp,ap);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz fname = ap->argval;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fname=sh_mactrim(shp,fname,(!sh_isoption(SH_NOGLOB)&&sh_isoption(SH_INTERACTIVE))?2:0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno=0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop->iovname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin np = nv_open(iop->iovname,shp->var_tree,NV_NOASSIGN|NV_VARNAME);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(nv_isattr(np,NV_RDONLY))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_readonly, nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[0] = '}';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((iof&IOLSEEK) || ((iof&IOMOV) && *fname=='-'))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fn = nv_getnum(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IOLSEEK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[2] = '#';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IOARITH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strcpy(&io_op[3]," ((");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin after = "))";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(iof&IOCOPY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[3] = '#';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto traceit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*fname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IODOC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(traceon)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sfstderr,io_op,'<');
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fd = io_heredoc(shp,iop,fname,traceon);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(traceon && (flag==SH_SHOWME))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fname = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(iof&IOMOV)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int dupfd,toclose= -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[2] = '&';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fd=fname[0])>='0' && fd<='9')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *number = fname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dupfd = strtol(fname,&number,10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*number=='-')
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin toclose = dupfd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin number++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*number || dupfd > IOUFD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin message = e_file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto fail;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(shp->subshell && dupfd==1 && (sfset(sfstdout,0,0)&SF_STRING))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_subtmpfile(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin dupfd = sffileno(sfstdout);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(shp->sftable[dupfd])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfsync(shp->sftable[dupfd]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(fd=='-' && fname[1]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd= -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto traceit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(fd=='p' && fname[1]==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IOPUT)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dupfd = shp->coutpipe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin dupfd = shp->cpipe[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin toclose = dupfd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin message = e_file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto fail;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==SH_SHOWME)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto traceit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fd=sh_fcntl(dupfd,F_DUPFD,3))<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto fail;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iocheckfd(shp,dupfd);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[fd] = (shp->fdstatus[dupfd]&~IOCLEX);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(toclose<0 && shp->fdstatus[fd]&IOREAD)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[fd] |= IODUP;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if(dupfd==shp->cpipe[0])
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_pclose(shp->cpipe);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(toclose>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iosave(shp,toclose,indx,(char*)0); /* save file descriptor */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(toclose);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(iof&IORDW)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_RESTRICTED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_restricted,fname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[2] = '>';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin o_mode = O_RDWR|O_CREAT;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(iof&IOREWRITE)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz trunc = io_op[2] = ';';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto openit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(!(iof&IOPUT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==SH_SHOWME)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto traceit;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd=sh_chkopen(fname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(sh_isoption(SH_RESTRICTED))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(1),e_restricted,fname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IOAPP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[2] = '>';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin o_mode |= O_APPEND;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else if((iof&IOREWRITE) && (flag==0 || flag==1 || sh_subsavefd(fn)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin io_op[2] = ';';
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin o_mode |= O_TRUNC;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin tname = io_usename(fname,&perm,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin o_mode |= O_TRUNC;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IOCLOB)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin io_op[2] = '|';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(sh_isoption(SH_NOCLOBBER))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat sb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(stat(fname,&sb)>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_FS_3D
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(S_ISREG(sb.st_mode)&&
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin (!shp->lim.fs3d || iview(&sb)==0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(S_ISREG(sb.st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_FS_3D */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EEXIST;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),e_exists,fname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin o_mode |= O_EXCL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin openit:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag!=SH_SHOWME)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((fd=sh_open(tname?tname:fname,o_mode,RW_ALL)) <0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),((o_mode&O_CREAT)?e_create:e_open),fname);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(perm>0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if _lib_fchmod
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fchmod(fd,perm);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin chmod(tname,perm);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin traceit:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(traceon && fname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr,"{%s",nv_name(np));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr,"%s %s%s%c",io_op,fname,after,iop->ionxt?' ':'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==SH_SHOWME)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(indx);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(trace && fname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *argv[7], **av=argv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[3] = io_op;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[4] = fname;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[5] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[6] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IOARITH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[5] = after;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[0] = "{";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[1] = nv_name(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av[2] = "}";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin av +=3;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_debug(shp,trace,(char*)0,(char*)0,av,ARG_NOGLOB);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IOLSEEK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Sfio_t *sp = shp->sftable[fn];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r = shp->fdstatus[fn];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(r&(IOSEEK|IONOSEEK)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r = sh_iocheckfd(shp,fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsprintf(io_op,sizeof(io_op),"%d\0",fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(r==IOCLOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fname = io_op;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin message = e_file;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto fail;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iof&IOARITH)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(r&IONOSEEK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fname = io_op;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin message = e_notseek;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto fail;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin message = e_badseek;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((off = file_offset(shp,fn,fname))<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto fail;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin off=sfseek(sp, off, SEEK_SET);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sfsync(sp);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin off=lseek(fn, off, SEEK_SET);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(off<0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin regex_t *rp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin extern const char e_notimp[];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(r&IOREAD))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin message = e_noread;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto fail;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(rp = regcache(fname, REG_SHELL|REG_NOSUB|REG_NEWLINE|REG_AUGMENTED|REG_FIRST|REG_LEFT|REG_RIGHT, &r)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin message = e_badpattern;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto fail;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sp)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp = sh_iostream(shp,fn);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin r=io_patseek(shp,rp,sp,iof);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp && flag==3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* close stream but not fn */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsetfd(sp,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(r<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto fail;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(flag==0 || tname)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd==fn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((r=sh_fcntl(fd,F_DUPFD,10)) > 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh_iosave(shp,fn,indx,tname?fname:(trunc?Empty:0));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(sh_subsavefd(fn))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iosave(shp,fn,indx|IOSUBSHELL,tname?fname:0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
3e14f97f673e8a630f076077de35afdd43dc1587Roger A. Faulkner if(sh_inuse(fn) || (fn && fn==shp->infd))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fn>9 || !(shp->inuse_bits&(1<<fn)))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin io_preserve(shp,shp->sftable[fn],fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(np)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int32_t v;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fn = fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd<10)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fn=fcntl(fd,F_DUPFD,10)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto fail;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[fn] = shp->fdstatus[fd];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = fn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_unset(np);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_onattr(np,NV_INT32);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin v = fn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nv_putval(np,(char*)&v, NV_INT32);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_iocheckfd(shp,fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fd = sh_iorenumber(shp,sh_iomovefd(fd),fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fn>2 && fn<10)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->inuse_bits |= (1<<fn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd >2 && clexec)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcntl(fd,F_SETFD,FD_CLOEXEC);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[fd] |= IOCLEX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto fail;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(indx);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinfail:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),message,fname);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* NOTREACHED */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Create a tmp file for the here-document
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic int io_heredoc(Shell_t *shp,register struct ionod *iop, const char *name, int traceon)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfio_t *infile = 0, *outfile;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int fd;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(iop->iofile&IOSTRG) && (!shp->heredocs || iop->iosize==0))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sh_open(e_devnull,O_RDONLY));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* create an unnamed temporary file */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(outfile=sftmp(0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),e_tmpcreate);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop->iofile&IOSTRG)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(traceon)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr,"< %s\n",name);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(outfile,name,'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin infile = subopen(shp,shp->heredocs,iop->iooffset,iop->iosize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(traceon)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *cp = sh_fmtq(iop->iodelim);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = (*cp=='$' || *cp=='\'')?' ':'\\';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr," %c%s\n",fd,cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfdisc(outfile,&tee_disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(iop->iofile&IOQUOTE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* This is a quoted here-document, not expansion */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfmove(infile,outfile,SF_UNBOUND,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(infile);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *lastpath = shp->lastpath;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_machere(shp,infile,outfile,iop->ioname);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->lastpath = lastpath;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(infile)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(infile);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* close stream outfile, but save file descriptor */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = sffileno(outfile);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsetfd(outfile,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfclose(outfile);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(traceon && !(iop->iofile&IOSTRG))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sfstderr,iop->ioname,'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin lseek(fd,(off_t)0,SEEK_SET);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[fd] = IOREAD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This write discipline also writes the output on standard error
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This is used when tracing here-documents
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic ssize_t tee_write(Sfio_t *iop,const void *buff,size_t n,Sfdisc_t *unused)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(unused);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfwrite(sfstderr,buff,n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(write(sffileno(iop),buff,n));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * copy file <origfd> into a save place
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The saved file is set close-on-exec
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * if <origfd> < 0, then -origfd is saved, but not duped so that it
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * will be closed with sh_iorestore.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid sh_iosave(Shell_t *shp, register int origfd, int oldtop, char *name)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*@
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin assume oldtop>=0 && oldtop<shp->lim.open_max;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin@*/
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int savefd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int flag = (oldtop&IOSUBSHELL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin oldtop &= ~IOSUBSHELL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* see if already saved, only save once */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(savefd=shp->topfd; --savefd>=oldtop; )
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(filemap[savefd].orig_fd == origfd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* make sure table is large enough */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->topfd >= filemapsize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *cp, *oldptr = (char*)filemap;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *oldend = (char*)&filemap[filemapsize];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin long moved;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin filemapsize += 8;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(filemap = (struct fdsave*)realloc(filemap,filemapsize*sizeof(struct fdsave))))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_exit(4),e_nospace);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(moved = (char*)filemap - oldptr)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#if SHOPT_FASTPIPE
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(savefd=shp->lim.open_max+2; --savefd>=0; )
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(savefd=shp->lim.open_max; --savefd>=0; )
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin#endif /* SHOPT_FASTPIPE */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = (char*)shp->fdptrs[savefd];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(cp >= oldptr && cp < oldend)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdptrs[savefd] = (int*)(oldptr+moved);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_DEVFD
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(origfd <0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin savefd = origfd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin origfd = -origfd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* SHOPT_DEVFD */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((savefd = sh_fcntl(origfd, F_DUPFD, 10)) < 0 && errno!=EBADF)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz shp->toomany=1;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ((struct checkpt*)shp->jmplist)->mode = SH_JMPERREXIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),e_toomany);
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin filemap[shp->topfd].tname = name;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin filemap[shp->topfd].subshell = flag;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin filemap[shp->topfd].orig_fd = origfd;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin filemap[shp->topfd++].save_fd = savefd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(savefd >=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin register Sfio_t* sp = shp->sftable[origfd];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* make saved file close-on-exec */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_fcntl(savefd,F_SETFD,FD_CLOEXEC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(origfd==job.fd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.fd = savefd;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[savefd] = shp->fdstatus[origfd];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdptrs[savefd] = &filemap[shp->topfd-1].save_fd;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(shp->sftable[savefd]=sp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsync(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(origfd <=2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* copy standard stream to new stream */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = sfswap(sp,NIL(Sfio_t*));
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[savefd] = sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[origfd] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * close all saved file descriptors
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid sh_iounsave(Shell_t* shp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int fd, savefd, newfd;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for(newfd=fd=0; fd < shp->topfd; fd++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((savefd = filemap[fd].save_fd)< 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin filemap[newfd++] = filemap[fd];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[savefd] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(savefd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->topfd = newfd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * restore saved file descriptors from <last> on
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinvoid sh_iorestore(Shell_t *shp, int last, int jmpval)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int origfd, savefd, fd;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int flag = (last&IOSUBSHELL);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin last &= ~IOSUBSHELL;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for (fd = shp->topfd - 1; fd >= last; fd--)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!flag && filemap[fd].subshell)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(jmpval==SH_JMPSCRIPT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((savefd = filemap[fd].save_fd) >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[savefd] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(savefd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin origfd = filemap[fd].orig_fd;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz if(filemap[fd].tname == Empty && shp->exitval==0)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz ftruncate(origfd,lseek(origfd,0,SEEK_CUR));
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz else if(filemap[fd].tname)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin io_usename(filemap[fd].tname,(int*)0,shp->exitval?2:1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(origfd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if ((savefd = filemap[fd].save_fd) >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_fcntl(savefd, F_DUPFD, origfd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(savefd==job.fd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin job.fd=origfd;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[origfd] = shp->fdstatus[savefd];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* turn off close-on-exec if flag if necessary */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(shp->fdstatus[origfd]&IOCLEX)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcntl(origfd,F_SETFD,FD_CLOEXEC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(origfd<=2)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sfswap(shp->sftable[savefd],shp->sftable[origfd]);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(origfd==0)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->st.ioset = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[origfd] = shp->sftable[savefd];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[savefd] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_close(savefd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[origfd] = IOCLOSE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* keep file descriptors for subshell restore */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin for (fd = last ; fd < shp->topfd; fd++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(filemap[fd].subshell)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin filemap[last++] = filemap[fd];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(last < shp->topfd)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->topfd = last;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns access information on open file <fd>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns -1 for failure, 0 for success
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <mode> is the same as for access()
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_ioaccess(int fd,register int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==X_OK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((flags=sh_iocheckfd(shp,fd))!=IOCLOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==F_OK)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==R_OK && (flags&IOREAD))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==W_OK && (flags&IOWRITE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Handle interrupts for slow streams
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int slowexcept(register Sfio_t *iop,int type,void *data,Sfdisc_t *handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int n,fno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(handle);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==SF_DPOP || type==SF_FINAL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)handle);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type!=SF_READ)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((sh.trapnote&(SH_SIGSET|SH_SIGTRAP)) && errno!=EIO && errno!=ENXIO)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EINTR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fno = sffileno(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=sfvalue(iop))<=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifndef FNDELAY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# ifdef O_NDELAY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(errno==0 && (n=fcntl(fno,F_GETFL,0))&O_NDELAY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n &= ~O_NDELAY;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcntl(fno, F_SETFL, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* O_NDELAY */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* !FNDELAY */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef O_NONBLOCK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(errno==EAGAIN)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = fcntl(fno,F_GETFL,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n &= ~O_NONBLOCK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcntl(fno, F_SETFL, n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* O_NONBLOCK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(errno!=EINTR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n=1;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_onstate(SH_TTYWAIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sh.bltinfun && sh.bltindata.sigset)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.trapnote&SH_SIGSET)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(isatty(fno))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sfstderr,'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_exit(SH_EXITSIG);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.trapnote&SH_SIGTRAP)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_chktrap();
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * called when slowread times out
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic void time_grace(void *handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(handle);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timeout = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_GRACE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_offstate(SH_GRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh_isstate(SH_INTERACTIVE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ((struct checkpt*)sh.jmplist)->mode = SH_JMPEXIT;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,2,e_timeout);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.trapnote |= SH_SIGSET;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,0,e_timewarn);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh_onstate(SH_GRACE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sigrelease(SIGALRM);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.trapnote |= SH_SIGTRAP;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic ssize_t piperead(Sfio_t *iop,void *buff,register size_t size,Sfdisc_t *handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fd = sffileno(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(handle);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(job.waitsafe && job.savesig)
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz {
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz job_lock();
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz job_unlock();
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.trapnote)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EINTR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_INTERACTIVE) && io_prompt(iop,sh.nextprompt)<0 && errno==EIO)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_onstate(SH_TTYWAIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(sh.fdstatus[sffileno(iop)]&IOCLEX) && (sfset(iop,0,0)&SF_SHARE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = ed_read(sh.ed_context, fd, (char*)buff, size,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = sfrd(iop,buff,size,handle);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sh_offstate(SH_TTYWAIT);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This is the read discipline that is applied to slow devices
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine takes care of prompting for input
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic ssize_t slowread(Sfio_t *iop,void *buff,register size_t size,Sfdisc_t *handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int (*readf)(void*, int, char*, int, int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int reedit=0, rsize;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_HISTEXPAND
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *xp=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(handle);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if SHOPT_ESH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_EMACS) || sh_isoption(SH_GMACS))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin readf = ed_emacsread;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* SHOPT_ESH */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if SHOPT_VSH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# if SHOPT_RAWONLY
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_VI) || ((SHOPT_RAWONLY-0) && mbwide()))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isoption(SH_VI))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin readf = ed_viread;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin# endif /* SHOPT_VSH */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin readf = ed_read;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.trapnote)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EINTR;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(io_prompt(iop,sh.nextprompt)<0 && errno==EIO)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.timeout)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timeout = (void*)sh_timeradd(sh_isstate(SH_GRACE)?1000L*TGRACE:1000L*sh.timeout,0,time_grace,NIL(void*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rsize = (*readf)(sh.ed_context, sffileno(iop), (char*)buff, size, reedit);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(timeout)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timerdel(timeout);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin timeout=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if SHOPT_HISTEXPAND
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(rsize && *(char*)buff != '\n' && sh.nextprompt==1 && sh_isoption(SH_HISTEXPAND))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int r;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ((char*)buff)[rsize] = '\0';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(xp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free(xp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin xp = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin r = hist_expand(buff, &xp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((r & (HIST_EVENT|HIST_PRINT)) && !(r & HIST_ERROR) && xp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin strlcpy(buff, xp, size);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rsize = strlen(buff);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh_isoption(SH_HISTVERIFY) || readf==ed_read)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sfstderr, xp, -1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reedit = rsize - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((r & HIST_ERROR) && sh_isoption(SH_HISTREEDIT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin reedit = rsize - 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin continue;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(r & (HIST_ERROR|HIST_PRINT))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *(char*)buff = '\n';
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin rsize = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(rsize);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * check and return the attributes for a file descriptor
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinint sh_iocheckfd(Shell_t *shp, register int fd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flags, n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=sh.fdstatus[fd])&IOCLOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(n&(IOREAD|IOWRITE)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef F_GETFL
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((flags=fcntl(fd,F_GETFL,0)) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sh.fdstatus[fd]=IOCLOSE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((flags&O_ACCMODE)!=O_WRONLY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n |= IOREAD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((flags&O_ACCMODE)!=O_RDONLY)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n |= IOWRITE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat statb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((flags = fstat(fd,&statb))< 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sh.fdstatus[fd]=IOCLOSE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n |= (IOREAD|IOWRITE);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(read(fd,"",0) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n &= ~IOREAD;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* F_GETFL */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(n&(IOSEEK|IONOSEEK)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct stat statb;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* /dev/null check is a workaround for select bug */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static ino_t null_ino;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static dev_t null_dev;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(null_ino==0 && stat(e_devnull,&statb) >=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin null_ino = statb.st_ino;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin null_dev = statb.st_dev;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(tty_check(fd))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n |= IOTTY;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(lseek(fd,NIL(off_t),SEEK_CUR)<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n |= IONOSEEK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef S_ISSOCK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((fstat(fd,&statb)>=0) && S_ISSOCK(statb.st_mode))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n |= IOREAD|IOWRITE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* S_ISSOCK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if((fstat(fd,&statb)>=0) && (
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin S_ISFIFO(statb.st_mode) ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef S_ISSOCK
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin S_ISSOCK(statb.st_mode) ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* S_ISSOCK */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* The following is for sockets on the sgi */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (statb.st_ino==0 && (statb.st_mode & ~(S_IRUSR|S_IRGRP|S_IROTH|S_IWUSR|S_IWGRP|S_IWOTH|S_IXUSR|S_IXGRP|S_IXOTH|S_ISUID|S_ISGID))==0) ||
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (S_ISCHR(statb.st_mode) && (statb.st_ino!=null_ino || statb.st_dev!=null_dev))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n |= IONOSEEK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n |= IOSEEK;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[fd] = n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(n);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Display prompt PS<flag> on standard error
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int io_prompt(Sfio_t *iop,register int flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char buff[1];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *endprompt;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin static short cmdno;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int sfflags;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag<3 && !sh_isstate(SH_INTERACTIVE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==2 && sfpkrd(sffileno(iop),buff,1,'\n',0,1) >= 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sfsync(sfstderr));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfflags = sfset(sfstderr,SF_SHARE|SF_PUBLIC|SF_READ,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(sh.prompt=(char*)sfreserve(sfstderr,0,0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.prompt = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(flag)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 1:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int c;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#if defined(TIOCLBIC) && defined(LFLUSHO)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!sh_isoption(SH_VI) && !sh_isoption(SH_EMACS) && !sh_isoption(SH_GMACS))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * re-enable output in case the user has
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * disabled it. Not needed with edit mode
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int mode = LFLUSHO;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ioctl(sffileno(sfstderr),TIOCLBIC,&mode);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif /* TIOCLBIC */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = sh_mactry(shp,nv_getval(sh_scoped(shp,PS1NOD)));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(;c= *cp;cp++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==HIST_CHAR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* look at next character */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin c = *++cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* print out line number if not !! */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c!= HIST_CHAR)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(sfstderr,"%d", sh.hist_ptr?(int)sh.hist_ptr->histind:++cmdno);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(c==0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(sfstderr,c);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 2:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = nv_getval(sh_scoped(shp,PS2NOD));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case 3:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin cp = nv_getval(sh_scoped(shp,PS3NOD));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto done;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputr(sfstderr,cp,-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chindone:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(*sh.prompt && (endprompt=(char*)sfreserve(sfstderr,0,0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin *endprompt = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfset(sfstderr,sfflags&SF_READ|SF_SHARE|SF_PUBLIC,1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sfsync(sfstderr));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This discipline is inserted on write pipes to prevent SIGPIPE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * from causing an infinite loop
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int pipeexcept(Sfio_t* iop, int mode, void *data, Sfdisc_t* handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==SF_DPOP || mode==SF_FINAL)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)handle);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mode==SF_WRITE && errno==EINTR && sh.lastsig==SIGPIPE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * keep track of each stream that is opened and closed
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic void sftrack(Sfio_t* sp, int flag, void* data)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int fd = sffileno(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct checkpt *pp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int mode;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin int newfd = integralof(data);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==SF_SETFD || flag==SF_CLOSING)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(newfd<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = SF_CLOSING;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fdnotify)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fdnotify)(sffileno(sp),flag==SF_CLOSING?-1:newfd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef DEBUG
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==SF_READ || flag==SF_WRITE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char *z = fmtbase((long)getpid(),0,0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin write(ERRIO,z,strlen(z));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin write(ERRIO,": ",2);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin write(ERRIO,"attempt to ",11);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==SF_READ)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin write(ERRIO,"read from",9);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin write(ERRIO,"write to",8);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin write(ERRIO," locked stream\n",15);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((unsigned)fd >= shp->lim.open_max)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh_isstate(SH_NOTRACK))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin mode = sfset(sp,0,0);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(sp==shp->heredocs && fd < 10 && flag==SF_NEW)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = sfsetfd(sp,10);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fcntl(fd,F_SETFD,FD_CLOEXEC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd < 3)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(flag==SF_NEW)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!shp->sftable[fd] && shp->fdstatus[fd]==IOCLOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[fd] = sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag = (mode&SF_WRITE)?IOWRITE:0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode&SF_READ)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flag |= IOREAD;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[fd] = flag;
34f9b3eef6fdadbda0a846aa4d68691ac40eace5Roland Mainz sh_iostream(shp,fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if((pp=(struct checkpt*)shp->jmplist) && pp->mode==SH_JMPCMD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct openlist *item;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * record open file descriptors so they can
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * be closed in case a longjmp prevents
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * built-ins from cleanup
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin item = new_of(struct openlist, 0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin item->strm = sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin item->next = pp->olist;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin pp->olist = item;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fdnotify)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fdnotify)(-1,sffileno(sp));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(flag==SF_CLOSING || (flag==SF_SETFD && newfd<=2))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->sftable[fd] = 0;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin shp->fdstatus[fd]=IOCLOSE;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(pp=(struct checkpt*)shp->jmplist)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin struct openlist *item;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(item=pp->olist; item; item=item->next)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(item->strm == sp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin item->strm = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstruct eval
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfdisc_t disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char **argv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin short slen;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin char addspace;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin};
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * Create a stream consisting of a space separated argv[] list
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t *sh_sfeval(register char *argv[])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfio_t *iop;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argv[1])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = "";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = argv[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin iop = sfopen(NIL(Sfio_t*),(char*)cp,"s");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argv[1])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct eval *ep;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(ep = new_of(struct eval,0)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(Sfio_t*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->disc = eval_disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->argv = argv;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->slen = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->addspace = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfdisc(iop,&ep->disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This code gets called whenever an end of string is found with eval
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int eval_exceptf(Sfio_t *iop,int type, void *data, Sfdisc_t *handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct eval *ep = (struct eval*)handle;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char *cp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int len;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* no more to do */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type!=SF_READ || !(cp = ep->argv[0]))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(type==SF_CLOSING)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfdisc(iop,SF_POPDISC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(ep && (type==SF_DPOP || type==SF_FINAL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)ep);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!ep->addspace)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* get the length of this string */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->slen = len = strlen(cp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* move to next string */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->argv++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else /* insert space between arguments */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin len = 1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin cp = " ";
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin /* insert the new string */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfsetbuf(iop,cp,len);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ep->addspace = !ep->addspace;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * This routine returns a stream pointer to a segment of length <size> from
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * the stream <sp> starting at offset <offset>
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * The stream can be read with the normal stream operations
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chinstatic Sfio_t *subopen(Shell_t *shp,Sfio_t* sp, off_t offset, long size)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct subfile *disp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sfseek(sp,offset,SEEK_SET) <0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(Sfio_t*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(!(disp = (struct subfile*)malloc(sizeof(struct subfile)+IOBSIZE+1)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(NIL(Sfio_t*));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin disp->disc = sub_disc;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin disp->oldsp = sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin disp->offset = offset;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin disp->size = disp->left = size;
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin sp = sfnew(NIL(Sfio_t*),(char*)(disp+1),IOBSIZE,shp->lim.open_max,SF_READ);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfdisc(sp,&disp->disc);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * read function for subfile discipline
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic ssize_t subread(Sfio_t* sp,void* buff,register size_t size,Sfdisc_t* handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct subfile *disp = (struct subfile*)handle;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin NOT_USED(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(disp->left == 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(size > disp->left)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin size = disp->left;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin disp->left -= size;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sfread(disp->oldsp,buff,size));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * exception handler for subfile discipline
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinstatic int subexcept(Sfio_t* sp,register int mode, void *data, Sfdisc_t* handle)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register struct subfile *disp = (struct subfile*)handle;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==SF_CLOSING)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfdisc(sp,SF_POPDISC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(disp && (mode==SF_DPOP || mode==SF_FINAL))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin free((void*)disp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef SF_ATEXIT
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if (mode==SF_ATEXIT)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfdisc(sp, SF_POPDISC);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else if(mode==SF_READ)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(-1);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define NROW 15 /* number of rows before going to multi-columns */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#define LBLSIZ 3 /* size of label field and interfield spacing */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * print a list of arguments in columns
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinvoid sh_menu(Sfio_t *outfile,int argn,char *argv[])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int i,j;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register char **arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int nrow, ncol=1, ndigits=1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int fldsize, wsize = ed_window();
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin char *cp = nv_getval(sh_scoped(shp,LINES));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nrow = (cp?1+2*((int)strtol(cp, (char**)0, 10)/3):NROW);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(i=argn;i >= 10;i /= 10)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ndigits++;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argn < nrow)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nrow = argn;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin goto skip;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(arg=argv; *arg;arg++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((j=strlen(*arg)) > i)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i = j;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin i += (ndigits+LBLSIZ);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(i < wsize)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ncol = wsize/i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(argn > nrow*ncol)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nrow = 1 + (argn-1)/ncol;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin ncol = 1 + (argn-1)/nrow;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin nrow = 1 + (argn-1)/ncol;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinskip:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fldsize = (wsize/ncol)-(ndigits+LBLSIZ);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin for(i=0;i<nrow;i++)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.trapnote&SH_SIGSET)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin j = i;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin while(1)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin arg = argv+j;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfprintf(outfile,"%*d) %s",ndigits,j+1,*arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin j += nrow;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(j >= argn)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfnputc(outfile,' ',fldsize-strlen(*arg));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sfputc(outfile,'\n');
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef read
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * shell version of read() for user added builtins
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t sh_read(register int fd, void* buff, size_t n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfio_t *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp=sh.sftable[fd])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sfread(sp,buff,n));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(read(fd,buff,n));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef write
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * shell version of write() for user added builtins
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinssize_t sh_write(register int fd, const void* buff, size_t n)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfio_t *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sp=sh.sftable[fd])
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sfwrite(sp,buff,n));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(write(fd,buff,n));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef lseek
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * shell version of lseek() for user added builtins
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinoff_t sh_seek(register int fd, off_t offset, int whence)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register Sfio_t *sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((sp=sh.sftable[fd]) && (sfset(sp,0,0)&(SF_READ|SF_WRITE)))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sfseek(sp,offset,whence));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(lseek(fd,offset,whence));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef dup
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_dup(register int old)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int fd = dup(old);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd>=0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.fdstatus[old] == IOCLOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[old] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[fd] = (sh.fdstatus[old]&~IOCLEX);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fdnotify)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fdnotify)(old,fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef fcntl
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinint sh_fcntl(register int fd, int op, ...)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int newfd, arg;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin va_list ap;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin va_start(ap, op);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin arg = va_arg(ap, int) ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin va_end(ap);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin newfd = fcntl(fd,op,arg);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(newfd>=0) switch(op)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case F_DUPFD:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.fdstatus[fd] == IOCLOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[fd] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[newfd] = (sh.fdstatus[fd]&~IOCLEX);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fdnotify)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin (*fdnotify)(fd,newfd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case F_SETFD:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(sh.fdstatus[fd] == IOCLOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[fd] = 0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(arg&FD_CLOEXEC)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[fd] |= IOCLEX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.fdstatus[fd] &= ~IOCLEX;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(newfd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#undef umask
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinmode_t sh_umask(mode_t m)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.mask = m;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(umask(m));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin/*
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * give file descriptor <fd> and <mode>, return an iostream pointer
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <mode> must be SF_READ or SF_WRITE
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * <fd> must be a non-negative number ofr SH_IOCOPROCESS or SH_IOHISTFILE.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin * returns NULL on failure and may set errno.
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin */
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t *sh_iogetiop(int fd, int mode)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *iop=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode!=SF_READ && mode!=SF_WRITE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EINVAL;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin switch(fd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case SH_IOHISTFILE:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!sh_histinit((void*)shp))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(iop);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fd = sffileno(shp->hist_ptr->histfp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin case SH_IOCOPROCESS:
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==SF_WRITE)
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fd = shp->coutpipe;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin else
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin fd = shp->cpipe[0];
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin break;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin default:
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(fd<0 || fd >= shp->lim.open_max)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fd = -1;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(fd<0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errno = EBADF;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(n=shp->fdstatus[fd]))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin n = sh_iocheckfd(shp,fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==SF_WRITE && !(n&IOWRITE))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(mode==SF_READ && !(n&IOREAD))
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(iop);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!(iop = shp->sftable[fd]))
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin iop=sh_iostream(shp,fd);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(iop);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chintypedef int (*Notify_f)(int,int);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinNotify_f sh_fdnotify(Notify_f notify)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Notify_f old;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin old = fdnotify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin fdnotify = notify;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(old);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t *sh_fd2sfio(int fd)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int status;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin Sfio_t *sp = sh.sftable[fd];
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin if(!sp && (status = sh_iocheckfd(shp,fd))!=IOCLOSE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin {
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin register int flags=0;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(status&IOREAD)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= SF_READ;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(status&IOWRITE)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin flags |= SF_WRITE;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sp = sfnew(NULL, NULL, -1, fd,flags);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin sh.sftable[fd] = sp;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin }
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin return(sp);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chinSfio_t *sh_pathopen(const char *cp)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin{
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin Shell_t *shp = &sh;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin int n;
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#ifdef PATH_BFPATH
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=path_open(cp,path_get(cp))) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = path_open(cp,(Pathcomp_t*)0);
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#else
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if((n=path_open(cp,path_get(cp))) < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin n = path_open(cp,"");
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin#endif
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin if(n < 0)
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin errormsg(SH_DICT,ERROR_system(1),e_open,cp);
7c2fbfb345896881c631598ee3852ce9ce33fb07April Chin return(sh_iostream(shp,n));
da2e3ebdc1edfbc5028edf1354e7dd2fa69a7968chin}