シリアルI / O付きの古いSVR4ボックスで作業している間、シリアルカード用のドライバはioctl呼び出し(たとえば、ioctl(fd、TIOCMGET、&arg);)を介してTIOCMGETをサポートしていないことがわかりました。ドライバのソースコードを持ってそれを見てください。呼び出しに対する応答を追加することはそれほど難しくないようです。しかし、私がやっていることがうまくいかなかったようで、ちょっとした障害物にぶつかりました。ドライバを見て、TCGETSを提供する次のコードがあります。
case TCGETS:
{ /* immediate parm retrieve */
register struct termios *cb;
if (mp->b_cont) /* Bad user supplied parameter */
freemsg(mp->b_cont);
if (!(bp1 = allocb(sizeof(struct termios), BPRI_MED)))
{
putbq(q, mp);
bufcall(sizeof(struct termios), BPRI_MED, getoblk, (long)tp);
return;
}
mp->b_cont = bp1;
cb = (struct termios *)mp->b_cont->b_rptr;
cb->c_iflag = tp->t_iflag;
cb->c_oflag = tp->t_oflag;
cb->c_cflag = tp->t_cflag;
mp->b_cont->b_wptr += sizeof(struct termios);
mp->b_datap->db_type = M_IOCACK;
iocbp->ioc_count = sizeof(struct termios);
putnext(RD(q), mp);
break;
}
私の考えは、単にこのコードをコピーしてtermios構造を返すのではなくintを返すことです。私のコードは次のとおりです。
case TIOCMGET:
{ /* immediate parm retrieve */
register int *cb;
if (mp->b_cont) /* Bad user supplied parameter */
freemsg(mp->b_cont);
if (!(bp1 = allocb(sizeof(int), BPRI_MED)))
{
putbq(q, mp);
bufcall(sizeof(int), BPRI_MED, getoblk, (long)tp);
return;
}
mp->b_cont = bp1;
cb = (int *)mp->b_cont->b_rptr;
/* my original attempt to get some bits */
*cb = (ql->carrier * TIOCM_CAR | ql->rts * TIOCM_RTS | (ql->lp->command & 1) * TIOCM_DTR)
/* Tried this to debug:
*cb = 0;
Doesn't seem to change the variable I pass in */
/* Tried this, compiles fine,
*(int *)mp->b_cont->b_rptr = 0;
but I get an improper argument passed error while running */
/* qreply(q, mp); not in my code, was a note to try it */
mp->b_cont->b_wptr += sizeof(int);
mp->b_datap->db_type = M_IOCACK;
iocbp->ioc_count = sizeof(int);
putnext(RD(q), mp);
break;
}
前述のように ioctl(fd, TIOCMGET, &arg) を呼び出すと、arg の値は変更されないように見えます。問題が私のビット割り当てコードにある場合に備えて、ゼロ値を返すためにいくつかの異なる試みを試みました。しかし、私は幸運ではありません。
私はTCGETSが正常に動作することを確認するプログラムを書いていましたが、実際に動作します。だから私は何が間違っているのかわかりません。おそらく非常に愚かなことが私の前で起こっていたでしょう。 SVR4とSTREAMSが答えを見つけることができないほど神秘的にならないことを願っています。
質問し、助けてくれた皆さんに感謝します。
表示