Print this page
XXXX adding PID information to netstat output


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







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









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






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




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