int setsid(void) { if (setsid_called != getpid()) { setsid_called = getpid(); return (bc_setsid()); } else { errno = EPERM; return (-1); } }
static int _bc_ioctl(int des, int request, int arg) { int ret; int nreq = (request >> 8) & 0xFF; struct n_sgttyb nsg; struct s5_dk_cinfo newArgs; struct dk_info *infoArgs; struct dk_conf *confArgs; extern int errno; /* not all mappings for 'm' have been performed */ switch (nreq) { case ((int) 't'): if (_ioctl(des, N_I_FIND, "ttcompat") == 0) if (_ioctl(des, N_I_PUSH, "ttcompat") == -1) perror("ioctl/I_PUSH"); switch(request) { case TIOCSETD: /* added for sunview */ return(0); case TIOCREMOTE: request = ('t'<<8)|30; break; case TIOCNOTTY: bc_setsid(); return(0); case TIOCGPGRP: request = ('t'<<8)|20; break; case TIOCSPGRP: { pid_t pgid; sigset_t set, oset; request = ('t'<<8)|21; ret = _ioctl(des, request, arg); /* * SunOS4.x allows this to succeed * even if the process group does * not exist yet. We emulate the 4.x * bug by creating the process group * and reissuing the ioctl(). * See bugid 1175044. */ if (ret != 0 && errno == EPERM && (pgid = *((pid_t *)arg)) != 0 && pgid == getpid() && setpgid(0, pgid) == 0) { sigemptyset(&set); sigaddset(&set, SIGTSTP); sigaddset(&set, SIGTTIN); sigaddset(&set, SIGTTOU); sigprocmask(SIG_BLOCK, &set, &oset); ret = _ioctl(des, request, arg); sigprocmask(SIG_SETMASK, &oset, NULL); } return(ret); } case TIOCSTI: request = ('t'<<8)|23; break; case TIOCSIGNAL: request = ('t'<<8)|31; break; case TIOCCONS: request = ('t'<<8)|36; break; case TIOCSWINSZ: request = ('T'<<8)|103; break; case TIOCGWINSZ: request = ('T'<<8)|104; break; case TIOCSETP: case TIOCSETN: { struct sgttyb *sg = (struct sgttyb *)arg; nsg.sg_ispeed = sg->sg_ispeed; nsg.sg_ospeed = sg->sg_ospeed; nsg.sg_erase = sg->sg_erase; nsg.sg_kill = sg->sg_kill; nsg.sg_flags = (int)sg->sg_flags; arg = (int)&nsg; request = request & 0x0FFFF; break; } case TIOCGETP: { struct sgttyb *sg = (struct sgttyb *)arg; ret = _ioctl(des, request&0xFFFF, &nsg); if (ret != -1) { sg->sg_ispeed = nsg.sg_ispeed; sg->sg_ospeed = nsg.sg_ospeed; sg->sg_erase = nsg.sg_erase; sg->sg_kill = nsg.sg_kill; sg->sg_flags = (short)nsg.sg_flags & 0x0FFFF; } return(ret); } case TIOCPKT: case TIOCUCNTL: case TIOCTCNTL: case TIOCSSOFTCAR: case TIOCGSOFTCAR: case TIOCISPACE: case TIOCISIZE: case TIOCSSIZE: case TIOCGSIZE: break; default: request = request & 0x0FFFF; break; } break; case ((int) 'T'): switch(request) { case TCGETS: request = ('T'<<8)|13; return(tcget(des, request, arg)); break; case TCSETS: request = ('T'<<8)|14; return(tcset(des, request, arg)); break; case TCSETSW: request = ('T'<<8)|15; return(tcset(des, request, arg)); break; case TCSETSF: request = ('T'<<8)|16; return(tcset(des, request, arg)); break; case TCGETA: case TCSETA: case TCSETAW: case TCSETAF: default: request = request & 0x0FFFF; break; } break; case ((int) 'S'): switch (request) { case I_PLINK: request = ('S'<<8)|026; break; case I_PUNLINK: request = ('S'<<8)|027; break; case I_STR: { struct strioctl *iarg = (struct strioctl *)arg; int cmd = iarg->ic_cmd; switch (cmd) { case TI_GETINFO: { /* * The T_info_ack structure * has one additional word * added to it in 5.x. * To prevent the module from * overwritting user memory we * use an internal buffer for * the transfer and copy out * the results to the caller. */ struct { struct T_info_ack info; long pad[16]; } args; char *dp = iarg->ic_dp; memcpy(&args.info, iarg->ic_dp, sizeof(struct T_info_ack)); iarg->ic_dp = (char *) &args.info; iarg->ic_cmd = (TIMOD | 140); ret = _ioctl(des, request & 0xffff, arg); iarg->ic_cmd = cmd; iarg->ic_dp = dp; iarg->ic_len = sizeof(struct T_info_ack); memcpy(iarg->ic_dp, &args.info, iarg->ic_len); return (ret); break; } case TI_OPTMGMT: iarg->ic_cmd = (TIMOD | 141); break; case TI_BIND: iarg->ic_cmd = (TIMOD | 142); break; case TI_UNBIND: iarg->ic_cmd = (TIMOD | 143); break; } ret = _ioctl(des, request & 0xffff, arg); iarg->ic_cmd = cmd; return ret; } default: request = request & 0x0FFFF; break; } break; case ((int) 'm'): switch (request) { case MSIOGETPARMS: request = ('m'<<8)|1; break; case MSIOSETPARMS: request = ('m'<<8)|2; break; default: request = request & 0x0FFFF; break; } break; case ((int) 'd'): switch (request) { case DKIOCGGEOM: request = S5DKIOCGGEOM; break; case DKIOCSGEOM: request = S5DKIOCSGEOM; break; case DKIOCSAPART: request = S5DKIOCSAPART; break; case DKIOCGAPART: request = S5DKIOCGAPART; break; case DKIOCSTYPE: request = S5HDKIOCSTYPE; break; case DKIOCGTYPE: request = S5HDKIOCGTYPE; break; case DKIOCSBAD: request = S5HDKIOCSBAD; break; case DKIOCGBAD: request = S5HDKIOCGBAD; break; case DKIOCSCMD: request = S5HDKIOCSCMD; break; case DKIOCGDIAG: request = S5HDKIOCGDIAG; break; case FDKIOGCHAR: request = S5FDIOGCHAR; break; case FDKIOSCHAR: request = S5FDIOSCHAR; break; case FDKEJECT: request = S5FDEJECT; break; case FDKGETCHANGE: request = S5FDGETCHANGE; break; case FDKGETDRIVECHAR: request = S5FDGETDRIVECHAR; break; case FDKSETDRIVECHAR: request = S5FDSETDRIVECHAR; break; case FDKGETSEARCH: request = S5FDGETSEARCH; break; case FDKSETSEARCH: request = S5FDSETSEARCH; break; case FDKIOCSCMD: request = S5FDIOCMD; break; case F_RAW: request = S5FDRAW; break; case DKIOCINFO: ret = _ioctl(des, S5DKIOCINFO, &newArgs); if (ret != -1) { infoArgs = (struct dk_info *)arg; infoArgs->dki_ctlr = newArgs.dki_addr; infoArgs->dki_unit = newArgs.dki_unit; infoArgs->dki_ctype = newArgs.dki_ctype; infoArgs->dki_flags = newArgs.dki_flags; } return ret; break; case DKIOCGCONF: ret = _ioctl(des, S5DKIOCINFO, &newArgs); if (ret != -1) { confArgs = (struct dk_conf *)arg; strncpy(confArgs->dkc_cname, newArgs.dki_cname, DK_DEVLEN); strncpy(confArgs->dkc_dname, newArgs.dki_dname, DK_DEVLEN); confArgs->dkc_ctype = (u_short)newArgs.dki_ctype; confArgs->dkc_flags = (u_short)newArgs.dki_flags; confArgs->dkc_cnum = newArgs.dki_cnum; confArgs->dkc_addr = newArgs.dki_addr; confArgs->dkc_space = (u_int)newArgs.dki_space; confArgs->dkc_prio = newArgs.dki_prio; confArgs->dkc_vec = newArgs.dki_vec; confArgs->dkc_unit = newArgs.dki_unit; confArgs->dkc_slave = newArgs.dki_slave; } return ret; break; case DKIOCWCHK: /* * This is unsupported in SVR4. It * turns on verify-after-write for * the floppy. I don't think the * system call should fail, however. */ return 0; break; case DKIOCGPART: case DKIOCSPART: return (handle_dkio_partitions(des, request, arg)); case DKIOCGLOG: /* unsupported */ errno = EINVAL; return -1; break; case DESIOCBLOCK: case DESIOCQUICK: break; /* no change for these two */ default: request = request & 0x0FFFF; /* try */ break; } break; case ((int) 'c'): switch (request) { case CDROMPAUSE: request = S5CDROMPAUSE; break; case CDROMRESUME: request = S5CDROMRESUME; break; case CDROMPLAYMSF: request = S5CDROMPLAYMSF; break; case CDROMPLAYTRKIND: request = S5CDROMPLAYTRKIND; break; case CDROMREADTOCHDR: request = S5CDROMREADTOCHDR; break; case CDROMREADTOCENTRY: request = S5CDROMREADTOCENTRY; break; case CDROMSTOP: request = S5CDROMSTOP; break; case CDROMSTART: request = S5CDROMSTART; break; case CDROMEJECT: request = S5CDROMEJECT; break; case CDROMVOLCTRL: request = S5CDROMVOLCTRL; break; case CDROMSUBCHNL: request = S5CDROMSUBCHNL; break; case CDROMREADMODE1: request = S5CDROMREADMODE1; break; case CDROMREADMODE2: request = S5CDROMREADMODE2; break; } break; case ((int) 'u'): switch (request) { case USCSICMD: { struct s5_uscsi_cmd s5_cmd; struct uscsi_cmd *cmd = (struct uscsi_cmd *) arg; request = S5USCSICMD; s5_cmd.uscsi_cdb = cmd->uscsi_cdb; s5_cmd.uscsi_cdblen = cmd->uscsi_cdblen; s5_cmd.uscsi_bufaddr = cmd->uscsi_bufaddr; s5_cmd.uscsi_buflen = cmd->uscsi_buflen; s5_cmd.uscsi_flags = cmd->uscsi_flags; ret = _ioctl(des, request, &s5_cmd); cmd->uscsi_status = s5_cmd.uscsi_status; return(ret); } } break; case ((int) 'k'): case ((int) 'v'): case ((int) 'F'): case ((int) 'G'): case ((int) 'X'): case ((int) 'L'): request = request & 0x0FFFF; break; case ((int) 'f'): if ((request == FIOCLEX) || (request == FIONCLEX)) return(fcntl(des, F_SETFD, ((request == FIOCLEX) ? 1 : 0))); break; case ((int) 'g'): /* Treat the following 2 ioctls specially for * sunview. */ if (request == WINGETEXPOSEDRL || request == WINGETDAMAGEDRL) { ret = _ioctl(des, request, arg); if (errno == N_ENOMSG) errno = EFBIG; return(ret); } break; } return (_ioctl(des, request, arg)); }