summaryrefslogtreecommitdiff
path: root/do/ctl
blob: 543cea83a2f89493a3e98fc4836cb5ee99ee329a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
int
do_ctl(optype,stab,func,argstr)
int optype;
STAB *stab;
int func;
STR *argstr;
{
    register STIO *stio;
    register char *s;
    int retval;

    if (!stab || !argstr || !(stio = stab_io(stab)) || !stio->ifp) {
	errno = EBADF;	/* well, sort of... */
	return -1;
    }

    if (argstr->str_pok || !argstr->str_nok) {
	if (!argstr->str_pok)
	    s = str_get(argstr);

#ifdef IOCPARM_MASK
#ifndef IOCPARM_LEN
#define IOCPARM_LEN(x)  (((x) >> 16) & IOCPARM_MASK)
#endif
#endif
#ifdef IOCPARM_LEN
	retval = IOCPARM_LEN(func);	/* on BSDish systes we're safe */
#else
	retval = 256;			/* otherwise guess at what's safe */
#endif
	if (argstr->str_cur < retval) {
	    Str_Grow(argstr,retval+1);
	    argstr->str_cur = retval;
	}

	s = argstr->str_ptr;
	s[argstr->str_cur] = 17;	/* a little sanity check here */
    }
    else {
	retval = (int)str_gnum(argstr);
#ifdef DOSISH
	s = (char*)(long)retval;		/* ouch */
#else
	s = (char*)retval;		/* ouch */
#endif
    }

#ifndef lint
    if (optype == O_IOCTL)
	retval = ioctl(fileno(stio->ifp), func, s);
    else
#ifdef DOSISH
	fatal("fcntl is not implemented");
#else
#ifdef HAS_FCNTL
	retval = fcntl(fileno(stio->ifp), func, s);
#else
	fatal("fcntl is not implemented");
#endif
#endif
#else /* lint */
    retval = 0;
#endif /* lint */

    if (argstr->str_pok) {
	if (s[argstr->str_cur] != 17)
	    fatal("Return value overflowed string");
	s[argstr->str_cur] = 0;		/* put our null back */
    }
    return retval;
}