1109 tsignal(curthread, SIGPIPE);
1110 return (error);
1111 }
1112
1113 /*ARGSUSED6*/
1114 static int
1115 fifo_ioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1116 cred_t *cr, int *rvalp, caller_context_t *ct)
1117 {
1118 /*
1119 * Just a quick check
1120 * Once we go to streams mode we don't ever revert back
1121 * So we do this quick check so as not to incur the overhead
1122 * associated with acquiring the lock
1123 */
1124 return ((VTOF(vp)->fn_flag & FIFOFAST) ?
1125 fifo_fastioctl(vp, cmd, arg, mode, cr, rvalp) :
1126 fifo_strioctl(vp, cmd, arg, mode, cr, rvalp));
1127 }
1128
1129 static int
1130 fifo_fastioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1131 cred_t *cr, int *rvalp)
1132 {
1133 fifonode_t *fnp = VTOF(vp);
1134 fifonode_t *fn_dest;
1135 int error = 0;
1136 fifolock_t *fn_lock = fnp->fn_lock;
1137 int cnt;
1138
1139 /*
1140 * tty operations not allowed
1141 */
1142 if (((cmd & IOCTYPE) == LDIOC) ||
1143 ((cmd & IOCTYPE) == tIOC) ||
1144 ((cmd & IOCTYPE) == TIOC)) {
1145 return (EINVAL);
1146 }
1147
1148 mutex_enter(&fn_lock->flk_lock);
1328 * (waking readers probably doesn't make sense, but it
1329 * doesn't hurt; i.e. we just got rid of all the data
1330 * what's to read ?)
1331 */
1332 if (fn_dest->fn_flag & (FIFOWANTW | FIFOWANTR)) {
1333 fn_dest->fn_flag &= ~(FIFOWANTW | FIFOWANTR);
1334 cv_broadcast(&fn_dest->fn_wait_cv);
1335 }
1336 *rvalp = 0;
1337 break;
1338
1339 /*
1340 * Since no band data can ever get on a fifo in fast mode
1341 * just return 0.
1342 */
1343 case I_FLUSHBAND:
1344 error = 0;
1345 *rvalp = 0;
1346 break;
1347
1348 /*
1349 * invalid calls for stream head or fifos
1350 */
1351
1352 case I_POP: /* shouldn't happen */
1353 case I_LOOK:
1354 case I_LINK:
1355 case I_PLINK:
1356 case I_UNLINK:
1357 case I_PUNLINK:
1358
1359 /*
1360 * more invalid tty type of ioctls
1361 */
1362
1363 case SRIOCSREDIR:
1364 case SRIOCISREDIR:
1365 error = EINVAL;
1366 break;
1367
1375 stream_mode:
1376 /*
1377 * streams mode
1378 */
1379 mutex_exit(&fn_lock->flk_lock);
1380 return (fifo_strioctl(vp, cmd, arg, mode, cr, rvalp));
1381
1382 }
1383
1384 /*
1385 * FIFO is in STREAMS mode; STREAMS framework does most of the work.
1386 */
1387 static int
1388 fifo_strioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1389 cred_t *cr, int *rvalp)
1390 {
1391 fifonode_t *fnp = VTOF(vp);
1392 int error;
1393 fifolock_t *fn_lock;
1394
1395 if (cmd == _I_GETPEERCRED) {
1396 if (mode == FKIOCTL && fnp->fn_pcredp != NULL) {
1397 k_peercred_t *kp = (k_peercred_t *)arg;
1398 crhold(fnp->fn_pcredp);
1399 kp->pc_cr = fnp->fn_pcredp;
1400 kp->pc_cpid = fnp->fn_cpid;
1401 return (0);
1402 } else {
1403 return (ENOTSUP);
1404 }
1405 }
1406
1407 error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp);
1408
1409 switch (cmd) {
1410 /*
1411 * The FIFOSEND flag is set to inform other processes that a file
1412 * descriptor is pending at the stream head of this pipe.
1413 * The flag is cleared and the sending process is awoken when
1414 * this process has completed receiving the file descriptor.
1415 * XXX This could become out of sync if the process does I_SENDFDs
1416 * and opens on connld attached to the same pipe.
1417 */
1418 case I_RECVFD:
1419 case I_E_RECVFD:
1420 if (error == 0) {
1421 fn_lock = fnp->fn_lock;
1422 mutex_enter(&fn_lock->flk_lock);
1423 if (fnp->fn_flag & FIFOSEND) {
1424 fnp->fn_flag &= ~FIFOSEND;
1425 cv_broadcast(&fnp->fn_dest->fn_wait_cv);
|
1109 tsignal(curthread, SIGPIPE);
1110 return (error);
1111 }
1112
1113 /*ARGSUSED6*/
1114 static int
1115 fifo_ioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1116 cred_t *cr, int *rvalp, caller_context_t *ct)
1117 {
1118 /*
1119 * Just a quick check
1120 * Once we go to streams mode we don't ever revert back
1121 * So we do this quick check so as not to incur the overhead
1122 * associated with acquiring the lock
1123 */
1124 return ((VTOF(vp)->fn_flag & FIFOFAST) ?
1125 fifo_fastioctl(vp, cmd, arg, mode, cr, rvalp) :
1126 fifo_strioctl(vp, cmd, arg, mode, cr, rvalp));
1127 }
1128
1129 static inline int
1130 fifo_ioctl_getpeercred(fifonode_t *fnp, intptr_t arg, int mode)
1131 {
1132 k_peercred_t *kp = (k_peercred_t *)arg;
1133
1134 if (mode == FKIOCTL && fnp->fn_pcredp != NULL) {
1135 crhold(fnp->fn_pcredp);
1136 kp->pc_cr = fnp->fn_pcredp;
1137 kp->pc_cpid = fnp->fn_cpid;
1138 return (0);
1139 } else {
1140 return (ENOTSUP);
1141 }
1142 }
1143
1144 static int
1145 fifo_fastioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1146 cred_t *cr, int *rvalp)
1147 {
1148 fifonode_t *fnp = VTOF(vp);
1149 fifonode_t *fn_dest;
1150 int error = 0;
1151 fifolock_t *fn_lock = fnp->fn_lock;
1152 int cnt;
1153
1154 /*
1155 * tty operations not allowed
1156 */
1157 if (((cmd & IOCTYPE) == LDIOC) ||
1158 ((cmd & IOCTYPE) == tIOC) ||
1159 ((cmd & IOCTYPE) == TIOC)) {
1160 return (EINVAL);
1161 }
1162
1163 mutex_enter(&fn_lock->flk_lock);
1343 * (waking readers probably doesn't make sense, but it
1344 * doesn't hurt; i.e. we just got rid of all the data
1345 * what's to read ?)
1346 */
1347 if (fn_dest->fn_flag & (FIFOWANTW | FIFOWANTR)) {
1348 fn_dest->fn_flag &= ~(FIFOWANTW | FIFOWANTR);
1349 cv_broadcast(&fn_dest->fn_wait_cv);
1350 }
1351 *rvalp = 0;
1352 break;
1353
1354 /*
1355 * Since no band data can ever get on a fifo in fast mode
1356 * just return 0.
1357 */
1358 case I_FLUSHBAND:
1359 error = 0;
1360 *rvalp = 0;
1361 break;
1362
1363 case _I_GETPEERCRED:
1364 error = fifo_ioctl_getpeercred(fnp, arg, mode);
1365 break;
1366
1367 /*
1368 * invalid calls for stream head or fifos
1369 */
1370
1371 case I_POP: /* shouldn't happen */
1372 case I_LOOK:
1373 case I_LINK:
1374 case I_PLINK:
1375 case I_UNLINK:
1376 case I_PUNLINK:
1377
1378 /*
1379 * more invalid tty type of ioctls
1380 */
1381
1382 case SRIOCSREDIR:
1383 case SRIOCISREDIR:
1384 error = EINVAL;
1385 break;
1386
1394 stream_mode:
1395 /*
1396 * streams mode
1397 */
1398 mutex_exit(&fn_lock->flk_lock);
1399 return (fifo_strioctl(vp, cmd, arg, mode, cr, rvalp));
1400
1401 }
1402
1403 /*
1404 * FIFO is in STREAMS mode; STREAMS framework does most of the work.
1405 */
1406 static int
1407 fifo_strioctl(vnode_t *vp, int cmd, intptr_t arg, int mode,
1408 cred_t *cr, int *rvalp)
1409 {
1410 fifonode_t *fnp = VTOF(vp);
1411 int error;
1412 fifolock_t *fn_lock;
1413
1414 if (cmd == _I_GETPEERCRED)
1415 return (fifo_ioctl_getpeercred(fnp, arg, mode));
1416
1417 error = strioctl(vp, cmd, arg, mode, U_TO_K, cr, rvalp);
1418
1419 switch (cmd) {
1420 /*
1421 * The FIFOSEND flag is set to inform other processes that a file
1422 * descriptor is pending at the stream head of this pipe.
1423 * The flag is cleared and the sending process is awoken when
1424 * this process has completed receiving the file descriptor.
1425 * XXX This could become out of sync if the process does I_SENDFDs
1426 * and opens on connld attached to the same pipe.
1427 */
1428 case I_RECVFD:
1429 case I_E_RECVFD:
1430 if (error == 0) {
1431 fn_lock = fnp->fn_lock;
1432 mutex_enter(&fn_lock->flk_lock);
1433 if (fnp->fn_flag & FIFOSEND) {
1434 fnp->fn_flag &= ~FIFOSEND;
1435 cv_broadcast(&fnp->fn_dest->fn_wait_cv);
|