*/ DEVICE_CMD Write_File(REBREQ *file) /* ** Bug?: update file->size value after write !? ** ***********************************************************************/ { if (!file->id) { file->error = -RFE_NO_HANDLE; return DR_ERROR; } if (GET_FLAG(file->modes, RFM_APPEND)) { CLR_FLAG(file->modes, RFM_APPEND); lseek(file->id, 0, SEEK_END); } if (file->modes & ((1 << RFM_SEEK) | (1 << RFM_RESEEK) | (1 << RFM_TRUNCATE))) { CLR_FLAG(file->modes, RFM_RESEEK); if (!Seek_File_64(file)) return DR_ERROR; if (GET_FLAG(file->modes, RFM_TRUNCATE)) if (ftruncate(file->id, file->file.index)) return DR_ERROR; } if (file->length == 0) return DR_DONE; file->actual = write(file->id, file->data, file->length); if (file->actual < 0) { if (errno == ENOSPC) file->error = -RFE_DISK_FULL; else file->error = -RFE_BAD_WRITE; return DR_ERROR; } return DR_DONE; }
static int emac_set_pauseparam(struct net_device *netdev, struct ethtool_pauseparam *pause) { struct emac_adapter *adpt = netdev_priv(netdev); struct emac_hw *hw = &adpt->hw; enum emac_fc_mode req_fc_mode; bool disable_fc_autoneg; int retval = 0; while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ req_fc_mode = hw->req_fc_mode; disable_fc_autoneg = hw->disable_fc_autoneg; if (pause->autoneg != AUTONEG_ENABLE) disable_fc_autoneg = true; else disable_fc_autoneg = false; if (pause->rx_pause && pause->tx_pause) req_fc_mode = emac_fc_full; else if (pause->rx_pause && !pause->tx_pause) req_fc_mode = emac_fc_rx_pause; else if (!pause->rx_pause && pause->tx_pause) req_fc_mode = emac_fc_tx_pause; else if (!pause->rx_pause && !pause->tx_pause) req_fc_mode = emac_fc_none; else { CLR_FLAG(adpt, ADPT_STATE_RESETTING); return -EINVAL; } if ((hw->req_fc_mode != req_fc_mode) || (hw->disable_fc_autoneg != disable_fc_autoneg)) { hw->req_fc_mode = req_fc_mode; hw->disable_fc_autoneg = disable_fc_autoneg; if (!adpt->no_ephy) retval = emac_setup_phy_link(hw, hw->autoneg_advertised, hw->autoneg, !disable_fc_autoneg); if (!retval) emac_hw_config_fc(hw); } CLR_FLAG(adpt, ADPT_STATE_RESETTING); return retval; }
static int Poll_Default(REBDEV *dev) { // The default polling function for devices. // Retries pending requests. Return TRUE if status changed. REBREQ **prior = &dev->pending; REBREQ *req; REBOOL change = FALSE; int result; for (req = *prior; req; req = *prior) { // Call command again: if (req->command < RDC_MAX) result = dev->commands[req->command](req); else { result = -1; // invalid command, remove it req->error = ((REBCNT)-1); } // If done or error, remove command from list: if (result <= 0) { *prior = req->next; req->next = 0; CLR_FLAG(req->flags, RRF_PENDING); change = TRUE; } else prior = &req->next; } return change; }
*/ void Detach_Request(REBREQ **node, REBREQ *req) /* ** Detach a request to a device's pending or accept list. ** If it is not in list, then no harm done. ** ***********************************************************************/ { REBREQ *r; #ifdef special_debug if (req->device == 5) Debug_Fmt("Detach= n: %x r: %x p: %x %x", *node, req, req->port, &req->next); #endif // See if its there, and get last req: for (r = *node; r; r = *node) { #ifdef special_debug if (req->device == 5) Debug_Fmt("Detach: r: %x n: %x", r, r->next); #endif if (r == req) { *node = req->next; req->next = 0; CLR_FLAG(req->flags, RRF_PENDING); return; } node = &r->next; } }
*/ DEVICE_CMD Read_File(REBREQ *file) /* ***********************************************************************/ { if (GET_FLAG(file->modes, RFM_DIR)) { return Read_Directory(file, (REBREQ*)file->data); } if (!file->id) { file->error = -RFE_NO_HANDLE; return DR_ERROR; } if (file->modes & ((1 << RFM_SEEK) | (1 << RFM_RESEEK))) { CLR_FLAG(file->modes, RFM_RESEEK); if (!Seek_File_64(file)) return DR_ERROR; } // printf("read %d len %d\n", file->id, file->length); file->actual = read(file->id, file->data, file->length); if (file->actual < 0) { file->error = -RFE_BAD_READ; return DR_ERROR; } else { file->file.index += file->actual; } return DR_DONE; }
*/ DEVICE_CMD Read_Clipboard(REBREQ *req) /* ***********************************************************************/ { REBYTE *data; //put the OS specific code here //============================= // //============================= req->actual = 0; if ((data) == NULL) { req->error = 30; return DR_ERROR; } //make sure "bytes mode" is set CLR_FLAG(req->flags, RRF_WIDE); req->data = data; req->actual = LEN_STR(data); return DR_DONE; }
// // Quit_IO: C // DEVICE_CMD Quit_IO(REBREQ *dr) { REBDEV *dev = (REBDEV*)dr; // just to keep compiler happy above Close_Stdio(); CLR_FLAG(dev->flags, RDF_OPEN); return DR_DONE; }
// // Close_IO: C // DEVICE_CMD Close_IO(REBREQ *req) { REBDEV *dev = Devices[req->device]; Close_Stdio(); CLR_FLAG(dev->flags, RRF_OPEN); return DR_DONE; }
*/ DEVICE_CMD Quit_IO(REBREQ *dr) /* ***********************************************************************/ { REBDEV *dev = (REBDEV*)dr; // just to keep compiler happy above //if (GET_FLAG(dev->flags, RDF_OPEN)) FreeConsole(); CLR_FLAG(dev->flags, RDF_OPEN); return DR_DONE; }
BOOL MYRTLEXP SetFileAttr( CONSTSTR fname,ATTR_TYPE v ) { #if defined(__GNUC__) || defined(__QNX__) CLR_FLAG( v,flDirectory ); #else #if defined(__HDOS__) CLR_FLAG( v,FA_DIREC | FA_LABEL ); #else #if defined(__HWIN16__) CLR_FLAG( v,FA_DIREC | FA_LABEL ); #else #if defined(__HWIN32__) CLR_FLAG( v,FILE_ATTRIBUTE_DIRECTORY ); #else #error ERR_PLATFORM #endif #endif #endif #endif #if defined(__GNUC__) || defined(__QNX__) return FIO_CHMOD(fname,v); #else #if defined(__REALDOS__) return _dos_setfileattr(fname,v) == 0; #else #if defined(__PROTDOS__) return dos_setfileattr(fname,v) == 0; #else #if defined(__BCWIN16__) return _dos_setfileattr(fname,v) == 0; #else #if defined(__HWIN32__) return SetFileAttributes(fname,v) != 0; #else #error ERR_PLATFORM #endif #endif #endif #endif #endif }
*/ static void Cleanup_File(REBREQ *file) /* ***********************************************************************/ { if (GET_FLAG(file->modes, RFM_NAME_MEM)) { //NOTE: file->special.file.path will get GC'd file->special.file.path = 0; CLR_FLAG(file->modes, RFM_NAME_MEM); } SET_CLOSED(file); }
*/ DEVICE_CMD Close_IO(REBREQ *req) /* ***********************************************************************/ { REBDEV *dev = Devices[req->device]; close_stdio(); CLR_FLAG(req->flags, RRF_OPEN); return DR_DONE; }
*/ int Quit_Net(REBREQ *dr) /* ** Close and cleanup networking libraries and related interfaces. ** ***********************************************************************/ { REBDEV *dev = (REBDEV*)dr; // just to keep compiler happy #ifdef TO_WIN32 if (GET_FLAG(dev->flags, RDF_INIT)) WSACleanup(); #endif CLR_FLAG(dev->flags, RDF_INIT); return DR_DONE; }
*/ DEVICE_CMD Close_DNS(REBREQ *sock) /* ** Note: valid even if not open. ** ***********************************************************************/ { // Terminate a pending request: #ifdef HAS_ASYNC_DNS if (GET_FLAG(sock->flags, RRF_PENDING)) { CLR_FLAG(sock->flags, RRF_PENDING); if (sock->handle) WSACancelAsyncRequest(sock->handle); } #endif if (sock->net.host_info) OS_Free(sock->net.host_info); sock->net.host_info = 0; sock->handle = 0; SET_CLOSED(sock); return DR_DONE; // Removes it from device's pending list (if needed) }
*/ DEVICE_CMD Poll_DNS(REBREQ *dr) /* ** Check for completed DNS requests. These are marked with ** RRF_DONE by the windows message event handler (dev-event.c). ** Completed requests are removed from the pending queue and ** event is signalled (for awake dispatch). ** ***********************************************************************/ { REBDEV *dev = (REBDEV*)dr; // to keep compiler happy REBREQ **prior = &dev->pending; REBREQ *req; BOOL change = FALSE; HOSTENT *host; // Scan the pending request list: for (req = *prior; req; req = *prior) { // If done or error, remove command from list: if (GET_FLAG(req->flags, RRF_DONE)) { // req->error may be set *prior = req->next; req->next = 0; CLR_FLAG(req->flags, RRF_PENDING); if (!req->error) { // success! host = (HOSTENT*)req->net.host_info; if (GET_FLAG(req->modes, RST_REVERSE)) req->data = host->h_name; else COPY_MEM((char*)&(req->net.remote_ip), (char *)(*host->h_addr_list), 4); //he->h_length); Signal_Device(req, EVT_READ); } else Signal_Device(req, EVT_ERROR); change = TRUE; } else prior = &req->next; } return change; }
static int Get_File_Info(REBREQ *file) { struct stat info; if (stat(file->file.path, &info)) { file->error = errno; return DR_ERROR; } if (S_ISDIR(info.st_mode)) { SET_FLAG(file->modes, RFM_DIR); file->file.size = 0; // in order to be consistent on all systems } else { CLR_FLAG(file->modes, RFM_DIR); file->file.size = info.st_size; } file->file.time.l = (long)(info.st_mtime); return DR_DONE; }
*/ DEVICE_CMD Close_IO(REBREQ *req) /* ***********************************************************************/ { REBDEV *dev = Devices[req->device]; if (GET_FLAG(dev->flags, RDF_OPEN)) { OS_Free(Std_Buf); Std_Buf = 0; //FreeConsole(); // problem: causes a delay } if (Std_Echo) { CloseHandle(Std_Echo); Std_Echo = 0; } CLR_FLAG(req->flags, RRF_OPEN); //CLR_FLAG(dev->flags, RDF_OPEN); return DR_DONE; }
*/ static int Event_Actor(REBVAL *ds, REBSER *port, REBCNT action) /* ***********************************************************************/ { REBVAL *spec; REBVAL *state; REBCNT result; REBVAL *arg; REBVAL save_port; Validate_Port(port, action); arg = D_ARG(2); *D_RET = *D_ARG(1); // Validate and fetch relevant PORT fields: state = BLK_SKIP(port, STD_PORT_STATE); spec = BLK_SKIP(port, STD_PORT_SPEC); if (!IS_OBJECT(spec)) Trap1(RE_INVALID_SPEC, spec); // Get or setup internal state data: if (!IS_BLOCK(state)) Set_Block(state, Make_Block(127)); switch (action) { case A_UPDATE: return R_NONE; // Normal block actions done on events: case A_POKE: if (!IS_EVENT(D_ARG(3))) Trap_Arg(D_ARG(3)); goto act_blk; case A_INSERT: case A_APPEND: //case A_PATH: // not allowed: port/foo is port object field access //case A_PATH_SET: // not allowed: above if (!IS_EVENT(arg)) Trap_Arg(arg); case A_PICK: act_blk: save_port = *D_ARG(1); // save for return *D_ARG(1) = *state; result = T_Block(ds, action); SET_FLAG(Eval_Signals, SIG_EVENT_PORT); if (action == A_INSERT || action == A_APPEND || action == A_REMOVE) { *D_RET = save_port; break; } return result; // return condition case A_CLEAR: VAL_TAIL(state) = 0; VAL_BLK_TERM(state); CLR_FLAG(Eval_Signals, SIG_EVENT_PORT); break; case A_LENGTHQ: SET_INTEGER(D_RET, VAL_TAIL(state)); break; case A_OPEN: if (!req) { //!!! req = OS_MAKE_DEVREQ(RDI_EVENT); SET_OPEN(req); OS_DO_DEVICE(req, RDC_CONNECT); // stays queued } break; default: Trap_Action(REB_PORT, action); } return R_RET; }
*/ static int Read_Directory(REBREQ *dir, REBREQ *file) /* ** This function will read a file directory, one file entry ** at a time, then close when no more files are found. ** ** Procedure: ** ** This function is passed directory and file arguments. ** The dir arg provides information about the directory to read. ** The file arg is used to return specific file information. ** ** To begin, this function is called with a dir->handle that ** is set to zero and a dir->file.path string for the directory. ** ** The directory is opened and a handle is stored in the dir ** structure for use on subsequent calls. If an error occurred, ** dir->error is set to the error code and -1 is returned. ** The dir->size field can be set to the number of files in the ** dir, if it is known. The dir->file.index field can be used by this ** function to store information between calls. ** ** If the open succeeded, then information about the first file ** is stored in the file argument and the function returns 0. ** On an error, the dir->error is set, the dir is closed, ** dir->handle is nulled, and -1 is returned. ** ** The caller loops until all files have been obtained. This ** action should be uninterrupted. (The caller should not perform ** additional OS or IO operations between calls.) ** ** When no more files are found, the dir is closed, dir->handle ** is nulled, and 1 is returned. No file info is returned. ** (That is, this function is called one extra time. This helps ** for OSes that may deallocate file strings on dir close.) ** ** Note that the dir->file.path can contain wildcards * and ?. The ** processing of these can be done in the OS (if supported) or ** by a separate filter operation during the read. ** ** Store file date info in file->file.index or other fields? ** Store permissions? Ownership? Groups? Or, require that ** to be part of a separate request? ** ***********************************************************************/ { struct stat info; struct dirent *d; char *cp; DIR *h; int n; // Remove * from tail, if present. (Allowed because the // path was copied into to-local-path first). n = strlen(cp = dir->file.path); if (n > 0 && cp[n-1] == '*') cp[n-1] = 0; // If no dir handle, open the dir: if (!(h = dir->handle)) { h = opendir(dir->file.path); if (!h) { dir->error = errno; return DR_ERROR; } dir->handle = h; CLR_FLAG(dir->flags, RRF_DONE); } // Get dir entry (skip over the . and .. dir cases): do { // Read next file entry or error: if (!(d = readdir(h))) { //dir->error = errno; closedir(h); dir->handle = 0; //if (dir->error) return DR_ERROR; SET_FLAG(dir->flags, RRF_DONE); // no more files return DR_DONE; } cp = d->d_name; } while (cp[0] == '.' && (cp[1] == 0 || cp[1] == '.')); file->modes = 0; COPY_BYTES(file->file.path, cp, MAX_FILE_NAME); // NOTE: not all posix filesystems support this (mainly // the Linux and BSD support it.) If this fails to build, a // different mechanism must be used. However, this is the // most efficient, because it does not require a separate // file system call for determining directories. if (d->d_type == DT_DIR) SET_FLAG(file->modes, RFM_DIR); // Line below DOES NOT WORK -- because we need full path. //Get_File_Info(file); // updates modes, size, time return DR_DONE; }
STOID Mold_Block(REBVAL *value, REB_MOLD *mold) { REBYTE *sep; REBOOL all = GET_MOPT(mold, MOPT_MOLD_ALL); REBSER *series = mold->series; REBFLG over = FALSE; if (SERIES_WIDE(VAL_SERIES(value)) == 0) Crash(RP_BAD_WIDTH, sizeof(REBVAL), 0, VAL_TYPE(value)); // Optimize when no index needed: if (VAL_INDEX(value) == 0 && !IS_MAP(value)) // && (VAL_TYPE(value) <= REB_LIT_PATH)) all = FALSE; // If out of range, do not cause error to avoid error looping. if (VAL_INDEX(value) >= VAL_TAIL(value)) over = TRUE; // Force it into [] if (all || (over && !IS_BLOCK(value) && !IS_PAREN(value))) { SET_FLAG(mold->opts, MOPT_MOLD_ALL); Pre_Mold(value, mold); // #[block! part //if (over) Append_Bytes(mold->series, "[]"); //else Mold_Block_Series(mold, VAL_SERIES(value), 0, 0); Post_Mold(value, mold); } else { switch(VAL_TYPE(value)) { case REB_MAP: Pre_Mold(value, mold); sep = 0; case REB_BLOCK: if (GET_MOPT(mold, MOPT_ONLY)) { CLR_FLAG(mold->opts, MOPT_ONLY); // only top level sep = "\000\000"; } else sep = 0; break; case REB_PAREN: sep = "()"; break; case REB_GET_PATH: series = Append_Byte(series, ':'); sep = "/"; break; case REB_LIT_PATH: series = Append_Byte(series, '\''); /* fall through */ case REB_PATH: case REB_SET_PATH: sep = "/"; break; } if (over) Append_Bytes(mold->series, sep ? sep : (REBYTE*)("[]")); else Mold_Block_Series(mold, VAL_SERIES(value), VAL_INDEX(value), sep); if (VAL_TYPE(value) == REB_SET_PATH) Append_Byte(series, ':'); } }
/* Main table driver */ static void percent( char type, char subtype ) { DWORD vofs; int extend = (addrsize == 32) ? 4 : 2; BYTE c; switch (type) { case 'A': /* direct address */ SET_FLAG( Info->CurrentFlags,DISASM_FL_CODE ); outhex(subtype, extend, 0, addrsize, 0); CLR_FLAG( Info->CurrentFlags,DISASM_FL_CODE ); break; case 'C': /* reg(r/m) picks control reg */ uprintf("C%d", REG(modrm())); must_do_size = 0; break; case 'D': /* reg(r/m) picks debug reg */ uprintf("D%d", REG(modrm())); must_do_size = 0; break; case 'E': /* r/m picks operand */ do_modrm(subtype); break; case 'G': /* reg(r/m) picks register */ if (subtype == 'F') /* 80*87 operand? */ reg_name(RM(modrm()), subtype); else reg_name(REG(modrm()), subtype); must_do_size = 0; break; case 'I': /* immed data */ SET_FLAG( Info->CurrentFlags,DISASM_FL_DATA ); outhex(subtype, 0, 0, opsize, 0); CLR_FLAG( Info->CurrentFlags,DISASM_FL_DATA ); break; case 'J': /* relative IP offset */ vofs = 0; switch(bytes(subtype)) { /* sizeof offset value */ case 1: vofs = (DWORD)getbyte(); break; case 2: vofs = (DWORD)getbyte(); vofs |= (DWORD)getbyte() << 8; vofs &= 0xFFFFu; break; case 4: vofs = (DWORD)getbyte(); /* yuk! */ vofs |= (DWORD)getbyte() << 8; vofs |= (DWORD)getbyte() << 16; vofs |= (DWORD)getbyte() << 24; break; } SET_FLAG( Info->CurrentFlags,DISASM_FL_CODE|DISASM_FL_OFFSET ); uprintf("%s", addr_to_hex(vofs + Info->instruction_length,1,bytes(subtype)) ); CLR_FLAG( Info->CurrentFlags,DISASM_FL_CODE|DISASM_FL_OFFSET ); break; case 'K': if (do_distance==0) break; switch (subtype) { case 'f': uprintf( Info->GetStringName(DISASM_ID_FAR) ); uputchar(' '); break; case 'n': uprintf( Info->GetStringName(DISASM_ID_NEAR) ); uputchar(' '); break; case 's': uprintf( Info->GetStringName(DISASM_ID_SHORT) ); uputchar(' '); break; } break; case 'M': /* r/m picks memory */ do_modrm(subtype); break; case 'O': /* offset only */ ua_str("%p:["); SET_FLAG( Info->CurrentFlags,DISASM_FL_REF ); outhex(subtype, extend, 0, addrsize, 0); CLR_FLAG( Info->CurrentFlags,DISASM_FL_REF ); uputchar(']'); break; case 'P': /* prefix byte (rh) */ ua_str("%p:"); break; case 'R': /* mod(r/m) picks register */ reg_name(REG(modrm()), subtype); /* rh */ must_do_size = 0; break; case 'S': /* reg(r/m) picks segment reg */ uputchar("ecsdfg"[REG(modrm())]); uputchar('s'); must_do_size = 0; break; case 'T': /* reg(r/m) picks T reg */ uprintf("tr%d", REG(modrm())); must_do_size = 0; break; case 'X': /* ds:si type operator */ uprintf("ds:["); if (addrsize == 32) uputchar('e'); uprintf("si]"); break; case 'Y': /* es:di type operator */ uprintf("es:["); if (addrsize == 32) uputchar('e'); uprintf("di]"); break; case '2': /* old [pop cs]! now indexes */ ua_str(second[getbyte()]); /* instructions in 386/486 */ break; case 'g': /* modrm group `subtype' (0--7) */ ua_str( GetOPGroup(subtype) ); break; case 'd': /* sizeof operand==dword? */ if (opsize == 32) uputchar('d'); uputchar(subtype); break; case 'w': /* insert explicit size specifier */ if (opsize == 32) uputchar('d'); else uputchar('w'); uputchar(subtype); break; case 'e': /* extended reg name */ if (opsize == 32) { if (subtype == 'w') uputchar('d'); else { uputchar('e'); uputchar(subtype); } } else uputchar(subtype); break; case 'f': /* '87 opcode */ floating_point(subtype-'0'); break; case 'j': if (addrsize==32 || opsize==32) /* both of them?! */ uputchar('e'); break; case 'p': /* prefix byte */ switch (subtype) { case 'c': case 'd': case 'e': case 'f': case 'g': case 's': prefix = subtype; c = getbyte(); wordop = c & 1; ua_str( GetOP(c) ); break; case ':': if (prefix) uprintf("%cs:", prefix); break; case ' ': c = getbyte(); wordop = c & 1; ua_str( GetOP(c) ); break; } break; case 's': /* size override */ switch (subtype) { case 'a': addrsize = 48 - addrsize; c = getbyte(); wordop = c & 1; ua_str( GetOP(c) ); break; case 'o': opsize = 48 - opsize; c = getbyte(); wordop = c & 1; ua_str( GetOP(c) ); break; } break; } }
/*------------------------------------------------------------------------*/ static void do_modrm(char subtype) { int mod = MOD(modrm()); int rm = RM(modrm()); int extend = (addrsize == 32) ? 4 : 2; /* specifies two registers */ if (mod == 3) { reg_name(rm, subtype); return; } if (must_do_size) { if (wordop) { if (addrsize==32 || opsize==32) /* then must specify size */ uprintf( Info->GetStringName(DISASM_ID_DWORD_PTR) ); else uprintf( Info->GetStringName(DISASM_ID_WORD_PTR) ); } else uprintf( Info->GetStringName(DISASM_ID_BYTE_PTR) ); uputchar(' '); } /* mem operand with 32 bit ofs */ if ((mod == 0) && (rm == 5) && (addrsize == 32)) { ua_str("%p:["); SET_FLAG( Info->CurrentFlags,DISASM_FL_REF ); outhex('d', extend, 0, addrsize, 0); CLR_FLAG( Info->CurrentFlags,DISASM_FL_REF ); uputchar(']'); } else /* 16 bit dsplcmnt */ if ((mod == 0) && (rm == 6) && (addrsize == 16)) { ua_str("%p:["); SET_FLAG( Info->CurrentFlags,DISASM_FL_REF ); outhex('w', extend, 0, addrsize, 0); CLR_FLAG( Info->CurrentFlags,DISASM_FL_REF ); uputchar(']'); } else { /*All other*/ if ( (addrsize != 32) || (rm != 4) ) ua_str("%p:["); SET_FLAG( Info->CurrentFlags,DISASM_FL_REF | DISASM_FL_REFADD ); if (addrsize == 16) switch (rm) { case 0: uprintf("bx+si"); break; case 1: uprintf("bx+di"); break; case 2: uprintf("bp+si"); break; case 3: uprintf("bp+di"); break; case 4: uprintf("si"); break; case 5: uprintf("di"); break; case 6: uprintf("bp"); break; case 7: uprintf("bx"); break; } else switch (rm) { case 0: uprintf("eax"); break; case 1: uprintf("ecx"); break; case 2: uprintf("edx"); break; case 3: uprintf("ebx"); break; case 4: do_sib(mod); break; case 5: uprintf("ebp"); break; case 6: uprintf("esi"); break; case 7: uprintf("edi"); break; } switch (mod) { case 1: outhex('b', extend, 1, addrsize, 0); break; case 2: outhex('v', extend, 1, addrsize, 1); break; } CLR_FLAG( Info->CurrentFlags,DISASM_FL_REF | DISASM_FL_REFADD ); uputchar(']'); } }
*/ DEVICE_CMD Connect_Socket(REBREQ *sock) /* ** Connect a socket to a service. ** Only required for connection-based protocols (e.g. not UDP). ** The IP address must already be resolved before calling. ** ** This function is asynchronous. It will return immediately. ** You can call this function again to check the pending connection. ** ** The function will return: ** =0: connection succeeded (or already is connected) ** >0: in-progress, still trying ** <0: error occurred, no longer trying ** ** Before usage: ** Open_Socket() -- to allocate the socket ** ***********************************************************************/ { int result; SOCKAI sa; if (GET_FLAG(sock->modes, RST_LISTEN)) return Listen_Socket(sock); if (GET_FLAG(sock->state, RSM_CONNECT)) return DR_DONE; // already connected Set_Addr(&sa, sock->net.remote_ip, sock->net.remote_port); result = connect(sock->socket, (struct sockaddr *)&sa, sizeof(sa)); if (result != 0) result = GET_ERROR; WATCH2("connect() error: %d - %s\n", result, strerror(result)); switch (result) { case 0: // no error case NE_ISCONN: // Connected, set state: CLR_FLAG(sock->state, RSM_ATTEMPT); SET_FLAG(sock->state, RSM_CONNECT); Get_Local_IP(sock); Signal_Device(sock, EVT_CONNECT); return DR_DONE; // done #ifdef TO_WIN32 case NE_INVALID: // Corrects for Microsoft bug #endif case NE_WOULDBLOCK: case NE_INPROGRESS: case NE_ALREADY: // Still trying: SET_FLAG(sock->state, RSM_ATTEMPT); return DR_PEND; default: // An error happened: CLR_FLAG(sock->state, RSM_ATTEMPT); sock->error = result; //Signal_Device(sock, EVT_ERROR); return DR_ERROR; } }
void FP_ItemList::Copy(PluginPanelItem *dest,const PluginPanelItem *src,int cn) { if(!cn) return; memmove(dest, src, sizeof(*dest)*cn); for(; cn; cn--,src++,dest++) { //User data if(IS_FLAG(src->Flags,PPIF_USERDATA)) { DWORD sz = (src->UserData && !IsBadReadPtr((void*)src->UserData,sizeof(DWORD))) ? (*((DWORD*)src->UserData)) : 0; if(sz && !IsBadReadPtr((void*)src->UserData,sz)) { dest->UserData = (DWORD_PTR)malloc(sz+1); memmove((char*)dest->UserData,(char*)src->UserData,sz); } else { dest->UserData = 0; CLR_FLAG(dest->Flags,PPIF_USERDATA); } } //CustomColumn if(src->CustomColumnNumber) { dest->CustomColumnData = (LPSTR*)malloc(sizeof(LPSTR*)*src->CustomColumnNumber); for(int n = 0; n < src->CustomColumnNumber; n++) { dest->CustomColumnData[n] = strdup(src->CustomColumnData[n]); } } //Description if(src->Description) dest->Description = strdup(src->Description); //Owner if(src->Owner) dest->Owner = strdup(src->Owner); //Additionals if(FPIL_ADDEXIST(src)) { DWORD sz = FPIL_ADDSIZE(src); LPVOID ptr = malloc(sz); if(ptr) { memmove(ptr, FPIL_ADDDATA(src), sz); FPIL_ADDSET(dest, sz, ptr); } else FPIL_ADDSET(dest, 0, NULL); } } }
// // Clipboard_Actor: C // static REB_R Clipboard_Actor(struct Reb_Call *call_, REBSER *port, REBCNT action) { REBREQ *req; REBINT result; REBVAL *arg; REBCNT refs; // refinement argument flags REBINT len; REBSER *ser; Validate_Port(port, action); arg = DS_ARGC > 1 ? D_ARG(2) : NULL; req = cast(REBREQ*, Use_Port_State(port, RDI_CLIPBOARD, sizeof(REBREQ))); switch (action) { case A_UPDATE: // Update the port object after a READ or WRITE operation. // This is normally called by the WAKE-UP function. arg = OFV(port, STD_PORT_DATA); if (req->command == RDC_READ) { // this could be executed twice: // once for an event READ, once for the CLOSE following the READ if (!req->common.data) return R_NONE; len = req->actual; if (GET_FLAG(req->flags, RRF_WIDE)) { // convert to UTF8, so that it can be converted back to string! Val_Init_Binary(arg, Make_UTF8_Binary( req->common.data, len / sizeof(REBUNI), 0, OPT_ENC_UNISRC )); } else { REBSER *ser = Make_Binary(len); memcpy(BIN_HEAD(ser), req->common.data, len); SERIES_TAIL(ser) = len; Val_Init_Binary(arg, ser); } OS_FREE(req->common.data); // release the copy buffer req->common.data = 0; } else if (req->command == RDC_WRITE) { SET_NONE(arg); // Write is done. } return R_NONE; case A_READ: // This device is opened on the READ: if (!IS_OPEN(req)) { if (OS_DO_DEVICE(req, RDC_OPEN)) fail (Error_On_Port(RE_CANNOT_OPEN, port, req->error)); } // Issue the read request: CLR_FLAG(req->flags, RRF_WIDE); // allow byte or wide chars result = OS_DO_DEVICE(req, RDC_READ); if (result < 0) fail (Error_On_Port(RE_READ_ERROR, port, req->error)); if (result > 0) return R_NONE; /* pending */ // Copy and set the string result: arg = OFV(port, STD_PORT_DATA); len = req->actual; if (GET_FLAG(req->flags, RRF_WIDE)) { // convert to UTF8, so that it can be converted back to string! Val_Init_Binary(arg, Make_UTF8_Binary( req->common.data, len / sizeof(REBUNI), 0, OPT_ENC_UNISRC )); } else { REBSER *ser = Make_Binary(len); memcpy(BIN_HEAD(ser), req->common.data, len); SERIES_TAIL(ser) = len; Val_Init_Binary(arg, ser); } *D_OUT = *arg; return R_OUT; case A_WRITE: if (!IS_STRING(arg) && !IS_BINARY(arg)) fail (Error(RE_INVALID_PORT_ARG, arg)); // This device is opened on the WRITE: if (!IS_OPEN(req)) { if (OS_DO_DEVICE(req, RDC_OPEN)) fail (Error_On_Port(RE_CANNOT_OPEN, port, req->error)); } refs = Find_Refines(call_, ALL_WRITE_REFS); // Handle /part refinement: len = VAL_LEN(arg); if (refs & AM_WRITE_PART && VAL_INT32(D_ARG(ARG_WRITE_LIMIT)) < len) len = VAL_INT32(D_ARG(ARG_WRITE_LIMIT)); // If bytes, see if we can fit it: if (SERIES_WIDE(VAL_SERIES(arg)) == 1) { #ifdef ARG_STRINGS_ALLOWED if (!All_Bytes_ASCII(VAL_BIN_DATA(arg), len)) { Val_Init_String( arg, Copy_Bytes_To_Unicode(VAL_BIN_DATA(arg), len) ); } else req->common.data = VAL_BIN_DATA(arg); #endif // Temp conversion:!!! ser = Make_Unicode(len); len = Decode_UTF8(UNI_HEAD(ser), VAL_BIN_DATA(arg), len, FALSE); SERIES_TAIL(ser) = len = abs(len); UNI_TERM(ser); Val_Init_String(arg, ser); req->common.data = cast(REBYTE*, UNI_HEAD(ser)); SET_FLAG(req->flags, RRF_WIDE); } else // If unicode (may be from above conversion), handle it: if (SERIES_WIDE(VAL_SERIES(arg)) == sizeof(REBUNI)) { req->common.data = cast(REBYTE *, VAL_UNI_DATA(arg)); SET_FLAG(req->flags, RRF_WIDE); }
static int emac_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) { struct emac_adapter *adpt = netdev_priv(netdev); struct emac_hw *hw = &adpt->hw; u32 advertised, old; int retval = 0; bool autoneg; emac_info(adpt, link, "ethtool cmd autoneg %d, speed %d, duplex %d\n", ecmd->autoneg, ecmd->speed, ecmd->duplex); while (TEST_N_SET_FLAG(adpt, ADPT_STATE_RESETTING)) msleep(20); /* Reset might take few 10s of ms */ old = hw->autoneg_advertised; advertised = 0; if (ecmd->autoneg == AUTONEG_ENABLE) { advertised = EMAC_LINK_SPEED_DEFAULT; autoneg = true; } else { u32 speed = ecmd->speed; autoneg = false; if (speed == SPEED_1000) { if (ecmd->duplex != DUPLEX_FULL) { emac_warn(adpt, hw, "1000M half is invalid\n"); CLR_FLAG(adpt, ADPT_STATE_RESETTING); return -EINVAL; } advertised = EMAC_LINK_SPEED_1GB_FULL; } else if (speed == SPEED_100) { if (ecmd->duplex == DUPLEX_FULL) advertised = EMAC_LINK_SPEED_100_FULL; else advertised = EMAC_LINK_SPEED_100_HALF; } else { if (ecmd->duplex == DUPLEX_FULL) advertised = EMAC_LINK_SPEED_10_FULL; else advertised = EMAC_LINK_SPEED_10_HALF; } } if ((hw->autoneg == autoneg) && (hw->autoneg_advertised == advertised)) goto done; retval = emac_setup_phy_link_speed(hw, advertised, autoneg, !hw->disable_fc_autoneg); if (retval) { emac_setup_phy_link_speed(hw, old, autoneg, !hw->disable_fc_autoneg); } if (netif_running(adpt->netdev)) { /* If there is no EPHY, the EMAC internal PHY may get reset in * emac_setup_phy_link_speed. Reset the MAC to avoid the memory * corruption. */ if (adpt->no_ephy) { emac_down(adpt, EMAC_HW_CTRL_RESET_MAC); emac_up(adpt); } } done: CLR_FLAG(adpt, ADPT_STATE_RESETTING); return retval; }
*/ static REBFLG Set_GOB_Var(REBGOB *gob, REBVAL *word, REBVAL *val) /* ***********************************************************************/ { switch (VAL_WORD_CANON(word)) { case SYM_OFFSET: return Set_Pair(&(gob->offset), val); case SYM_SIZE: return Set_Pair(&gob->size, val); case SYM_IMAGE: CLR_GOB_OPAQUE(gob); if (IS_IMAGE(val)) { SET_GOB_TYPE(gob, GOBT_IMAGE); GOB_W(gob) = (REBD32)VAL_IMAGE_WIDE(val); GOB_H(gob) = (REBD32)VAL_IMAGE_HIGH(val); GOB_CONTENT(gob) = VAL_SERIES(val); // if (!VAL_IMAGE_TRANSP(val)) SET_GOB_OPAQUE(gob); } else if (IS_NONE(val)) SET_GOB_TYPE(gob, GOBT_NONE); else return FALSE; break; case SYM_DRAW: CLR_GOB_OPAQUE(gob); if (IS_BLOCK(val)) { SET_GOB_TYPE(gob, GOBT_DRAW); GOB_CONTENT(gob) = VAL_SERIES(val); } else if (IS_NONE(val)) SET_GOB_TYPE(gob, GOBT_NONE); else return FALSE; break; case SYM_TEXT: CLR_GOB_OPAQUE(gob); if (IS_BLOCK(val)) { SET_GOB_TYPE(gob, GOBT_TEXT); GOB_CONTENT(gob) = VAL_SERIES(val); } else if (IS_STRING(val)) { SET_GOB_TYPE(gob, GOBT_STRING); GOB_CONTENT(gob) = VAL_SERIES(val); } else if (IS_NONE(val)) SET_GOB_TYPE(gob, GOBT_NONE); else return FALSE; break; case SYM_EFFECT: CLR_GOB_OPAQUE(gob); if (IS_BLOCK(val)) { SET_GOB_TYPE(gob, GOBT_EFFECT); GOB_CONTENT(gob) = VAL_SERIES(val); } else if (IS_NONE(val)) SET_GOB_TYPE(gob, GOBT_NONE); else return FALSE; break; case SYM_COLOR: CLR_GOB_OPAQUE(gob); if (IS_TUPLE(val)) { SET_GOB_TYPE(gob, GOBT_COLOR); Set_Pixel_Tuple((REBYTE*)&GOB_CONTENT(gob), val); if (VAL_TUPLE_LEN(val) < 4 || VAL_TUPLE(val)[3] == 0) SET_GOB_OPAQUE(gob); } else if (IS_NONE(val)) SET_GOB_TYPE(gob, GOBT_NONE); break; case SYM_PANE: if (GOB_PANE(gob)) Clear_Series(GOB_PANE(gob)); if (IS_BLOCK(val)) Insert_Gobs(gob, VAL_BLK_DATA(val), 0, VAL_BLK_LEN(val), 0); else if (IS_GOB(val)) Insert_Gobs(gob, val, 0, 1, 0); else if (IS_NONE(val)) gob->pane = 0; else return FALSE; break; case SYM_ALPHA: GOB_ALPHA(gob) = Clip_Int(Int32(val), 0, 255); break; case SYM_DATA: SET_GOB_DTYPE(gob, GOBD_NONE); if (IS_OBJECT(val)) { SET_GOB_DTYPE(gob, GOBD_OBJECT); SET_GOB_DATA(gob, VAL_OBJ_FRAME(val)); } else if (IS_BLOCK(val)) { SET_GOB_DTYPE(gob, GOBD_BLOCK); SET_GOB_DATA(gob, VAL_SERIES(val)); } else if (IS_STRING(val)) { SET_GOB_DTYPE(gob, GOBD_STRING); SET_GOB_DATA(gob, VAL_SERIES(val)); } else if (IS_BINARY(val)) { SET_GOB_DTYPE(gob, GOBD_BINARY); SET_GOB_DATA(gob, VAL_SERIES(val)); } else if (IS_INTEGER(val)) { SET_GOB_DTYPE(gob, GOBD_INTEGER); SET_GOB_DATA(gob, (void*)VAL_INT32(val)); } else if (IS_NONE(val)) SET_GOB_TYPE(gob, GOBT_NONE); else return FALSE; break; case SYM_FLAGS: if (IS_WORD(val)) Set_Gob_Flag(gob, val); else if (IS_BLOCK(val)) { REBINT i; //clear only flags defined by words for (i = 0; Gob_Flag_Words[i]; i += 2) CLR_FLAG(gob->flags, Gob_Flag_Words[i+1]); for (val = VAL_BLK(val); NOT_END(val); val++) if (IS_WORD(val)) Set_Gob_Flag(gob, val); } break; case SYM_OWNER: if (IS_GOB(val)) GOB_TMP_OWNER(gob) = VAL_GOB(val); else return FALSE; break; default: return FALSE; } return TRUE; }
*/ DEVICE_CMD Transfer_Socket(REBREQ *sock) /* ** Write or read a socket (for connection-based protocols). ** ** This function is asynchronous. It will return immediately. ** You can call this function again to check the pending connection. ** ** The mode is RSM_RECEIVE or RSM_SEND. ** ** The function will return: ** =0: succeeded ** >0: in-progress, still trying ** <0: error occurred, no longer trying ** ** Before usage: ** Open_Socket() ** Connect_Socket() ** Verify that RSM_CONNECT is true ** Setup the sock->data and sock->length ** ** Note that the mode flag is cleared by the caller, not here. ** ***********************************************************************/ { int result; long len; int mode = (sock->command == RDC_READ ? RSM_RECEIVE : RSM_SEND); if (!GET_FLAG(sock->state, RSM_CONNECT)) { sock->error = -18; return DR_ERROR; } SET_FLAG(sock->state, mode); // Limit size of transfer: len = MIN(sock->length, MAX_TRANSFER); if (mode == RSM_SEND) { // If host is no longer connected: result = send(sock->socket, sock->data, len, 0); WATCH2("send() len: %d actual: %d\n", len, result); if (result >= 0) { sock->data += result; sock->actual += result; if (sock->actual >= sock->length) { Signal_Device(sock, EVT_WROTE); return DR_DONE; } return DR_PEND; } // if (result < 0) ... } else { result = recv(sock->socket, sock->data, len, 0); WATCH2("recv() len: %d result: %d\n", len, result); if (result > 0) { sock->actual = result; Signal_Device(sock, EVT_READ); return DR_DONE; } if (result == 0) { // The socket gracefully closed. sock->actual = 0; CLR_FLAG(sock->state, RSM_CONNECT); // But, keep RRF_OPEN true Signal_Device(sock, EVT_CLOSE); return DR_DONE; } // if (result < 0) ... } // Check error code: result = GET_ERROR; WATCH2("get error: %d %s\n", result, strerror(result)); if (result == NE_WOULDBLOCK) return DR_PEND; // still waiting WATCH4("ERROR: recv(%d %x) len: %d error: %d\n", sock->socket, sock->data, len, result); // A nasty error happened: sock->error = result; //Signal_Device(sock, EVT_ERROR); return DR_ERROR; }
*/ static REBINT Do_Set_Operation(struct Reb_Call *call_, REBCNT flags) /* ** Do set operations on a series. ** ***********************************************************************/ { REBVAL *val; REBVAL *val1; REBVAL *val2 = 0; REBSER *ser; REBSER *hser = 0; // hash table for series REBSER *retser; // return series REBSER *hret; // hash table for return series REBCNT i; REBINT h = TRUE; REBCNT skip = 1; // record size REBCNT cased = 0; // case sensitive when TRUE SET_NONE(D_OUT); val1 = D_ARG(1); i = 2; // Check for second series argument: if (flags != SET_OP_UNIQUE) { val2 = D_ARG(i++); if (VAL_TYPE(val1) != VAL_TYPE(val2)) raise Error_Unexpected_Type(VAL_TYPE(val1), VAL_TYPE(val2)); } // Refinements /case and /skip N cased = D_REF(i++); // cased if (D_REF(i++)) skip = Int32s(D_ARG(i), 1); switch (VAL_TYPE(val1)) { case REB_BLOCK: i = VAL_LEN(val1); // Setup result block: if (GET_FLAG(flags, SOP_BOTH)) i += VAL_LEN(val2); retser = BUF_EMIT; // use preallocated shared block Resize_Series(retser, i); hret = Make_Hash_Sequence(i); // allocated // Optimization note: !! // This code could be optimized for small blocks by not hashing them // and extending Find_Key to do a FIND on the value itself w/o the hash. do { // Check what is in series1 but not in series2: if (GET_FLAG(flags, SOP_CHECK)) hser = Hash_Block(val2, cased); // Iterate over first series: ser = VAL_SERIES(val1); i = VAL_INDEX(val1); for (; val = BLK_SKIP(ser, i), i < SERIES_TAIL(ser); i += skip) { if (GET_FLAG(flags, SOP_CHECK)) { h = Find_Key(VAL_SERIES(val2), hser, val, skip, cased, 1) >= 0; if (GET_FLAG(flags, SOP_INVERT)) h = !h; } if (h) Find_Key(retser, hret, val, skip, cased, 2); } // Iterate over second series? if ((i = GET_FLAG(flags, SOP_BOTH))) { val = val1; val1 = val2; val2 = val; CLR_FLAG(flags, SOP_BOTH); } if (GET_FLAG(flags, SOP_CHECK)) Free_Series(hser); } while (i); if (hret) Free_Series(hret); Val_Init_Block(D_OUT, Copy_Array_Shallow(retser)); RESET_TAIL(retser); // required - allow reuse break; case REB_BINARY: cased = TRUE; SET_TYPE(D_OUT, REB_BINARY); case REB_STRING: i = VAL_LEN(val1); // Setup result block: if (GET_FLAG(flags, SOP_BOTH)) i += VAL_LEN(val2); retser = BUF_MOLD; Reset_Buffer(retser, i); RESET_TAIL(retser); do { REBUNI uc; cased = cased ? AM_FIND_CASE : 0; // Iterate over first series: ser = VAL_SERIES(val1); i = VAL_INDEX(val1); for (; i < SERIES_TAIL(ser); i += skip) { uc = GET_ANY_CHAR(ser, i); if (GET_FLAG(flags, SOP_CHECK)) { h = Find_Str_Char(VAL_SERIES(val2), 0, VAL_INDEX(val2), VAL_TAIL(val2), skip, uc, cased) != NOT_FOUND; if (GET_FLAG(flags, SOP_INVERT)) h = !h; } if (h && (Find_Str_Char(retser, 0, 0, SERIES_TAIL(retser), skip, uc, cased) == NOT_FOUND)) { Append_String(retser, ser, i, skip); } } // Iterate over second series? if ((i = GET_FLAG(flags, SOP_BOTH))) { val = val1; val1 = val2; val2 = val; CLR_FLAG(flags, SOP_BOTH); } } while (i); ser = Copy_String(retser, 0, -1); if (IS_BINARY(D_OUT)) Val_Init_Binary(D_OUT, ser); else Val_Init_String(D_OUT, ser); break; case REB_BITSET: switch (flags) { case SET_OP_UNIQUE: return R_ARG1; case SET_OP_UNION: i = A_OR; break; case SET_OP_INTERSECT: i = A_AND; break; case SET_OP_DIFFERENCE: i = A_XOR; break; case SET_OP_EXCLUDE: i = 0; // special case break; } ser = Xandor_Binary(i, val1, val2); Val_Init_Bitset(D_OUT, ser); break; case REB_TYPESET: switch (flags) { case SET_OP_UNIQUE: break; case SET_OP_UNION: VAL_TYPESET(val1) |= VAL_TYPESET(val2); break; case SET_OP_INTERSECT: VAL_TYPESET(val1) &= VAL_TYPESET(val2); break; case SET_OP_DIFFERENCE: VAL_TYPESET(val1) ^= VAL_TYPESET(val2); break; case SET_OP_EXCLUDE: VAL_TYPESET(val1) &= ~VAL_TYPESET(val2); break; } return R_ARG1; default: raise Error_Invalid_Arg(val1); } return R_OUT; }
*/ DEVICE_CMD Lookup_Socket(REBREQ *sock) /* ** Initiate the GetHost request and return immediately. ** This is very similar to the DNS device. ** The request will pend until the main event handler gets WM_DNS. ** Note the temporary results buffer (must be freed later). ** Note we use the sock->handle for the DNS handle. During use, ** we store the TCP socket in the length field. ** ***********************************************************************/ { #ifdef TO_WIN32 HANDLE handle; #endif HOSTENT *host; #ifdef HAS_ASYNC_DNS // Check if we are polling for completion: if (host = (HOSTENT*)(sock->net.host_info)) { // The windows main event handler will change this when it gets WM_DNS event: if (!GET_FLAG(sock->flags, RRF_DONE)) return DR_PEND; // still waiting CLR_FLAG(sock->flags, RRF_DONE); if (!sock->error) { // Success! host = (HOSTENT*)sock->net.host_info; COPY_MEM((char*)&(sock->net.remote_ip), (char *)(*host->h_addr_list), 4); //he->h_length); Signal_Device(sock, EVT_LOOKUP); } else Signal_Device(sock, EVT_ERROR); OS_Free(host); // free what we allocated earlier sock->socket = sock->length; // Restore TCP socket saved below sock->net.host_info = 0; return DR_DONE; } // Else, make the lookup request: host = OS_Make(MAXGETHOSTSTRUCT); // be sure to free it handle = WSAAsyncGetHostByName(Event_Handle, WM_DNS, sock->data, (char*)host, MAXGETHOSTSTRUCT); if (handle != 0) { sock->net.host_info = host; sock->length = sock->socket; // save TCP socket temporarily sock->handle = handle; return DR_PEND; // keep it on pending list } OS_Free(host); #else // Use old-style blocking DNS (mainly for testing purposes): host = gethostbyname(sock->data); sock->net.host_info = 0; // no allocated data if (host) { COPY_MEM((char*)&(sock->net.remote_ip), (char *)(*host->h_addr_list), 4); //he->h_length); CLR_FLAG(sock->flags, RRF_DONE); Signal_Device(sock, EVT_LOOKUP); return DR_DONE; } #endif sock->error = GET_ERROR; //Signal_Device(sock, EVT_ERROR); return DR_ERROR; // Remove it from pending list }