Print this page
XXXX adding PID information to netstat output


 162                  * close the file still referenced by the original
 163                  * file descriptor.
 164                  */
 165                 mutex_enter(&fp->f_tlock);
 166                 fp->f_count++;
 167                 mutex_exit(&fp->f_tlock);
 168                 if ((retval = ufalloc_file(iarg, fp)) == -1) {
 169                         /*
 170                          * New file descriptor can't be allocated.
 171                          * Revert the reference count.
 172                          */
 173                         mutex_enter(&fp->f_tlock);
 174                         fp->f_count--;
 175                         mutex_exit(&fp->f_tlock);
 176                         error = EMFILE;
 177                 } else {
 178                         if (cmd == F_DUPFD_CLOEXEC) {
 179                                 f_setfd(retval, FD_CLOEXEC);
 180                         }
 181                 }







 182                 goto done;
 183 
 184         case F_DUP2FD_CLOEXEC:
 185                 if (fdes == iarg) {
 186                         error = EINVAL;
 187                         goto done;
 188                 }
 189 
 190                 /*FALLTHROUGH*/
 191 
 192         case F_DUP2FD:
 193                 p = curproc;
 194                 if (fdes == iarg) {
 195                         retval = iarg;
 196                 } else if ((uint_t)iarg >= p->p_fno_ctl) {
 197                         if (iarg >= 0)
 198                                 fd_too_big(p);
 199                         error = EBADF;
 200                 } else {
 201                         /*
 202                          * We can't hold our getf(fdes) across the call to
 203                          * closeandsetf() because it creates a window for
 204                          * deadlock: if one thread is doing dup2(a, b) while
 205                          * another is doing dup2(b, a), each one will block
 206                          * waiting for the other to call releasef().  The
 207                          * solution is to increment the file reference count
 208                          * (which we have to do anyway), then releasef(fdes),
 209                          * then closeandsetf().  Incrementing f_count ensures
 210                          * that fp won't disappear after we call releasef().
 211                          * When closeandsetf() fails, we try avoid calling
 212                          * closef() because of all the side effects.
 213                          */
 214                         mutex_enter(&fp->f_tlock);
 215                         fp->f_count++;
 216                         mutex_exit(&fp->f_tlock);
 217                         releasef(fdes);











 218                         if ((error = closeandsetf(iarg, fp)) == 0) {
 219                                 if (cmd == F_DUP2FD_CLOEXEC) {
 220                                         f_setfd(iarg, FD_CLOEXEC);
 221                                 }
 222                                 retval = iarg;
 223                         } else {
 224                                 mutex_enter(&fp->f_tlock);
 225                                 if (fp->f_count > 1) {
 226                                         fp->f_count--;
 227                                         mutex_exit(&fp->f_tlock);











 228                                 } else {
 229                                         mutex_exit(&fp->f_tlock);
 230                                         (void) closef(fp);
 231                                 }
 232                         }
 233                         goto out;
 234                 }
 235                 goto done;
 236 
 237         case F_SETFL:
 238                 vp = fp->f_vnode;
 239                 flag = fp->f_flag;
 240                 if ((iarg & (FNONBLOCK|FNDELAY)) == (FNONBLOCK|FNDELAY))
 241                         iarg &= ~FNDELAY;
 242                 if ((error = VOP_SETFL(vp, flag, iarg, fp->f_cred, NULL)) ==
 243                     0) {
 244                         iarg &= FMASK;
 245                         mutex_enter(&fp->f_tlock);
 246                         fp->f_flag &= ~FMASK | (FREAD|FWRITE);
 247                         fp->f_flag |= (iarg - FOPEN) & ~(FREAD|FWRITE);




 162                  * close the file still referenced by the original
 163                  * file descriptor.
 164                  */
 165                 mutex_enter(&fp->f_tlock);
 166                 fp->f_count++;
 167                 mutex_exit(&fp->f_tlock);
 168                 if ((retval = ufalloc_file(iarg, fp)) == -1) {
 169                         /*
 170                          * New file descriptor can't be allocated.
 171                          * Revert the reference count.
 172                          */
 173                         mutex_enter(&fp->f_tlock);
 174                         fp->f_count--;
 175                         mutex_exit(&fp->f_tlock);
 176                         error = EMFILE;
 177                 } else {
 178                         if (cmd == F_DUPFD_CLOEXEC) {
 179                                 f_setfd(retval, FD_CLOEXEC);
 180                         }
 181                 }
 182 
 183                 if (error == 0 && fp->f_vnode != NULL) {
 184                         (void) VOP_IOCTL(fp->f_vnode, F_ASSOCI_PID,
 185                             (intptr_t)p->p_pidp->pid_id, FKIOCTL, kcred,
 186                             NULL, NULL);
 187                 }
 188 
 189                 goto done;
 190 
 191         case F_DUP2FD_CLOEXEC:
 192                 if (fdes == iarg) {
 193                         error = EINVAL;
 194                         goto done;
 195                 }
 196 
 197                 /*FALLTHROUGH*/
 198 
 199         case F_DUP2FD:
 200                 p = curproc;
 201                 if (fdes == iarg) {
 202                         retval = iarg;
 203                 } else if ((uint_t)iarg >= p->p_fno_ctl) {
 204                         if (iarg >= 0)
 205                                 fd_too_big(p);
 206                         error = EBADF;
 207                 } else {
 208                         /*
 209                          * We can't hold our getf(fdes) across the call to
 210                          * closeandsetf() because it creates a window for
 211                          * deadlock: if one thread is doing dup2(a, b) while
 212                          * another is doing dup2(b, a), each one will block
 213                          * waiting for the other to call releasef().  The
 214                          * solution is to increment the file reference count
 215                          * (which we have to do anyway), then releasef(fdes),
 216                          * then closeandsetf().  Incrementing f_count ensures
 217                          * that fp won't disappear after we call releasef().
 218                          * When closeandsetf() fails, we try avoid calling
 219                          * closef() because of all the side effects.
 220                          */
 221                         mutex_enter(&fp->f_tlock);
 222                         fp->f_count++;
 223                         mutex_exit(&fp->f_tlock);
 224                         releasef(fdes);
 225 
 226                         /*
 227                          * Assume we succeed to duplicate the file descriptor
 228                          * and associate the pid to the vnode.
 229                          */
 230                         if (fp->f_vnode != NULL) {
 231                                 (void) VOP_IOCTL(fp->f_vnode, F_ASSOCI_PID,
 232                                     (intptr_t)p->p_pidp->pid_id, FKIOCTL,
 233                                     kcred, NULL, NULL);
 234                         }
 235 
 236                         if ((error = closeandsetf(iarg, fp)) == 0) {
 237                                 if (cmd == F_DUP2FD_CLOEXEC) {
 238                                         f_setfd(iarg, FD_CLOEXEC);
 239                                 }
 240                                 retval = iarg;
 241                         } else {
 242                                 mutex_enter(&fp->f_tlock);
 243                                 if (fp->f_count > 1) {
 244                                         fp->f_count--;
 245                                         mutex_exit(&fp->f_tlock);
 246                                         /*
 247                                          * Failed to duplicate fdes,
 248                                          * disassociate the pid from the vnode.
 249                                          */
 250                                         if (fp->f_vnode != NULL) {
 251                                                 (void) VOP_IOCTL(fp->f_vnode,
 252                                                     F_DASSOC_PID,
 253                                                     (intptr_t)p->p_pidp->pid_id,
 254                                                     FKIOCTL, kcred, NULL, NULL);
 255                                         }
 256 
 257                                 } else {
 258                                         mutex_exit(&fp->f_tlock);
 259                                         (void) closef(fp);
 260                                 }
 261                         }
 262                         goto out;
 263                 }
 264                 goto done;
 265 
 266         case F_SETFL:
 267                 vp = fp->f_vnode;
 268                 flag = fp->f_flag;
 269                 if ((iarg & (FNONBLOCK|FNDELAY)) == (FNONBLOCK|FNDELAY))
 270                         iarg &= ~FNDELAY;
 271                 if ((error = VOP_SETFL(vp, flag, iarg, fp->f_cred, NULL)) ==
 272                     0) {
 273                         iarg &= FMASK;
 274                         mutex_enter(&fp->f_tlock);
 275                         fp->f_flag &= ~FMASK | (FREAD|FWRITE);
 276                         fp->f_flag |= (iarg - FOPEN) & ~(FREAD|FWRITE);